[关闭]
@veightz 2014-10-03T15:49:09.000000Z 字数 6046 阅读 1959

DES 编程与实现


DES 密码学

算法描述及实现

二进制矩阵变换

  1. void transform(bool *Out, bool *In, const char *Table, int len)
  2. {
  3. static bool Tmp[256];
  4. for(int i = 0; i < len; i++)
  5. {
  6. Tmp[i] = In[ Table[i] - 1 ];
  7. }
  8. memcpy(Out, Tmp, len);
  9. }

子密钥生成

  1. void DesSetKey(const char Key[8])
  2. {
  3. static bool K[64], *KL = &K[0], *KR = &K[28];
  4. // 字节组转换成位组
  5. byteToBit(K, Key, 64);
  6. // 变换
  7. transform(K, K, PC1_Table, 56);
  8. for(int i=0; i<16; i++)
  9. {
  10. // 循环左移
  11. rotateL(KL, 28, LOOP_Table[i]);
  12. // 循环左移
  13. rotateL(KR, 28, LOOP_Table[i]);
  14. // 变换
  15. transform(SubKey[i], K, PC2_Table, 48);
  16. }
  17. }

S盒实现

  1. const static char S_Box[8][4][16] = {
  2. // S1
  3. 14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7,
  4. 0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8,
  5. 4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0,
  6. 15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13,
  7. //S2
  8. 15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10,
  9. 3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5,
  10. 0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15,
  11. 13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9,
  12. //S3
  13. 10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8,
  14. 13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1,
  15. 13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7,
  16. 1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12,
  17. //S4
  18. 7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15,
  19. 13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9,
  20. 10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4,
  21. 3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14,
  22. //S5
  23. 2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9,
  24. 14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6,
  25. 4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14,
  26. 11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3,
  27. //S6
  28. 12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11,
  29. 10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8,
  30. 9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6,
  31. 4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13,
  32. //S7
  33. 4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1,
  34. 13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6,
  35. 1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2,
  36. 6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12,
  37. //S8
  38. 13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7,
  39. 1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2,
  40. 7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8,
  41. 2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11
  42. };
  1. void sFunc(bool Out[32], const bool In[48])
  2. {
  3. for(char i=0,j,k; i<8; i++,In+=6,Out+=4)
  4. {
  5. j = (In[0]<<1) + In[5];
  6. k = (In[1]<<3) + (In[2]<<2) + (In[3]<<1) + In[4];
  7. byteToBit(Out, &S_Box[i][j][k], 4);
  8. }
  9. }

加解密实现

  1. void DesRun(char Out[8], char In[8], bool Type)
  2. {
  3. static bool M[64], Tmp[32], *Li = &M[0], *Ri = &M[32];
  4. // 字节组转换成位组
  5. byteToBit(M, In, 64);
  6. // 变换
  7. transform(M, M, IPTable, 64);
  8. if( Type == ENCRYPT ){
  9. for(int i=0; i<16; i++) {
  10. memcpy(Tmp, Ri, 32);
  11. fFunc(Ri, SubKey[i]);
  12. // 异或
  13. xor(Ri, Li, 32);
  14. memcpy(Li, Tmp, 32);
  15. }
  16. }else{
  17. for(int i=15; i>=0; i--) {
  18. memcpy(Tmp, Li, 32);
  19. fFunc(Li, SubKey[i]);
  20. // 异或
  21. xor(Li, Ri, 32);
  22. memcpy(Ri, Tmp, 32);
  23. }
  24. }
  25. // 变换
  26. transform(M, M, IPRTable, 64);
  27. bitToByte(Out, M, 64);
  28. }

相关模块实现

  1. void fFunc(bool In[32], const bool Ki[48])
  2. {
  3. static bool MR[48];
  4. // 变换
  5. transform(MR, In, eTable, 48);
  6. // 异或
  7. xor(MR, Ki, 48);
  8. // S 盒代替
  9. sFunc(In, MR);
  10. // 变换
  11. transform(In, In, P_Table, 32);
  12. }
  1. void xor(bool *InA, const bool *InB, int len)
  2. {
  3. for(int i = 0; i < len; i++)
  4. {
  5. InA[i] ^= InB[i];
  6. }
  7. }
  1. void rotateL(bool *In, int len, int loop)
  2. {
  3. static bool Tmp[256];
  4. memcpy(Tmp, In, loop);
  5. memcpy(In, In+loop, len-loop);
  6. memcpy(In+len-loop, Tmp, loop);
  7. }
  1. void byteToBit(bool *Out, const char *In, int bits)
  2. {
  3. for(int i = 0; i < bits; i++)
  4. {
  5. Out[i] = (In[i/8] >> (i%8)) & 1;
  6. }
  7. }
  1. void bitToByte(char *Out, const bool *In, int bits)
  2. {
  3. memset(Out, 0, (bits+7)/8);
  4. for(int i = 0; i < bits; i++)
  5. {
  6. Out[i/8] |= In[i] << (i%8);
  7. }
  8. }
  1. - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
  2. {
  3. // Insert code here to initialize your application
  4. self.tf_plainText.stringValue = @"qwertyuiop";
  5. self.tf_key.stringValue = @"12345678";
  6. self.tf_encryption.stringValue = @"";
  7. self.tf_decryption.stringValue = @"";
  8. }
  9. - (IBAction)runDES:(id)sender {
  10. #if 0
  11. //明文合法性判断
  12. if ([self.tf_plainText.stringValue length] > 8) {
  13. self.tf_plainText.stringValue = @"The string is too long!";
  14. return;
  15. }
  16. #endif
  17. if ([self.tf_plainText.stringValue length] <= 0) {
  18. self.tf_plainText.stringValue = @"The string is too short!";
  19. }
  20. //密钥合法性判断
  21. if ([self.tf_key.stringValue length] != 8) {
  22. self.tf_key.stringValue = @"Wrong key length!";
  23. // self.tf_key.placeholder = @"Wrong Key Length!";
  24. return;
  25. }
  26. //数据初始化
  27. const char *const_key = [self.tf_key.stringValue UTF8String];
  28. const char *const_str = [self.tf_plainText.stringValue UTF8String];
  29. int keyLength = (int)[self.tf_key.stringValue length];
  30. int strLength = (int)[self.tf_plainText.stringValue length];
  31. char *key = (char *)malloc(sizeof(char)*(keyLength+1));
  32. memcpy(key, const_key, keyLength);
  33. key[[self.tf_key.stringValue length]] = '\0';
  34. char *str = (char *)malloc(sizeof(char)*(strLength+1));
  35. memcpy(str, const_str, strLength);
  36. str[strLength] = '\0';
  37. if (strLength <= 8) {
  38. //DES 加密
  39. puts("Before encrypting:");
  40. puts(str);
  41. DesSetKey(key);
  42. DesRun(str, str, ENCRYPT);
  43. puts("After encrypting:");
  44. puts(str);
  45. // self.tf_encryption.stringValue = [NSString stringWithUTF8String:str];
  46. self.tf_encryption.stringValue = @"Some chars can't print.";
  47. //DES 解密
  48. puts("After decrypting:");
  49. DesRun(str, str, DECRYPT);
  50. puts(str);
  51. self.tf_decryption.stringValue = [NSString stringWithUTF8String:str];
  52. } else {
  53. //
  54. puts("Before encrypting:");
  55. puts(str);
  56. // char resultEn[strLength];
  57. // char resultDe[strLength];
  58. char *resultEn = (char *)malloc(sizeof(char)*strLength);
  59. char *resultDe = (char *)malloc(sizeof(char)*strLength);
  60. for (int i = 0; i <= ((strLength-1)/8); i++) {
  61. int startIndex = i * 8;
  62. int offset = (i+1)*8 < (strLength-1) ? 8:(strLength-i*8);
  63. char *groupKey = (char *)malloc(sizeof(char)*offset);
  64. memcpy(groupKey, str+startIndex, offset);
  65. DesRun(groupKey, groupKey, ENCRYPT);
  66. strcat(resultEn, groupKey);
  67. DesRun(groupKey, groupKey, DECRYPT);
  68. strcat(resultDe, groupKey);
  69. }
  70. puts("After encrypting:");
  71. puts(resultEn);
  72. puts("After decrypting:");
  73. puts(resultDe);
  74. // self.tf_decryption.stringValue = [NSString stringwth]
  75. self.tf_encryption.stringValue = @"Some chars can't print.";
  76. self.tf_decryption.stringValue = [NSString stringWithUTF8String:str];
  77. free(resultEn);
  78. free(resultDe);
  79. }
  80. }

结果演示


由于输出字符的显示是用ASCII表中读取的,尽管一个字符是8位,取值范围是0~255,但是ASCII表中的内容只有0~127,而且这128个内容中也不全是字符内容,有一部分是特殊控制字符, 所以不能直接输入.

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注