第二次作业
1、源码
/*
@author liuxin
*/
import java.io.*;
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
public class sdes{
public static void main(String args[]) {
String s1 = "0101010101010101";
String s2 = "1f1f1f1f0e0e0e0e";
String s3 = "e0e0e0e0f1f1f1f1";
String s4 = "fefefefefefefefe";
String Algrithm = "DES";
String code = "hello world!";
byte[] kb1 = s1.getBytes();
byte[] kb2 = s2.getBytes();
byte[] kb3 = s3.getBytes();
byte[] kb4 = s4.getBytes();
doEncode(readByteArray
(kb1),Algrithm,code);
doEncode(readByteArray
(kb2),Algrithm,code);
doEncode(readByteArray
(kb3),Algrithm,code);
doEncode(readByteArray
(kb4),Algrithm,code);
}
public static byte[] readByteArray(byte[]
b){
byte[] returnB = new byte [(int)
b.length/2];
if ((b.length%2)==1){
System.out.println("hehe
,wrong");
return returnB;
}
for (int i = 0,j = 0;i <
b.length;i++){
if (b[i] < 0X3A){
returnB[j] =
(byte)((b[i] & 0X0F) << 4);
}
else{
returnB[j] =
(byte)(((b[i] & 0X0F)+0X09) << 4);
}//high bit
if (b[++i] < 0X3A){
returnB[j] =
(byte)(returnB[j] | (b[i] & 0X0F));
}
else{
returnB[j] =
(byte)(returnB[j] | ((b[i] & 0X0F) + 0X09));
}
j++;
}
return returnB;
}
public static void doEncode(byte[]
encodeKey,String Algrithm,String code){
try{
//get specified key
SecretKeySpec key = new
SecretKeySpec(encodeKey,Algrithm);
//encoding ...
Cipher cp =
Cipher.getInstance(Algrithm);
cp.init
(Cipher.ENCRYPT_MODE,key);
//origin code
byte[] originCode =
code.getBytes("UTF8");
//output origin code
if (times==1){
/*for (int i =
0;i<originCode.length;i++){
System.out.print
(originCode[i]+" ");
}*/
System.out.print
(byte2hex(originCode));
}
times++;
System.out.println(" ");
//do encode
byte[] enCode =
cp.doFinal(originCode);
//output the encoded code
/*for (int i =
0;i<enCode.length;i++){
System.out.print
(enCode[i]+" ");
}*/
System.out.print(byte2hex
(enCode));
System.out.println("");
System.out.println
(byte2hex(encodeKey));
}
catch
(java.security.NoSuchAlgorithmException e1)
{e1.printStackTrace();}
catch
(javax.crypto.NoSuchPaddingException e2)
{e2.printStackTrace();}
catch (java.lang.Exception e3)
{e3.printStackTrace();}
}
public static String byte2hex(byte[] b) //
二行制转字符串
{
String hs="";
String stmp="";
for (int n=0;n<b.length;n++)
{
stmp=(java.lang.Integer.toHexString(b[n] &
0XFF));
if (stmp.length()==1) hs=hs+"0"+stmp;
else hs=hs+stmp;
if (n<b.length-1) hs=hs+":";
}
return hs.toUpperCase();
}
public static int times = 1;
}
我的说明如下:
使用的明文为:"hello world!"
密钥是key1-4,
一下是 java sdes >sdes.txt 的内容
68:65:6C:6C:6F:20:77:6F:72:6C:64:21
DE:F3:F8:EA:78:1A:12:41:C0:45:F9:53:C5:14:81:25
01:01:01:01:01:01:01:01
F8:83:2D:B2:E0:0A:89:C4:F4:60:AB:0F:14:12:54:5E
1F:1F:1F:1F:0E:0E:0E:0E
E7:AE:6C:25:00:6A:D5:AC:F7:ED:F7:FB:27:CF:21:16
E0:E0:E0:E0:F1:F1:F1:F1
11:EB:97:A9:54:01:0C:86:81:C3:C5:99:8F:11:FF:C6
FE:FE:FE:FE:FE:FE:FE:FE
由于密文和明文都是用byte[]这样的字节数组保存,故我
编写了byte2hex函数,输出数组的每个字节的16进制形式
,第一行是明文,下面每两行为一组,上面的是密文,下
面的是相应的keyn。
具体的规律就是DES加密算法的具体算法,DES是个对称的
算法,是说加密解密的密钥是对称的。DES算法进行按位
的运算,具体的算法老师的课件上有:体现的就是这个算
法的规律。
2、
在A目录下运行:
java KeyAgree Bpub.dat Apri.dat生成共享密钥
在B目录下运行:
java KeyAgree Apub.dat Bpri.dat生成共享密钥
根据代码的说明,指令执行后的输出就是共享密钥,而且
在这两个目录下运行指令得到的结果是相同的,所以运行
java KeyAgree Bpub.dat Apri.dat >share.txt 得到的
共享密钥的内容如下
1,-32,7,71,-91,69,-48,-77,-85,-35,19,16,-41,-89,-
100,56,15,-110,98,110,53,-48,-20,43,-48,15,-64,-
80,86,66,113,63,73,60,119,-
42,110,100,19,55,65,55,-73,77,2,29,-122,-46,-84,-
66,-30,-43,-54,-88,9,-127,61,56,-63,-
55,52,99,69,52,45,-109,-89,-117,119,95,89,6,-
67,62,-126,82,48,-53,60,-1,93,-44,-29,66,-62,-54,
-75,23,30,114,-85,80,-76,57,68,-18,63,125,-
118,117,99,67,41,-75,36,-86,98,74,68,22,-56,-
2,5,29,30,53,120,111,-127,-56,-44,-92,120,94,-54,
-10,-82,-90,
1. 利用DES算法,使用如下密钥进行加密,观察明文和密文的特点,总结规律
Key1(十六进制) | 0101 0101 0101 0101 |
Key2 | 1f 1f 1f 1f 0e0e 0e0e |
Key3 | E0e0 eoeo f 1f 1 f 1f 1 |
Key4 | Fefe fefe fefe fefe |
要求:给出源码、密文明文对、规律总结
2. 用diffie_hellman算法进行密钥交换
文件功能
Key_DH.java | 创建diffie_hellman的公钥和私钥 |
KeyAgree.java | 创建共享密钥 |
练习过程
建立两个目录A和B,模拟需要通信的A、B双方,由于DH算法需要A和B各自生成DH公钥和私钥,因此在这两个目录下都复制编译后的文件Key_DH。
首先由A创建自己的公钥和私钥,即在A目录下输入“java Key_DH Apub.dat Apri.dat”运行程序,这是在目录A下将产生文件Apub.dat和Apri.dat, 分别保存A的公钥和私钥。
然后由B创建自己的公钥和私钥,即在B目录下输入“java Key_DH Bpub.dat Bpri.dat”运行程序,这是在目录B下将产生文件Bpub.dat和Bpri.dat, 分别保存B的公钥和私钥。
最后发布公钥,A将Apub.dat复制到B目录,B将Bpub.dat复制到A目录。
将KeyAgree编译后分别复制到A和B两个目录。
在A目录下运行:
java KeyAgree Bpub.dat Apri.dat生成共享密钥
在B目录下运行:
java KeyAgree Apub.dat Bpri.dat生成共享密钥
要求给出最后的共享密钥