@veightz
2014-10-03T15:49:09.000000Z
字数 6046
阅读 2041
DES 密码学
算法思路
DES加密算法用多次运用到基于二维矩阵的二进制变换,所以可以实现一个统一的变换函数,每次使用不同的矩阵用于变换处理即可.实现的时候只需留意代码中的数组的下标是从0开始的,而提供的二维矩阵的数据是从1开始计数的,稍作处理即可.
实现代码
void transform(bool *Out, bool *In, const char *Table, int len){static bool Tmp[256];for(int i = 0; i < len; i++){Tmp[i] = In[ Table[i] - 1 ];}memcpy(Out, Tmp, len);}
算法思路
DES 的密钥长度是56位,实际长度是64位的,因为第8的倍数位为奇偶校验码,不参与DES运算.经过缩小选择换位表1的变换后,密钥的位数由64位变成了56位,此56位分为C0、D0两部分,各28位,然后分别进行第1次循环左移,得到C1、D1,将C1(28位)、D1(28位)合并得到56位,再经过缩小选择换位2,从而便得到了密钥K0(48位).依此类推,便可得到K1、K2、...K15,不过需要注意的是,16次循环左移对应的左移位数要依据下述规则进行:
循环左移位数: 1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1
实现代码
void DesSetKey(const char Key[8]){static bool K[64], *KL = &K[0], *KR = &K[28];// 字节组转换成位组byteToBit(K, Key, 64);// 变换transform(K, K, PC1_Table, 56);for(int i=0; i<16; i++){// 循环左移rotateL(KL, 28, LOOP_Table[i]);// 循环左移rotateL(KR, 28, LOOP_Table[i]);// 变换transform(SubKey[i], K, PC2_Table, 48);}}
算法思路
把48位的数分成8组,每组6位.在其输入b1,b2,b3,b4,b5,b6中,计算出x=b1*2+b6, y=b5+b4*2+b3*4+b2*8,再从Sbox表中查出x 行,y 列的值Sxy,将Sxy化为二进制,即得Si盒的输出.
实现代码
const static char S_Box[8][4][16] = {// S114,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,//S215,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,//S310,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,//S47,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,//S52,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,//S612,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,//S74,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,//S813,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};
void sFunc(bool Out[32], const bool In[48]){for(char i=0,j,k; i<8; i++,In+=6,Out+=4){j = (In[0]<<1) + In[5];k = (In[1]<<3) + (In[2]<<2) + (In[3]<<1) + In[4];byteToBit(Out, &S_Box[i][j][k], 4);}}
算法思路
按顺序进行16轮 Feistel 迭代即可.以上的算法都是基于64位以下内容加密的,由于 DES 是分组加密的,所以将明文逐8个字符分组进行加密处理即可.
实现代码
void DesRun(char Out[8], char In[8], bool Type){static bool M[64], Tmp[32], *Li = &M[0], *Ri = &M[32];// 字节组转换成位组byteToBit(M, In, 64);// 变换transform(M, M, IPTable, 64);if( Type == ENCRYPT ){for(int i=0; i<16; i++) {memcpy(Tmp, Ri, 32);fFunc(Ri, SubKey[i]);// 异或xor(Ri, Li, 32);memcpy(Li, Tmp, 32);}}else{for(int i=15; i>=0; i--) {memcpy(Tmp, Li, 32);fFunc(Li, SubKey[i]);// 异或xor(Li, Ri, 32);memcpy(Ri, Tmp, 32);}}// 变换transform(M, M, IPRTable, 64);bitToByte(Out, M, 64);}
void fFunc(bool In[32], const bool Ki[48]){static bool MR[48];// 变换transform(MR, In, eTable, 48);// 异或xor(MR, Ki, 48);// S 盒代替sFunc(In, MR);// 变换transform(In, In, P_Table, 32);}
void xor(bool *InA, const bool *InB, int len){for(int i = 0; i < len; i++){InA[i] ^= InB[i];}}
void rotateL(bool *In, int len, int loop){static bool Tmp[256];memcpy(Tmp, In, loop);memcpy(In, In+loop, len-loop);memcpy(In+len-loop, Tmp, loop);}
void byteToBit(bool *Out, const char *In, int bits){for(int i = 0; i < bits; i++){Out[i] = (In[i/8] >> (i%8)) & 1;}}
void bitToByte(char *Out, const bool *In, int bits){memset(Out, 0, (bits+7)/8);for(int i = 0; i < bits; i++){Out[i/8] |= In[i] << (i%8);}}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification{// Insert code here to initialize your applicationself.tf_plainText.stringValue = @"qwertyuiop";self.tf_key.stringValue = @"12345678";self.tf_encryption.stringValue = @"";self.tf_decryption.stringValue = @"";}- (IBAction)runDES:(id)sender {#if 0//明文合法性判断if ([self.tf_plainText.stringValue length] > 8) {self.tf_plainText.stringValue = @"The string is too long!";return;}#endifif ([self.tf_plainText.stringValue length] <= 0) {self.tf_plainText.stringValue = @"The string is too short!";}//密钥合法性判断if ([self.tf_key.stringValue length] != 8) {self.tf_key.stringValue = @"Wrong key length!";// self.tf_key.placeholder = @"Wrong Key Length!";return;}//数据初始化const char *const_key = [self.tf_key.stringValue UTF8String];const char *const_str = [self.tf_plainText.stringValue UTF8String];int keyLength = (int)[self.tf_key.stringValue length];int strLength = (int)[self.tf_plainText.stringValue length];char *key = (char *)malloc(sizeof(char)*(keyLength+1));memcpy(key, const_key, keyLength);key[[self.tf_key.stringValue length]] = '\0';char *str = (char *)malloc(sizeof(char)*(strLength+1));memcpy(str, const_str, strLength);str[strLength] = '\0';if (strLength <= 8) {//DES 加密puts("Before encrypting:");puts(str);DesSetKey(key);DesRun(str, str, ENCRYPT);puts("After encrypting:");puts(str);// self.tf_encryption.stringValue = [NSString stringWithUTF8String:str];self.tf_encryption.stringValue = @"Some chars can't print.";//DES 解密puts("After decrypting:");DesRun(str, str, DECRYPT);puts(str);self.tf_decryption.stringValue = [NSString stringWithUTF8String:str];} else {//puts("Before encrypting:");puts(str);// char resultEn[strLength];// char resultDe[strLength];char *resultEn = (char *)malloc(sizeof(char)*strLength);char *resultDe = (char *)malloc(sizeof(char)*strLength);for (int i = 0; i <= ((strLength-1)/8); i++) {int startIndex = i * 8;int offset = (i+1)*8 < (strLength-1) ? 8:(strLength-i*8);char *groupKey = (char *)malloc(sizeof(char)*offset);memcpy(groupKey, str+startIndex, offset);DesRun(groupKey, groupKey, ENCRYPT);strcat(resultEn, groupKey);DesRun(groupKey, groupKey, DECRYPT);strcat(resultDe, groupKey);}puts("After encrypting:");puts(resultEn);puts("After decrypting:");puts(resultDe);// self.tf_decryption.stringValue = [NSString stringwth]self.tf_encryption.stringValue = @"Some chars can't print.";self.tf_decryption.stringValue = [NSString stringWithUTF8String:str];free(resultEn);free(resultDe);}}
Before encrypting:
qwertyuiop
After encrypting:
JUp\246\302ĺϱ\376\214\212\357\326,
After decrypting:
qwertyuiop
