目录
1. RSA ................................................................................. 2
RSA 简介........................................................................................... 2
RSA 原理........................................................................................... 2
2. SHA .................................................................................6
SHA 简介...........................................................................................6
SHA 原理...........................................................................................6
3. MD5 ..............................................................................11
MD5 简介....................................................................................... 11
MD5 原理....................................................................................... 11
4. AES ................................................................................16
AES 简介......................................................................................... 16
AES 原理......................................................................................... 16
5. IDEA ..............................................................................20
IDEA 简介....................................................................................... 20
IDEA 原理....................................................................................... 20
实验总结 ............................................................................. 25
1. RSA
RSA 简介
RSA 算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。 RSA 是被
研究得最广泛的公钥算法,从提出到现在已近二十年,经历了各种攻击的考验,逐渐为人们
接受,普遍认为是目前最优秀的公钥方案之一。RSA 的安全性依赖于大数的因子分解,但
并没有从理论上证明破译 RSA 的难度与大数分解难度等价。即 RSA 的重大缺陷是无法从理
论上把握它的保密性能如何,而且密码学界多数人士倾向于因子分解不是 NPC 问题。RSA
的缺点主要有:A)产生密钥很麻烦,受到素数产生技术的限制,因而难以做到一次一密。B)
分组长度太大,为保证安全性,n 至少也要 600 bits 以上,使运算代价很高,尤其是速度较
慢,较对称密码算法慢几个数量级;且随着大数分解技术的发展,这个长度还在增加,不利
于数据格式的标准化。目前,SET(Secure Electronic Transaction)协议中要求 CA 采用 2048 比
特长的密钥,其他实体使用 1024 比特的密钥
RSA 原理
实现使用 java 语言以方便大数的产生。
import java.math.*;
import java.util.*;
import java.io.*;
class RSA {
BigInteger n, e, d;
int bitlen;
BigInteger qv(int x) {
return BigInteger.valueOf(x);
}
RSA(int bitl) {
BigInteger p, q, t;
bitlen = bitl;
do
{
p = BigInteger.probablePrime(bitlen / 2, new Random());
q = BigInteger.probablePrime(bitlen / 2, new Random());
e = BigInteger.probablePrime((new Random().nextInt(bitlen - 2))+ 2, new
Random());
n = p.multiply(q);
} while (n.bitLength() != bitlen);
n = p.multiply(q);
t = p.subtract(qv(1)).multiply(q.subtract(qv(1)));
d = e.modInverse(t);
System.out.println("p = " + p);
System.out.println("q = " + q);
System.out.println("n = " + n);
System.out.println("e = " + e);
System.out.println("d = " + d);
}
byte[] Process(byte[] plaintext, BigInteger key) {
int s = bitlen / 8;
int len = plaintext.length;
if (len % s != 0) len = len / s * s + s;
byte[] ciphertext = new byte[len];
int i, j;
for (i = 0; i < plaintext.length; i += s) {
byte[] m = new byte[s + 1];
for (j = 0; j < s && i + j < plaintext.length; j++) m[j + 1] = plaintext[i +
BigInteger c = new BigInteger(m);
c = c.modPow(key, n);
m = c.toByteArray();
for (j = 1; j <= s && j <= m.length; j++) ciphertext[i + s - j] = m[m.length
}
return ciphertext;
j];
- j];
}
}
public class Main {
public static void main(String[] args) {
RSA x = new RSA(1024);
FileInputStream fsRead;
FileOutputStream fsWrite;
try {
fsRead = new FileInputStream("plaintext");
byte[] buffer = new byte[fsRead.available()];
System.out.println(buffer.length);
fsRead.read(buffer);
fsRead.close();
byte[] res = x.Process(buffer, x.e);
fsWrite = new FileOutputStream("ciphertext");
fsWrite.write(res);
fsWrite.close();
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
try {
fsRead = new FileInputStream("ciphertext");
byte[] buffer = new byte[fsRead.available()];
fsRead.read(buffer);
fsRead.close();
byte[] res = x.Process(buffer, x.d);
fsWrite = new FileOutputStream("decryptedext");
fsWrite.write(res);
fsWrite.close();
} catch (Exception ex) {
System.out.println(ex.getMessage());
}
}
}
程序产生的参数:
p
=
1254298063125829847416982813567929512337411373424791042335938115492587778679389342376429
5491518748603677400966339423227946984275456817266962845092077360901
q
=
1318909742479177278180754444999925413620686256837030820640322631798245030951305458966078
1355439575940971853188446666966589685846013579360490926418742418977
n
=
1654305935429419089508659437102527953852565598818954409831768871573070706674565065696515
8864494251285810127608733918537252558059319743839475663415254173255336700650290617816099
1961927839141142690958862689043343248332699287911580323087899505535013155775294127284775
662365897053414640681513676290727702980218277
e
=
2575787895500266704420933586060586178533015185521416869643059760461810496503515630568603
86404286909294456262756930415966657263126256101464211096540700818967
d
=
2662931820407137350193989089526325262935147949273781456738926196092414284318185931608913
8863008183650716663158256456346546726406986325879415530976445364599879607574426275018544
6044477275180598605983813219508475132381822004449257778011575741462570697056091695349573
45047377730730086842567608598535415994446503
成功生成(总时间:7 秒)
程序读入 plaintext 文件,将其加密成 ciphertext 文件,然后再解密成 decryptext 文件,下面
是三个文件的情况,可见 plaintext 和 decryptext 文件完全一致。
2. SHA
SHA 简介
安全哈希算法(Secure Hash Algorithm)主要适用于数字签名标准(Digital Signature
Standard DSS)里面定义的数字签名算法(Digital Signature Algorithm DSA)。对于长度小于
2^64 位的消息,SHA1 会产生一个 160 位的消息摘要。当接收到消息的时候,这个消息摘要
可以用来验证数据的完整性。在传输的过程中,数据很可能会发生变化,那么这时候就会产
生不同的消息摘要。
SHA1 有如下特性:不可以从消息摘要中复原信息;两个不同的消息不会产生同样的消
息摘要。
SHA 原理
SHA-1 压缩算法中的一个
循环。A, B, C, D 和 E 是
这个 state 中的 32 位元
文字;F 是会变化的非线
性函数;<<
位(Bit),字节(Byte)和字(Word)
SHA1 始终把消息当成一个位(bit)字符串来处理。本文中,一个“字”(Word)是 32
位,而一个“字节”(Byte)是 8 位。比如,字符串“abc”可以被转换成一个位字符串:01100001
01100010 01100011。它也可以被表示成 16 进制字符串: 0x616263.
运算符和符号
循 环 左 移 位 操 作 符 Sn(X) 。 X 是 一 个 字 , n 是 一 个 整 数 , 0<=n<=32 。 Sn(X) =
(X<>32-n)
补位
消息必须进行补位,以使其长度在对 512 取模以后的余数是 448。也就是说,(补位后
的消息长度)%512 = 448。即使长度已经满足对 512 取模后余数是 448,补位也必须要进行。
补位是这样进行的:先补一个 1,然后再补 0,直到长度满足对 512 取模后余数是 448。
总而言之,补位是至少补一位,最多补 512 位。。
补长度
所谓的补长度是将原始数据的长度补到已经进行了补位操作的消息后面。通常用一个
64 位的数据来表示原始消息的长度。如果消息长度不大于 2^64,那么第一个字就是 0。
如果原始的消息长度超过了 512,我们需要将它补成 512 的倍数。然后我们把整个消息
分成一个一个 512 位的数据块,分别处理每一个数据块,从而得到消息摘要。
计算消息摘要
必须使用进行了补位和补长度后的消息来计算消息摘要。计算需要两个缓冲区,每个都
由 5 个 32 位的字组成,还需要一个 80 个 32 位字的缓冲区。第一个 5 个字的缓冲区被标识
为 A,B,C,D,E。第一个 5 个字的缓冲区被标识为 H0, H1, H2, H3, H4