一、目的
通过对RSA工具与RC4算法实现,掌握RSA与RC4基本原理。
二、环境
两台安装windows的主机,通过网络相连。
软件工具:MD5Verify、MD5Crack、RSA-TOOLS。这里用到的工具请自行百度获取。
三、实验步骤
使用RSA-TOOLS工具,完成RSA加密。
为了生成符合要求的随机RSA**,操作如下:
1、在“Number Base”组合框中选择进制为 10 ;
2、单击“Start”按钮,然后随意移动鼠标直到提示信息框出现,以获取一个随机数种子;
3、在“KeySize(Bits)”编辑框中输入 32 ;
4、单击“Generate”按钮生成;
5、复制“Prime(P)”编辑框中的内容到“Public Exp.(E)”编辑框;
6、在“Number Base”组合框中选择进制为 16 ;
7、记录下“Prime(P)”编辑框中的十六进制文本内容,此时得到了公钥e,(e,n)公开。
8、再次重复第 2 步;
9、在“KeySize(Bits)”编辑框中输入您所希望的**位数,从32到4096,位数越多安全性也高,但运算速度越慢,一般选择1024位足够了;
10、单击“Generate”按钮生成,此时得到私钥d,(d,n)私有;
11、单击“Test”按钮测试,在“Message to encrypt”编辑框中随意输入一段文本,然后单击“Encrypt”按钮加密,再单击“Decrypt”按钮解密,看解密后的结果是否和所输入的一致,如果一致表示所生成的RSA**可用,否则需要重新生成;
12、到此生成完成,“Private Exp.(D)”编辑框中的内容为私钥,第7步所记录的内容为公钥,“Modulus (N)”编辑框中的内容为公共模数,请将上述三段十六进制文本保存起来即可。
4、帮助文档
查阅官方文档
RSA原理
1. 选择两个大素数 p, q , p¹q,保密;
2. 计算n=p´q,公开n;
3. 计算f(n) =(p-1)(q-1);
4. 选取一个与f(n) 互素的整数e, 即 gcd (e, f(n) )=1; 1<e< f(n) (e,n)为公钥;
5. 计算d, 使得 de ≡1 mod f(n) , e ´ d =kf(n) +1 (d<ф(n) ) d 为私钥。
2、编程实现RC4算法,并上机验证。
//初始化S数组,S[0]=0,S[1]=1, …… ,S[255]=255
//T是临时数组,K是**
算法:
for i = 0 to 255 do {
S[i] = i
T[i] = K[i mod keylen])
}
j = 0
for i = 0 to 255 do {
j = (j + S[i] + T[i]) (mod 256)
swap (S[i], S[j])
}
//加密
i = j = 0
for each message byte Mi(Ci){
i = (i + 1) (mod 256)
j = (j + S[i]) (mod 256)
swap(S[i], S[j])
t = (S[i] + S[j]) (mod 256)
K= S[t]
Ci = Mi XOR k ( Mi = Ci XOR k )
}
实例代码:
package demo;
public class MYRC4 {
public static void main(String[] args) {
MYRC4 rc4 = new MYRC4();
String plaintext = "我是个卧底,007";
String key = "007007";
String ciphertext = rc4.encrypt(plaintext, key);
String decryptText = rc4.encrypt(ciphertext, key);
System.out.print(
"明文为:" + plaintext + "\n" + "**为:" + key + "\n\n" + "密文为:" + ciphertext + "\n" + "解密为:" + decryptText);
}
/**
* 3.加解密过程是一样的
* 加密:明文流字与**流字XOR得到密文流字
* 解密:密文流字与**流字XOR得到明文流字
* */
public String encrypt(final String plainOrCipherText, final String key) {
Integer[] S = new Integer[256]; // S盒
Character[] keySchedul = new Character[plainOrCipherText.length()]; // 生成的**流
StringBuffer ciphertext = new StringBuffer();
ksa(S, key);
rpga(S, keySchedul, plainOrCipherText.length());
for (int i = 0; i < plainOrCipherText.length(); ++i) {
ciphertext.append((char) (plainOrCipherText.charAt(i) ^ keySchedul[i]));
}
return ciphertext.toString();
}
/*1.初始化向量S*/
public void ksa(Integer[] s, String key) {
for (int i = 0; i < 256; ++i) {
s[i] = i;
}
int j = 0;
for (int i = 0; i < 256; ++i) {
j = (j + s[i] + key.charAt(i % key.length())) % 256;
swap(s, i, j);
}
}
/*2.伪随机生成算法*/
public void rpga(Integer[] s, Character[] keySchedul, int plaintextLength) {
int i = 0, j = 0;
for (int k = 0; k < plaintextLength; ++k) {
i = (i + 1) % 256;
j = (j + s[i]) % 256;
swap(s, i, j);
keySchedul[k] = (char) (s[(s[i] + s[j]) % 256]).intValue();
}
}
/*置换*/
public void swap(Integer[] s, int i, int j) {
Integer mTemp = s[i];
s[i] = s[j];
s[j] = mTemp;
}
}
输出结果: