当前位置:文档之家› DES加密算法实验报告

DES加密算法实验报告

苏州科技学院实验报告学生姓名:杨刘涛学号:1220126117 指导教师:陶滔刘学书1220126114实验地点:计算机学院大楼东309 实验时间:2015-04-20一、实验室名称:软件实验室二、实验项目名称:DES加解密算法实现三、实验学时:4学时四、实验原理:DES算法由加密、子密钥和解密的生成三部分组成。

现将DES算法介绍如下。

1.加密DES算法处理的数据对象是一组64比特的明文串。

设该明文串为m=m1m2…m64 (mi=0或1)。

明文串经过64比特的密钥K来加密,最后生成长度为64比特的密文E。

其加密过程图示如下:图2-1:DES算法加密过程对DES算法加密过程图示的说明如下:待加密的64比特明文串m,经过IP置换(初始置换)后,得到的比特串的下标列表如下:表2-1:得到的比特串的下标列表IP 58 50 42 34 26 18 10 2 60 52 44 36 28 20 12 4 62 54 46 38 30 22 14 6 64 56 48 40 32 24 16 8 57 49 41 33 25 17 9 1 59 51 43 35 27 19 11 3 61 53 45 37 29 21 13 5 63 55 47 39 31 23 15 7该比特串被分为32位的L0和32位的R0两部分。

R0子密钥K1(子密钥的生成将在后面讲)经过变换f(R0,K1)(f变换将在下面讲)输出32位的比特串f1,f1与L0做不进位的二进制加法运算。

运算规则为:f1与L0做不进位的二进制加法运算后的结果赋给R1,R0则原封不动的赋给L1。

L1与R0又做与以上完全相同的运算,生成L2,R2……一共经过16次运算。

最后生成R16和L16。

其中R16为L15与f(R15,K16)做不进位二进制加法运算的结果,L16是R15的直接赋值。

R16与L16合并成64位的比特串。

值得注意的是R16一定要排在L16前面。

R16与L16合并后成的比特串,经过置换IP-1(终结置换)后所得比特串的下标列表如下:表2-2:置换后所得比特串的下标列表IP-1 40 8 48 16 56 24 64 32 39 7 47 15 55 23 63 31 38 6 46 14 54 22 62 30 37 5 45 13 53 21 61 29 36 4 44 12 52 20 60 28 35 3 43 11 51 19 59 27 34 2 42 10 50 18 58 26 33 1 41 9 49 17 57 25经过置换IP-1后生成的比特串就是密文e。

变换f(Ri-1,Ki):它的功能是将32比特的输入再转化为32比特的输出。

其过程如图2-2所示:图2-2:将32比特的输入再转化为32比特的输出f变换说明:输入Ri-1(32比特)经过变换E(扩展置换E)后,膨胀为48比特。

膨胀后的比特串的下标列表如下:表2-3:膨胀后的比特串的下标列表E: 32 1 2 3 4 5 4 5 6 7 8 9 8 9 10 11 12 13 12 13 14 15 16 17 16 17 18 19 20 21 20 21 22 23 24 25 24 25 26 27 28 29 28 29 30 31 32 1膨胀后的比特串分为8组,每组6比特。

各组经过各自的S盒后,又变为4比特(具体过程见后),合并后又成为32比特。

该32比特经过P变换(压缩置换P)后,其下标列表如下:表2-4:压缩置换P后的下标列表P: 16 7 20 21 29 12 28 17 1 15 23 26 5 18 31 10 2 8 24 14 32 27 3 9 19 13 30 622 11 4 25经过P变换后输出的比特串才是32比特的f(Ri-1,Ki).S盒的变换过程: 任取一S盒。

见图2-3:图2-3在其输入b1,b2,b3,b4,b5,b6中,计算出x=b1*2+b6,y=b5+b4*2+b3*4+b2*8,再从Si表中查出x 行,y 列的值Sxy。

将Sxy化为二进制,即得Si盒的输出。

(S表如图2-4所示)图2-4以上是DES算法加密原理五、实验目的:了解DES加密算法及原理,掌握其基本应用。

六、实验内容:了解DES加密算法及原理,掌握其基本应用,利用java编程实现。

七、实验器材(设备、元器件):(1)PC(2)Windows 8.1系统平台(3)java程序开发环境。

八、源代码:package WindowsDemo;public class DesUtil {byte[] bytekey;public DesUtil(String strKey) {this.bytekey = strKey.getBytes();}// 声明常量字节数组private static final int[] IP = { 58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48,40, 32, 24, 16, 8, 57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35,27, 19, 11, 3, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31,23, 15, 7 }; // 64private static final int[] IP_1 = { 40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45,13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11,51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49,17, 57, 25 }; // 64private static final int[] PC_1 = { 57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44,36, 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 14, 6,61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4 }; // 56private static final int[] PC_2 = { 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21,10, 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, 41, 52, 31, 37, 47,55, 30, 40, 51, 45, 33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36,29, 32 }; // 48private static final int[] E = { 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9,10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 16, 17, 18, 19, 20, 21, 20,21, 22, 23, 24, 25, 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1 }; // 48private static final int[] P = { 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23,26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22,11, 4, 25 }; // 32private static final int[][][] S_Box = {//S-盒{// S_Box[1]{ 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 },{ 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 },{ 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0 },{ 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 } },{ // S_Box[2]{ 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 },{ 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 },{ 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15 },{ 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 } },{ // S_Box[3]{ 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 },{ 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1 },{ 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7 },{ 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 } },{ // S_Box[4]{ 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 },{ 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 },{ 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4 },{ 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 } },{ // S_Box[5]{ 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 },{ 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 },{ 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14 },{ 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 } },{ // S_Box[6]{ 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 },{ 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8 },{ 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6 },{ 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 } },{ // S_Box[7]{ 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 },{ 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6 },{ 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2 },{ 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 } },{ // S_Box[8]{ 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 },{ 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2 },{ 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8 },{ 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 } }};private static final int[] LeftMove = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2,2, 2, 2, 1 };// 左移位置列表private byte[] UnitDes(byte[] des_key, byte[] des_data, int flag) { // 检测输入参数格式是否正确,错误直接返回空值(null)if ((des_key.length != 8) || (des_data.length != 8)|| ((flag != 1) && (flag != 0))) {throw new RuntimeException("Data Format Error !");}int flags = flag;// 二进制加密密钥int[] keydata = new int[64];// 二进制加密数据int[] encryptdata = new int[64]; // 加密操作完成后的字节数组byte[] EncryptCode = new byte[8];// 密钥初试化成二维数组int[][] KeyArray = new int[16][48];// 将密钥字节数组转换成二进制字节数组 keydata = ReadDataToBirnaryIntArray(des_key);// 将加密数据字节数组转换成二进制字节数组encryptdata = ReadDataToBirnaryIntArray(des_data);// 初试化密钥为二维密钥数组KeyInitialize(keydata, KeyArray); // 执行加密解密操作EncryptCode = Encrypt(encryptdata, flags, KeyArray);return EncryptCode;}// 初试化密钥数组private void KeyInitialize(int[] key, int[][] keyarray) {int i;int j;int[] K0 = new int[56];// 特别注意:xxx[IP[i]-1]等类似变换for (i = 0; i < 56; i++) {K0[i] = key[PC_1[i] - 1]; // 密钥进行PC-1变换}for (i = 0; i < 16; i++) {LeftBitMove(K0, LeftMove[i]); // 特别注意:xxx[IP[i]-1]等类似变换for (j = 0; j < 48; j++) {keyarray[i][j] = K0[PC_2[j] - 1]; // 生成子密钥keyarray[i][j]}}} // 执行加密解密操作private byte[] Encrypt(int[] timeData, int flag, int[][] keyarray) { int i;byte[] encrypt = new byte[8];int flags = flag;int[] M = new int[64];int[] MIP_1 = new int[64];// 特别注意:xxx[IP[i]-1]等类似变换for (i = 0; i < 64; i++) {M[i] = timeData[IP[i] - 1]; // 明文IP变换}if (flags == 1) { // 加密for (i = 0; i < 16; i++) {LoopF(M, i, flags, keyarray);}} else if (flags == 0) { // 解密for (i = 15; i > -1; i--) {LoopF(M, i, flags, keyarray);}}for (i = 0; i < 64; i++) {MIP_1[i] = M[IP_1[i] - 1]; // 进行IP-1运算}GetEncryptResultOfByteArray(MIP_1, encrypt);// 返回加密数据return encrypt;}private int[] ReadDataToBirnaryIntArray(byte[] intdata) {int i;int j;// 将数据转换为二进制数,存储到数组int[] IntDa = new int[8];for (i = 0; i < 8; i++) {IntDa[i] = intdata[i];if (IntDa[i] < 0) {IntDa[i] += 256;IntDa[i] %= 256;}}int[] IntVa = new int[64];for (i = 0; i < 8; i++) {for (j = 0; j < 8; j++) {IntVa[((i * 8) + 7) - j] = IntDa[i] % 2;IntDa[i] = IntDa[i] / 2;}}return IntVa;}private void LeftBitMove(int[] k, int offset) { int i;// 循环移位操作函数int[] c0 = new int[28];int[] d0 = new int[28];int[] c1 = new int[28];int[] d1 = new int[28];for (i = 0; i < 28; i++) {c0[i] = k[i];d0[i] = k[i + 28];}if (offset == 1) {for (i = 0; i < 27; i++) { // 循环左移一位c1[i] = c0[i + 1];d1[i] = d0[i + 1];}c1[27] = c0[0];d1[27] = d0[0];} else if (offset == 2) {for (i = 0; i < 26; i++) { // 循环左移两位c1[i] = c0[i + 2];d1[i] = d0[i + 2];}c1[26] = c0[0];d1[26] = d0[0];c1[27] = c0[1];d1[27] = d0[1];}for (i = 0; i < 28; i++) {k[i] = c1[i];k[i + 28] = d1[i];}}private void LoopF(int[] M, int times, int flag, int[][] keyarray) {int i;int j;int[] L0 = new int[32];int[] R0 = new int[32];int[] L1 = new int[32];int[] R1 = new int[32];int[] RE = new int[48];int[][] S = new int[8][6];int[] sBoxData = new int[8];int[] sValue = new int[32];int[] RP = new int[32];for (i = 0; i < 32; i++) {L0[i] = M[i]; // 明文左侧的初始化R0[i] = M[i + 32]; // 明文右侧的初始化}for (i = 0; i < 48; i++) {RE[i] = R0[E[i] - 1]; // 经过E变换扩充,由32位变为48位RE[i] = RE[i] + keyarray[times][i]; // 与KeyArray[times][i]按位作不进位加法运算if (RE[i] == 2) {RE[i] = 0;}}for (i = 0; i < 8; i++) { // 48位分成8组for (j = 0; j < 6; j++) {S[i][j] = RE[(i * 6) + j];}// 下面经过S盒,得到8个数sBoxData[i] = S_Box[i][(S[i][0] << 1) + S[i][5]][(S[i][1] << 3)+ (S[i][2] << 2) + (S[i][3] << 1) + S[i][4]];// 8个数变换输出二进制for (j = 0; j < 4; j++) {sValue[((i * 4) + 3) - j] = sBoxData[i] % 2;sBoxData[i] = sBoxData[i] / 2;}}for (i = 0; i < 32; i++) {RP[i] = sValue[P[i] - 1]; // 经过P变换L1[i] = R0[i]; // 右边移到左边R1[i] = L0[i] + RP[i];if (R1[i] == 2) {R1[i] = 0;}// 重新合成M,返回数组M// 最后一次变换时,左右不进行互换。

相关主题