DES加密算法在C#下的实现

此程序分两部分,第一部分为主程序,另一部分为函数库

本程序中用int[]表示char的2进制形式,如'a'=int[8]{0,1,1,0,0,0,0,1}

下面副程序 本程序在C# 2005下通过。。

#region Using directives

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using System.IO;
#endregion

namespace DES_2nd
{
partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Func.Func F = new Func.Func(); // 初始化函数库

private void button1_Click(object sender, EventArgs e)
{
char[] tempmchar = mbox.Text.ToCharArray(); //原始明文

int mod = tempmchar.Length % 8; //扩展明文为8的倍数
char[] mchar = new char[tempmchar.Length + (8 - mod)];
for (int i = 0; i < tempmchar.Length; i++)
{
mchar[i] = tempmchar[i];
}
for (int i = tempmchar.Length; i < mchar.Length; i++)
{
mchar[i] = ' ';
}

char[] kchar = kbox.Text.ToCharArray();//获得64位密钥
char[] cchar = new char[mchar.Length];//初始化密文数组

int[][] keys = F.makekey(kchar);//由makekey函数通过64位密钥计算16个48位密钥

int div = mchar.Length / 8;//每8个为一组对明文分组
if ((mchar.Length % 8) != 0) div += 1;
char[][] divmchar = new char[div][];//存放分组明文
for (int i = 0; i < div; i++)
{
divmchar[i] = new char[8];
divmchar[i][0] = mchar[i * 8 + 0];
divmchar[i][1] = mchar[i * 8 + 1];
divmchar[i][2] = mchar[i * 8 + 2];
divmchar[i][3] = mchar[i * 8 + 3];
divmchar[i][4] = mchar[i * 8 + 4];
divmchar[i][5] = mchar[i * 8 + 5];
divmchar[i][6] = mchar[i * 8 + 6];
divmchar[i][7] = mchar[i * 8 + 7];
}

int[][] divcint = new int[div][];//获得分组加密后的分组密文2进制形式
for (int i = 0; i < div; i++)
{
divcint[i] = new int[64];
divcint[i] = F.DES(keys, divmchar[i]);
}

int[] cint = new int[div*64];//合并密文2进制形式
for (int i = 0; i < div; i++)
{
for (int j = 0; j < 64; j++)
{
cint[i * 64 + j] = divcint[i][j];
}
}

//初始序列化
FileStream fs = new FileStream(target.Text, FileMode.OpenOrCreate, FileAccess.Write);
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter br = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();

//将2进制密文转化为char密文
for (int i = 0; i < cchar.Length; i++)
{
cchar[i] = (char)(cchar[i] & 0x0000);
}
for (int i = 0; i < cchar.Length; i++)
{
if (cint[i * 8 + 0] == 1) cchar[i] = (char)(cchar[i] | 0x80);
if (cint[i * 8 + 1] == 1) cchar[i] = (char)(cchar[i] | 0x40);
if (cint[i * 8 + 2] == 1) cchar[i] = (char)(cchar[i] | 0x20);
if (cint[i * 8 + 3] == 1) cchar[i] = (char)(cchar[i] | 0x10);
if (cint[i * 8 + 4] == 1) cchar[i] = (char)(cchar[i] | 0x8);
if (cint[i * 8 + 5] == 1) cchar[i] = (char)(cchar[i] | 0x4);
if (cint[i * 8 + 6] == 1) cchar[i] = (char)(cchar[i] | 0x2);
if (cint[i * 8 + 7] == 1) cchar[i] = (char)(cchar[i] | 0x1);
}

//显示密文
cbox.Text = System.Text.Encoding.Default.GetString(System.Text.Encoding.Default.GetBytes(cchar));

//序列化密文到文件
br.Serialize(fs, cchar);
fs.Close();
}

private void button2_Click(object sender, EventArgs e)
{

//初始化
int[] cint = new int[64];
char[] kchar = kbox.Text.ToCharArray();
int[] kint = new int[56];

//或得16个密钥
int[][] keys = F.makekey(kchar);

//从文件反序列化或得密文char形式
FileStream fs = new FileStream(sourse.Text, FileMode.OpenOrCreate, FileAccess.Read);
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
char[] cchar = (char[])bf.Deserialize(fs);
char[] mchar = new char[cchar.Length];

//每8位一组分组密文
int div = cchar.Length / 8;
if ((cchar.Length % 8) != 0) div += 1;
char[][] divcchar = new char[div][];
for (int i = 0; i < div; i++)
{
divcchar[i] = new char[8];
divcchar[i][0] = cchar[i * 8 + 0];
divcchar[i][1] = cchar[i * 8 + 1];
divcchar[i][2] = cchar[i * 8 + 2];
divcchar[i][3] = cchar[i * 8 + 3];
divcchar[i][4] = cchar[i * 8 + 4];
divcchar[i][5] = cchar[i * 8 + 5];
divcchar[i][6] = cchar[i * 8 + 6];
divcchar[i][7] = cchar[i * 8 + 7];
}

//获得分组后明文2进制形式
int[][] divmint = new int[div][];
for (int i = 0; i < div; i++)
{
divmint[i] = new int[64];
divmint[i] = F.DES_1(keys, divcchar[i]);
}

//合并明文2进制形式
int[] mint = new int[div * 64];
for (int i = 0; i < div; i++)
{
for (int j = 0; j < 64; j++)
{
mint[i * 64 + j] = divmint[i][j];
}
}

//由明文2进制形式转化为char形式
for (int i = 0; i < mchar.Length; i++)
{
mchar[i] = (char)(mchar[i] & 0x0000);
}
for (int i = 0; i < mchar.Length; i++)
{
if (mint[i * 8 + 0] == 1) mchar[i] = (char)(mchar[i] | 0x80);
if (mint[i * 8 + 1] == 1) mchar[i] = (char)(mchar[i] | 0x40);
if (mint[i * 8 + 2] == 1) mchar[i] = (char)(mchar[i] | 0x20);
if (mint[i * 8 + 3] == 1) mchar[i] = (char)(mchar[i] | 0x10);
if (mint[i * 8 + 4] == 1) mchar[i] = (char)(mchar[i] | 0x8);
if (mint[i * 8 + 5] == 1) mchar[i] = (char)(mchar[i] | 0x4);
if (mint[i * 8 + 6] == 1) mchar[i] = (char)(mchar[i] | 0x2);
if (mint[i * 8 + 7] == 1) mchar[i] = (char)(mchar[i] | 0x1);
}

//显示明文
mbox.Text = System.Text.Encoding.Default.GetString(System.Text.Encoding.Default.GetBytes(mchar));
fs.Close();
}

}
}

以下为函数库

#region Using directives

using System;
using System.Collections.Generic;
using System.Text;

#endregion

namespace Func //函数库
{
public class Func
{

//IP置换
public int[] IP(char[] mchar)
{
int[] mint = new int[64];
int[] mreturn = new int[64];
for (int i=0;i<mint.Length;i++)
{
mint[i] = 0;
}

//将char明文转化为2进制明文
for (int i =0;i<mchar.Length;i++)
{
if ((mchar[i] & 0x80)!=0) mint[i8+0] =1;
if ((mchar[i] & 0x40)!=0) mint[i
8+1] =1;
if ((mchar[i] & 0x20)!=0) mint[i8+2] =1;
if ((mchar[i] & 0x10)!=0) mint[i
8+3] =1;
if ((mchar[i] & 0x8)!=0) mint[i8+4] =1;
if ((mchar[i] & 0x4)!=0) mint[i
8+5] =1;
if ((mchar[i] & 0x2)!=0) mint[i8+6] =1;
if ((mchar[i] & 0x1)!=0) mint[i
8+7] =1;
}

//置换表
mreturn[0] = mint[57];mreturn[1] = mint[49];mreturn[2] = mint[41];
mreturn[3] = mint[33];mreturn[4] = mint[25];mreturn[5] = mint[17];
mreturn[6] = mint[9]; mreturn[7] = mint[1]; mreturn[8] = mint[59];
mreturn[9] = mint[51];mreturn[10] = mint[43];mreturn[11] = mint[35];
mreturn[12] = mint[27];mreturn[13] = mint[19];mreturn[14] = mint[11];
mreturn[15] = mint[3];mreturn[16] = mint[61];mreturn[17] = mint[53];
mreturn[18] = mint[45];mreturn[19] = mint[37];mreturn[20] = mint[29];
mreturn[21] = mint[21];mreturn[22] = mint[13];mreturn[23] = mint[5];
mreturn[24] = mint[63];mreturn[25] = mint[55];mreturn[26] = mint[47];
mreturn[27] = mint[39];mreturn[28] = mint[31];mreturn[29] = mint[23];
mreturn[30] = mint[15];mreturn[31] = mint[7];mreturn[32] = mint[56];
mreturn[33] = mint[48];mreturn[34] = mint[40];mreturn[35] = mint[32];
mreturn[36] = mint[24];mreturn[37] = mint[16];mreturn[38] = mint[8];
mreturn[39] = mint[0];mreturn[40] = mint[58];mreturn[41] = mint[50];
mreturn[42] = mint[42];mreturn[43] = mint[34];mreturn[44] = mint[26];
mreturn[45] = mint[18];mreturn[46] = mint[10];mreturn[47] = mint[2];
mreturn[48] = mint[60];mreturn[49] = mint[52];mreturn[50] = mint[44];
mreturn[51] = mint[36];mreturn[52] = mint[28];mreturn[53] = mint[20];
mreturn[54] = mint[12];mreturn[55] = mint[4];mreturn[56] = mint[62];
mreturn[57] = mint[54];mreturn[58] = mint[46];mreturn[59] = mint[38];
mreturn[60] = mint[30];mreturn[61] = mint[22];mreturn[62] = mint[14];
mreturn[63] = mint[6];
return mreturn;
}
//IP-1置换
public int[] IP_1(int[] mchar)
{
//置换表
int[] IPreturn = new int[64];
IPreturn[0] = mchar[39];
IPreturn[1] = mchar[7];
IPreturn[2] = mchar[47];
IPreturn[3] = mchar[15];
IPreturn[4] = mchar[55];
IPreturn[5] = mchar[23];
IPreturn[6] = mchar[63];
IPreturn[7] = mchar[31];
IPreturn[8] = mchar[38];
IPreturn[9] = mchar[6];
IPreturn[10] = mchar[46];
IPreturn[11] = mchar[14];
IPreturn[12] = mchar[54];
IPreturn[13] = mchar[22];
IPreturn[14] = mchar[62];
IPreturn[15] = mchar[30];
IPreturn[16] = mchar[37];
IPreturn[17] = mchar[5];
IPreturn[18] = mchar[45];
IPreturn[19] = mchar[13];
IPreturn[20] = mchar[53];
IPreturn[21] = mchar[21];
IPreturn[22] = mchar[61];
IPreturn[23] = mchar[29];
IPreturn[24] = mchar[36];
IPreturn[25] = mchar[4];
IPreturn[26] = mchar[44];
IPreturn[27] = mchar[12];
IPreturn[28] = mchar[52];
IPreturn[29] = mchar[20];
IPreturn[30] = mchar[60];
IPreturn[31] = mchar[28];
IPreturn[32] = mchar[35];
IPreturn[33] = mchar[3];
IPreturn[34] = mchar[43];
IPreturn[35] = mchar[11];
IPreturn[36] = mchar[51];
IPreturn[37] = mchar[19];
IPreturn[38] = mchar[59];
IPreturn[39] = mchar[27];
IPreturn[40] = mchar[34];
IPreturn[41] = mchar[2];
IPreturn[42] = mchar[42];
IPreturn[43] = mchar[10];
IPreturn[44] = mchar[50];
IPreturn[45] = mchar[18];
IPreturn[46] = mchar[58];
IPreturn[47] = mchar[26];
IPreturn[48] = mchar[33];
IPreturn[49] = mchar[1];
IPreturn[50] = mchar[41];
IPreturn[51] = mchar[9];
IPreturn[52] = mchar[49];
IPreturn[53] = mchar[17];
IPreturn[54] = mchar[57];
IPreturn[55] = mchar[25];
IPreturn[56] = mchar[32];
IPreturn[57] = mchar[0];
IPreturn[58] = mchar[40];
IPreturn[59] = mchar[8];
IPreturn[60] = mchar[48];
IPreturn[61] = mchar[16];
IPreturn[62] = mchar[56];
IPreturn[63] = mchar[24];
return IPreturn;
}
//由64位原始密钥计算16个48位密钥
public int[][] makekey(char[] kchar)
{
//16位数组存放16个输出密钥
int[][] keyreturn = new int[16][];
int[] temp = new int[64];
int[] kint = new int[56];
int[] c0 = new int[28]; int[] d0 = new int[28];
int[] c16 = new int[28]; int[] d1 = new int[28];
int[] c1 = new int[28]; int[] d2 = new int[28];
int[] c2 = new int[28]; int[] d3 = new int[28];
int[] c3 = new int[28]; int[] d4 = new int[28];
int[] c4 = new int[28]; int[] d5 = new int[28];
int[] c5 = new int[28]; int[] d6 = new int[28];
int[] c6 = new int[28]; int[] d7 = new int[28];
int[] c7 = new int[28]; int[] d8 = new int[28];
int[] c8 = new int[28]; int[] d9 = new int[28];
int[] c9 = new int[28]; int[] d10 = new int[28];
int[] c10 = new int[28]; int[] d11 = new int[28];
int[] c11 = new int[28]; int[] d12 = new int[28];
int[] c12 = new int[28]; int[] d13 = new int[28];
int[] c13 = new int[28]; int[] d14 = new int[28];
int[] c14 = new int[28]; int[] d15 = new int[28];
int[] c15 = new int[28]; int[] d16 = new int[28];
int[] k1 = new int[48]; int[] k2 = new int[48]; int[] k3 = new int[48];
int[] k4 = new int[48]; int[] k5 = new int[48]; int[] k6 = new int[48];
int[] k7 = new int[48]; int[] k8 = new int[48]; int[] k9 = new int[48];
int[] k10 = new int[48]; int[] k11 = new int[48]; int[] k12 = new int[48];
int[] k13 = new int[48]; int[] k14 = new int[48]; int[] k15 = new int[48];
int[] k16 = new int[48];

//获得原始密钥2进制形式
for (int i=0;i<kchar.Length;i++)
{
if ((kchar[i] & 0x80)!=0) temp[i8 +0] =1;
if ((kchar[i] & 0x40)!=0) temp[i
8 +1] =1;
if ((kchar[i] & 0x20)!=0) temp[i8 +2] =1;
if ((kchar[i] & 0x10)!=0) temp[i
8 +3] =1;
if ((kchar[i] & 0x8)!=0) temp[i8 +4] =1;
if ((kchar[i] & 0x4)!=0) temp[i
8 +5] =1;
if ((kchar[i] & 0x2)!=0) temp[i8 +6] =1;
if ((kchar[i] & 0x1)!=0) temp[i
8 +7] =1;
}

//去掉7。。15。。。。。63的奇校检位并打乱
kint[0] = temp[56];
kint[1] = temp[48];
kint[2] = temp[40];
kint[3] = temp[32];
kint[4] = temp[24];
kint[5] = temp[16];
kint[6] = temp[8];
kint[7] = temp[0];
kint[8] = temp[57];
kint[9] = temp[49];
kint[10] = temp[41];
kint[11] = temp[33];
kint[12] = temp[25];
kint[13] = temp[17];
kint[14] = temp[9];
kint[15] = temp[1];
kint[16] = temp[58];
kint[17] = temp[50];
kint[18] = temp[42];
kint[19] = temp[34];
kint[20] = temp[26];
kint[21] = temp[18];
kint[22] = temp[10];
kint[23] = temp[2];
kint[24] = temp[59];
kint[25] = temp[51];
kint[26] = temp[43];
kint[27] = temp[35];
kint[28] = temp[62];
kint[29] = temp[54];
kint[30] = temp[46];
kint[31] = temp[38];
kint[32] = temp[30];
kint[33] = temp[22];
kint[34] = temp[14];
kint[35] = temp[6];
kint[36] = temp[61];
kint[37] = temp[53];
kint[38] = temp[45];
kint[39] = temp[37];
kint[40] = temp[29];
kint[41] = temp[21];
kint[42] = temp[13];
kint[43] = temp[5];
kint[44] = temp[60];
kint[45] = temp[52];
kint[46] = temp[44];
kint[47] = temp[36];
kint[48] = temp[28];
kint[49] = temp[20];
kint[50] = temp[12];
kint[51] = temp[4];
kint[52] = temp[27];
kint[53] = temp[19];
kint[54] = temp[11];
kint[55] = temp[3];

//分组56位密钥为2部分
for (int i=0;i<28;i++)
{
c0[i] = kint[i];
d0[i] = kint[i+28];
}

//循环左移1位
for (int i = 1; i < 28; i++)
{
c1[i - 1] = c0[i];
d1[i - 1] = d0[i];
}
c1[27] = c0[0];
d1[27] = d0[0];

//循环左移1位
for (int i = 1; i < 28; i++)
{
c2[i - 1] = c1[i];
d2[i - 1] = d1[i];
}
c2[27] = c1[0];
d2[27] = d1[0];

//循环左移2位
for (int i = 2; i < 28; i++)
{
c3[i - 2] = c2[i];
d3[i - 2] = d2[i];
}
c3[26] = c2[0];
c3[27] = c2[1];

d3[26] = d2[0];
d3[27] = d2[1];
//循环左移2位
for (int i = 2; i < 28; i++)
{
c4[i - 2] = c3[i];
}
c4[26] = c3[0];
c4[27] = c3[1];
for (int i = 2; i < 28; i++)
{
d4[i - 2] = d3[i];
}
d4[26] = d3[0];
d4[27] = d3[1];
//循环左移2位
for (int i = 2; i < 28; i++)
{
c5[i - 2] = c4[i];
}
c5[26] = c4[0];
c5[27] = c4[1];
for (int i = 2; i < 28; i++)
{
d5[i - 2] = d4[i];
}
d5[26] = d4[0];
d5[27] = d4[1];
//循环左移2位
for (int i = 2; i < 28; i++)
{
c6[i - 2] = c5[i];
}
c6[26] = c5[0];
c6[27] = c5[1];
for (int i = 2; i < 28; i++)
{
d6[i - 2] = d5[i];
}
d6[26] = d5[0];
d6[27] = d5[1];
//循环左移2位
for (int i = 2; i < 28; i++)
{
c7[i - 2] = c6[i];
}
c7[26] = c6[0];
c7[27] = c6[1];
for (int i = 2; i < 28; i++)
{
d7[i - 2] = d6[i];
}
d7[26] = d6[0];
d7[27] = d6[1];
//循环左移2位
for (int i = 2; i < 28; i++)
{
c8[i - 2] = c7[i];
}
c8[26] = c7[0];
c8[27] = c7[1];
for (int i = 2; i < 28; i++)
{
d8[i - 2] = d7[i];
}
d8[26] = d7[0];
d8[27] = d7[1];
//循环左移1位
for (int i = 1; i < 28; i++)
{
c9[i - 1] = c8[i];
}
c9[27] = c8[0];
for (int i = 1; i < 28; i++)
{
d9[i - 1] = d8[i];
}
d9[27] = d8[0];
//循环左移2位
for (int i = 2; i < 28; i++)
{
c10[i - 2] = c9[i];
}
c10[26] = c9[0];
c10[27] = c9[1];
for (int i = 2; i < 28; i++)
{
d10[i - 2] = d9[i];
}
d10[26] = d9[0];
d10[27] = d9[1];
//循环左移2位
for (int i = 2; i < 28; i++)
{
c11[i - 2] = c10[i];
}
c11[26] = c10[0];
c11[27] = c10[1];
for (int i = 2; i < 28; i++)
{
d11[i - 2] = d10[i];
}
d11[26] = d10[0];
d11[27] = d10[1];
//循环左移2位
for (int i = 2; i < 28; i++)
{
c12[i - 2] = c11[i];
}
c12[26] = c11[0];
c12[27] = c11[1];
for (int i = 2; i < 28; i++)
{
d12[i - 2] = d11[i];
}
d12[26] = d11[0];
d12[27] = d11[1];
//循环左移2位
for (int i = 2; i < 28; i++)
{
c13[i - 2] = c12[i];
}
c13[26] = c12[0];
c13[27] = c12[1];
for (int i = 2; i < 28; i++)
{
d13[i - 2] = d12[i];
}
d13[26] = d12[0];
d13[27] = d12[1];
//循环左移2位
for (int i = 2; i < 28; i++)
{
c14[i - 2] = c13[i];
}
c14[26] = c13[0];
c14[27] = c13[1];
for (int i = 2; i < 28; i++)
{
d14[i - 2] = d13[i];
}
d14[26] = d13[0];
d14[27] = d13[1];
//循环左移2位
for (int i = 2; i < 28; i++)
{
c15[i - 2] = c14[i];
}
c15[26] = c14[0];
c15[27] = c14[1];
for (int i = 2; i < 28; i++)
{
d15[i - 2] = d14[i];
}
d15[26] = d14[0];
d15[27] = d14[1];
//循环左移1位
for (int i = 1; i < 28; i++)
{
c16[i - 1] = c15[i];
}
c16[27] = c15[0];
for (int i = 1; i < 28; i++)
{
d16[i - 1] = d15[i];
}
d16[27] = d15[0];

//合并Ci,Di并由PC2置换计算最终16个密钥
k1 = PC2(c1, d1);
k2 = PC2(c2, d2);
k3 = PC2(c3, d3);
k4 = PC2(c4, d4);
k5 = PC2(c5, d5);
k6 = PC2(c6, d6);
k7 = PC2(c7, d7);
k8 = PC2(c8, d8);
k9 = PC2(c9, d9);
k10 = PC2(c10, d10);
k11 = PC2(c11, d11);
k12 = PC2(c12, d12);
k13 = PC2(c13, d13);
k14 = PC2(c14, d14);
k15 = PC2(c15, d15);
k16 = PC2(c16, d16);

keyreturn[0] = (int[])k1.Clone();
keyreturn[1] = (int[])k2.Clone();
keyreturn[2] = (int[])k3.Clone();
keyreturn[3] = (int[])k4.Clone();
keyreturn[4] = (int[])k5.Clone();
keyreturn[5] = (int[])k6.Clone();
keyreturn[6] = (int[])k7.Clone();
keyreturn[7] = (int[])k8.Clone();
keyreturn[8] = (int[])k9.Clone();
keyreturn[9] = (int[])k10.Clone();
keyreturn[10] = (int[])k11.Clone();
keyreturn[11] = (int[])k12.Clone();
keyreturn[12] = (int[])k13.Clone();
keyreturn[13] = (int[])k14.Clone();
keyreturn[14] = (int[])k15.Clone();
keyreturn[15] = (int[])k16.Clone();

return keyreturn;

}
//PC2置换
public int[] PC2(int[] c, int[] d)
{
int[] temp = new int[56];
int[] k = new int[48];
//合并Ci和Di
for (int i = 0; i < 28; i++)
{
temp[i] = c[i];
temp[i + 28] = d[i];
}

//置换表
k[0] = temp[13];
k[1] = temp[16];
k[2] = temp[10];
k[3] = temp[23];
k[4] = temp[0];
k[5] = temp[4];
k[6] = temp[2];
k[7] = temp[27];
k[8] = temp[14];
k[9] = temp[5];
k[10] = temp[20];
k[11] = temp[9];
k[12] = temp[22];
k[13] = temp[18];
k[14] = temp[11];
k[15] = temp[3];
k[16] = temp[25];
k[17] = temp[7];
k[18] =

Published At
Categories with Web编程
Tagged with
comments powered by Disqus