DES 文件加密, RSA 給密碼加密

DES算法已經很經典了,因此用它來文件加密,也是簡單不過。
-------------------------------------------------------------------------------------------------------
C_DesEncryptFile::EncryptFile(LPCTSTR lpSourceFile, LPCTSTR lpszDestFile, const BYTE key[8], bool bFlag)
--------------------------------------------------------------------------------------------------------
lpSourceFile ---源文件名
lpszDestFile ---目標文件名
key[8]---密碼,不能超過64bit
bFlag--加密解密標誌
  1. // C_DesEncryptFile.h: interface for the C_DesEncryptFile class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #if !defined(AFX_C_DESENCRYPTFILE_H__3667F854_C709_40B4_AFD3_265D4B1B0618__INCLUDED_)
  5. #define AFX_C_DESENCRYPTFILE_H__3667F854_C709_40B4_AFD3_265D4B1B0618__INCLUDED_
  6. #if _MSC_VER > 1000
  7. #pragma once
  8. #endif // _MSC_VER > 1000
  9. #include <tchar.h>
  10. namespace  Encrypt {
  11. class C_DesEncryptFile  
  12. {
  13.     typedef unsigned char BYTE;
  14.     typedef  BYTE*         LPBYTE;
  15.     typedef  const BYTE*  LPCBYTE;
  16.     typedef  const TCHAR  *LPCSTR;
  17. public:
  18.     C_DesEncryptFile();
  19.     virtual ~C_DesEncryptFile();
  20. public:
  21.      bool EncryptFile(LPCBYTE lpSource, LPBYTE lpDest, unsigned int nSize, const BYTE key[8], bool bFlag);
  22.      bool EncryptFile(LPCTSTR lpSourceFile, LPCTSTR lpszDestFile, const BYTE key[8], bool bFlag);
  23. private:
  24.     HANDLE OpenFile(LPCTSTR lpSourceFile, bool bReadMode);    
  25.     LPBYTE GetFileBuffer(HANDLE &hFile, DWORD &dwFileSize);
  26. };
  27. };
  28. #endif // !defined(AFX_C_DESENCRYPTFILE_H__3667F854_C709_40B4_AFD3_265D4B1B0618__INCLUDED_)
下面是實現代碼:
  1. // C_DesEncryptFile.cpp: implementation of the C_DesEncryptFile class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "RSA.h"
  6. #include "C_DesEncryptFile.h"
  7. #include "C_Des.h"
  8. #include <io.h>
  9. #ifdef _DEBUG
  10. #undef THIS_FILE
  11. static char THIS_FILE[]=__FILE__;
  12. #define new DEBUG_NEW
  13. #endif
  14. //////////////////////////////////////////////////////////////////////
  15. // Construction/Destruction
  16. //////////////////////////////////////////////////////////////////////
  17. namespace  Encrypt {
  18. C_DesEncryptFile::C_DesEncryptFile()
  19. {
  20. }
  21. C_DesEncryptFile::~C_DesEncryptFile()
  22. {
  23. }
  24. bool C_DesEncryptFile::EncryptFile(LPCTSTR lpSourceFile, LPCTSTR lpszDestFile, const BYTE key[8], bool bFlag)
  25. {
  26.     HANDLE hSHandle;
  27.     HANDLE hDHandle;
  28.     hSHandle = OpenFile(lpSourceFile, true);
  29.     if (INVALID_HANDLE_VALUE == hSHandle)
  30.     {
  31.         return false;
  32.     }
  33.     DWORD dwFileSize = 0;
  34.     LPBYTE lpSource = GetFileBuffer(hSHandle, dwFileSize);
  35.     if (NULL == lpSource)
  36.     {
  37.         return false;
  38.     }
  39.     hDHandle = OpenFile(lpszDestFile, false);
  40.     if (INVALID_HANDLE_VALUE == hSHandle)
  41.     {
  42.         delete [] lpSource;
  43.         return false;
  44.     }
  45.     LPBYTE lpDest = new BYTE [dwFileSize];
  46.    bool bret = EncryptFile(lpSource, lpDest, dwFileSize, key, bFlag);
  47.    DWORD dwWriteNum = 0;
  48.    WriteFile(hDHandle, lpDest, dwFileSize, &dwWriteNum, NULL);
  49.    CloseHandle(hDHandle); 
  50.    delete [] lpSource;
  51.    delete [] lpDest;
  52.    return bret;
  53. }
  54. bool C_DesEncryptFile::EncryptFile(LPCBYTE lpSource, LPBYTE lpDest, unsigned int nSize, const BYTE key[8], bool bFlag)
  55. {
  56.     C_Des DesEncrpty;
  57.     BOOLEAN bRet = DesEncrpty.CDesEnter(lpSource, lpDest, nSize, key, bFlag);
  58.     if (bRet)
  59.     {
  60.         return true;
  61.     }
  62.     return false;
  63. }
  64. HANDLE C_DesEncryptFile::OpenFile(LPCTSTR lpSourceFile, bool bReadMode)
  65. {
  66.     
  67.     DWORD dwMode = GENERIC_READ ;
  68.     DWORD dwShared = FILE_SHARE_READ;
  69.     DWORD dwCreate = OPEN_EXISTING;
  70.     if (!bReadMode)
  71.     {
  72.         dwMode |= GENERIC_WRITE;
  73.         dwShared |= FILE_SHARE_WRITE;
  74.         dwCreate = CREATE_ALWAYS;
  75.     }
  76.     HANDLE hTemplateFile = NULL;
  77.     hTemplateFile = ::CreateFile(lpSourceFile, dwMode, dwShared, NULL, 
  78.         dwCreate, FILE_ATTRIBUTE_NORMAL, hTemplateFile);
  79.     return hTemplateFile;
  80. }
  81. LPBYTE C_DesEncryptFile::GetFileBuffer(HANDLE &hFile, DWORD &dwFileSize)
  82. {
  83.     DWORD dwFileHigh = 0;;
  84.     
  85.     DWORD dwRealSize = dwFileSize = GetFileSize(hFile, &dwFileHigh); 
  86.     if (dwFileSize % 8 != 0)
  87.     {
  88.         DWORD dwRatio = dwFileSize / 8;
  89.         dwFileSize = (dwRatio + 1) * 8;
  90.     }
  91.     LPBYTE pSourBuffer = new BYTE [dwFileSize];
  92.     DWORD dwReadNum = 0;
  93.     ReadFile(hFile, pSourBuffer, dwRealSize, &dwReadNum, NULL);
  94.     CloseHandle(hFile);
  95.     DWORD dwOffset = dwFileSize - dwRealSize;
  96.     ZeroMemory(pSourBuffer + dwRealSize, dwOffset);
  97.     return pSourBuffer;
  98. }
  99. };
DES 的代碼:
  1. // C_Des.h: interface for the C_Des class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #if !defined(AFX_C_DES_H__387D4F78_8819_43DC_BCC9_CB6C6BFB5A2D__INCLUDED_)
  5. #define AFX_C_DES_H__387D4F78_8819_43DC_BCC9_CB6C6BFB5A2D__INCLUDED_
  6. #if _MSC_VER > 1000
  7. #pragma once
  8. #endif // _MSC_VER > 1000
  9. namespace  Encrypt {
  10.     typedef  unsigned char   BYTE;
  11.     typedef  BYTE*         LPBYTE;
  12.     typedef  const BYTE*  LPCBYTE;
  13.     typedef  int             BOOLEAN;
  14.     
  15.     
  16.     class C_Des 
  17.     { 
  18.         
  19.     public:
  20.         C_Des();
  21.         ~C_Des();
  22.     public
  23.         BOOLEAN CDesEnter(LPCBYTE in, LPBYTE out, int datalen, const BYTE key[8], BOOL type); 
  24.         BOOLEAN CDesMac(LPCBYTE mac_data, LPBYTE mac_code, int datalen, const BYTE key[8]); 
  25.     private
  26.         void XOR(const BYTE in1[8], const BYTE in2[8], BYTE out[8]); 
  27.         LPBYTE Bin2ASCII(const BYTE byte[64], BYTE bit[8]); 
  28.         LPBYTE ASCII2Bin(const BYTE bit[8], BYTE byte[64]); 
  29.         void GenSubKey(const BYTE oldkey[8], BYTE newkey[16][8]); 
  30.         void endes(const BYTE m_bit[8], const BYTE k_bit[8], BYTE e_bit[8]); 
  31.         void undes(const BYTE m_bit[8], const BYTE k_bit[8], BYTE e_bit[8]); 
  32.         void SReplace(BYTE s_bit[8]); 
  33.     }; 
  34. };
  35. #endif // !defined(AFX_C_DES_H__387D4F78_8819_43DC_BCC9_CB6C6BFB5A2D__INCLUDED_)
DES 實現:(是網上找到的) 
  1. // C_Des.cpp: implementation of the C_Des class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "RSA.h"
  6. #include "C_Des.h"
  7. #ifdef _DEBUG
  8. #undef THIS_FILE
  9. static char THIS_FILE[]=__FILE__;
  10. #define new DEBUG_NEW
  11. #endif
  12. namespace Encrypt {
  13. //////////////////////////////////////////////////////////////////////
  14. // Construction/Destruction
  15. //////////////////////////////////////////////////////////////////////
  16. C_Des::C_Des()
  17. {
  18. }
  19. C_Des::~C_Des()
  20. {
  21. }
  22.  
  23. /* 
  24. *   CDesEnter 函數說明: 
  25. *     des加密/解密入口 
  26. *   返回: 
  27. *     1則成功,0失敗 
  28. *   參數: 
  29. *     in 需要加密或解密的數據  
  30. *         注意:in緩衝區的大小必須和datalen相同. 
  31. *     out 加密後或解密後輸出。 
  32. *         注意:out緩衝區大小必須是8的倍數而且比datalen大或者相等。 
  33. *         如datalen=7,out緩衝區的大小應該是8,datalen=8,out緩衝區的大小應該是8, 
  34. *         datalen=9,out緩衝區的大小應該是16,依此類推。 
  35. *     datalen 數據長度(字節)。  
  36. *         注意:datalen 必須是8的倍數。 
  37. *     key 8個字節的加密或解密的密碼。 
  38. *     type 是對數據進行加密還是解密 
  39. *         0 表示加密 1 表示解密 
  40. */ 
  41. BOOLEAN C_Des::CDesEnter(LPCBYTE in, LPBYTE out, int datalen, const BYTE key[8], BOOL type) 
  42.   //判斷輸入參數是否正確,失敗的情況爲: 
  43.   //!in: in指針(輸入緩衝)無效 
  44.   //!out: out指針(輸出緩衝)無效 
  45.   //datalen<1: 數據長度不正確 
  46.   //!key: 加/解密密碼無效 
  47.   //type && ((datalen % 8) !=0:選擇解密方式但是輸入密文不爲8的倍數 
  48.   if((!in) || (!out) || (datalen<1) || (!key) || (type && ((datalen % 8) !=0))) 
  49.     return FALSE; 
  50.  
  51.      
  52.   if(type==0) //選擇的模式是加密 
  53.   { 
  54.     // 用於存儲待加密字串最後的若干字節 
  55.     // DES算法是以8個字節爲單位進行加密,如果待加密字串以8爲單位分段加密時,最後一段不足 
  56.     //8字節,則在後面補0,使其最後一段的長度爲8字節 
  57.     // te8bit是作爲存儲待加密字串最後一段(不足8字節)的變量 
  58.     BYTE te8bit[8]={0,0,0,0,0,0,0,0}; 
  59.  
  60.     // 這是待加密字串的調整長度 
  61.     // 如果原始長度是8的整數倍,則調整長度的值和原來的長度一樣 
  62.     // 如果原始長度不是8的整數倍,則調整長度的值是能被8整除且不大於原來長度的最大整數。 
  63.     //也就是不需要補齊的塊的總長度。 
  64.     int te_fixlen = datalen - (datalen % 8); 
  65.  
  66.     // 將待加密密文以8爲單位分段,把最後長度不足8的一段存儲到te8bit中。 
  67.     for(int i = 0; i < (datalen % 8); i++) 
  68.         te8bit[i] = in[te_fixlen + i]; 
  69.  
  70.     // 將待加密字串分以8字節爲單位分段加密 
  71.     for(i = 0; i < te_fixlen; i += 8) 
  72.         endes(in + i, key, out + i); 
  73.  
  74.     // 如果待加密字串不是8的整數倍,則將最後一段補齊(補0)後加密 
  75.     if(datalen % 8 != 0) 
  76.         endes(te8bit, key, out + datalen / 8 * 8); 
  77.   } 
  78.   else   //選擇的模式是解密 
  79.   { 
  80.     // 將密文以8字節爲單位分段解密 
  81.     for(int i = 0; i < datalen; i += 8) 
  82.         undes(in + i, key, out + i); 
  83.   } 
  84.   return TRUE; 
  85.  
  86. /* 
  87. *   CDesMAC 函數說明: 
  88. *     DESMAC 數據驗校 
  89. *   返回: 
  90. *     1則成功,0失敗 
  91. *   參數: 
  92. *     mac_data MAC驗校數據 
  93. *         注意:Mac_data緩衝區的大小(16字節以上)必須和datalen相同,而且應是8的倍數。 
  94. *     out_mac MAC驗校輸出(8字節) 
  95. *     dadalen 數據長度(字節)。  
  96. *         注意:datalen 必須是16以上而且是8的倍數。 
  97. *     key 8個字節的驗校密碼。      
  98. */ 
  99. BOOLEAN C_Des::CDesMac(LPCBYTE mac_data, LPBYTE mac_code, int datalen, const BYTE key[8]) 
  100.   //判斷輸入參數是否正確,失敗的情況爲: 
  101.   //!mac_data: mac_data指針(輸入緩衝)無效 
  102.   //!mac_code: mac_code指針(輸出緩衝)無效 
  103.   //datalen<16: 數據長度不正確 
  104.   //datalen % 8 != 0: 數據長度不爲8的整數倍 
  105.   //!key:密碼不符合要求 
  106.   if((!mac_data) || (!mac_code) || (datalen < 16) || (datalen % 8 != 0) || (!key)) 
  107.     return FALSE; 
  108.   endes(mac_data, key, mac_code); 
  109.   for(int i = 8; i < datalen; i += 8) 
  110.   { 
  111.     XOR(mac_code, mac_data + i, mac_code); 
  112.     endes(mac_code, key, mac_code); 
  113.   } 
  114.   return TRUE; 
  115.  
  116. /* 
  117. *   XOR 函數說明: 
  118. *     將輸入的兩個8字節字符串異或 
  119. *   返回: 
  120. *     無 
  121. *   參數: 
  122. *     const BYTE in1[8] 輸入字符串1 
  123. *     const BYTE in2[8] 輸入字符串2 
  124. *     BYTE out[8] 輸出的結果字符串      
  125. */ 
  126. void C_Des::XOR(const BYTE in1[8], const BYTE in2[8], BYTE out[8]) 
  127.   for(int i = 0; i < 8; i++) 
  128.     out[i] = in1[i] ^ in2[i];  
  129.  
  130. /* 
  131. *   Bin2ASCII 函數說明: 
  132. *     將64字節的01字符串轉換成對應的8個字節 
  133. *   返回: 
  134. *     轉換後結果的指針 
  135. *   參數: 
  136. *     const BYTE byte[64] 輸入字符串 
  137. *     BYTE bit[8] 輸出的轉換結果      
  138. */ 
  139. LPBYTE C_Des::Bin2ASCII(const BYTE byte[64], BYTE bit[8]) 
  140.   for(int i = 0; i < 8; i++) 
  141.   { 
  142.     bit[i] = byte[i * 8] * 128 + byte[i * 8 + 1] * 64 +  
  143.           byte[i * 8 + 2] * 32 + byte[i * 8 + 3] * 16 +  
  144.           byte[i * 8 + 4] * 8 + byte[i * 8 + 5] * 4 +  
  145.           byte[i * 8 + 6] * 2 + byte[i * 8 + 7];  
  146.   } 
  147.   return bit; 
  148.  
  149. /* 
  150. *   ASCII2Bin 函數說明: 
  151. *     將8個字節輸入轉換成對應的64字節的01字符串 
  152. *   返回: 
  153. *     轉換後結果的指針 
  154. *   參數: 
  155. *     const BYTE bit[8] 輸入字符串 
  156. *     BYTE byte[64] 輸出的轉換結果      
  157. */ 
  158. LPBYTE C_Des::ASCII2Bin(const BYTE bit[8], BYTE byte[64]) 
  159.   for(int i=0; i < 8; i++) 
  160.     for(int j = 0; j < 8; j++) 
  161.         byte[i * 8 + j] = ( bit[i] >> (7 - j) ) & 0x01; 
  162.   return byte; 
  163.  
  164. /* 
  165. *   GenSubKey 函數說明: 
  166. *     由輸入的密鑰得到16個子密鑰 
  167. *   返回: 
  168. *     無 
  169. *   參數: 
  170. *     const BYTE oldkey[8] 輸入密鑰 
  171. *     BYTE newkey[16][8] 輸出的子密鑰      
  172. */ 
  173. void C_Des::GenSubKey(const BYTE oldkey[8], BYTE newkey[16][8]) 
  174.   int i, k, rol = 0; 
  175.  
  176.   //縮小換位表1 
  177.   int pc_1[56] = {57,49,41,33,25,17,9, 
  178.           1,58,50,42,34,26,18, 
  179.           10,2,59,51,43,35,27, 
  180.           19,11,3,60,52,44,36, 
  181.           63,55,47,39,31,23,15, 
  182.           7,62,54,46,38,30,22, 
  183.           14,6,61,53,45,37,29, 
  184.           21,13,5,28,20,12,4}; 
  185.   //縮小換位表2 
  186.   int pc_2[48] = {14,17,11,24,1,5, 
  187.           3,28,15,6,21,10, 
  188.           23,19,12,4,26,8, 
  189.           16,7,27,20,13,2, 
  190.           41,52,31,37,47,55, 
  191.           30,40,51,45,33,48, 
  192.           44,49,39,56,34,53, 
  193.           46,42,50,36,29,32}; 
  194.   //16次循環左移對應的左移位數 
  195.   int ccmovebit[16] = {1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1}; 
  196.  
  197.   BYTE oldkey_byte[64]; 
  198.   BYTE oldkey_byte1[64]; 
  199.   BYTE oldkey_byte2[64]; 
  200.   BYTE oldkey_c[56]; 
  201.   BYTE oldkey_d[56]; 
  202.   BYTE newkey_byte[16][64]; 
  203.  
  204.   ASCII2Bin(oldkey, oldkey_byte); 
  205.  
  206.   //位變換 
  207.   for(i = 0; i < 56; i++) 
  208.     oldkey_byte1[i] = oldkey_byte[pc_1[i] - 1]; 
  209.   //分爲左右兩部分,複製一遍以便於循環左移 
  210.   for(i = 0; i < 28; i++) 
  211.     oldkey_c[i] = oldkey_byte1[i], oldkey_c[i + 28] = oldkey_byte1[i], 
  212.     oldkey_d[i] = oldkey_byte1[i + 28], oldkey_d[i + 28] = oldkey_byte1[i + 28]; 
  213.  
  214.   //分別生成16個子密鑰 
  215.   for(i = 0; i < 16; i++) 
  216.   { 
  217.     //循環左移 
  218.     rol += ccmovebit[i]; 
  219.     //合併左移後的結果 
  220.     for(k = 0; k < 28; k++)  
  221.         oldkey_byte2[k] = oldkey_c[k + rol], oldkey_byte2[k + 28] = oldkey_d[k + rol]; 
  222.     //位變換 
  223.     for(k = 0; k < 48; k++) 
  224.         newkey_byte[i][k] = oldkey_byte2[pc_2[k] - 1]; 
  225.  
  226.   } 
  227.   //生成最終結果 
  228.   for(i = 0; i < 16; i++) 
  229.     Bin2ASCII(newkey_byte[i], newkey[i]); 
  230.  
  231. /* 
  232. *   endes 函數說明: 
  233. *     DES加密 
  234. *   返回: 
  235. *     無 
  236. *   參數: 
  237. *     const BYTE m_bit[8] 輸入的原文 
  238. *     const BYTE k_bit[8] 輸入的密鑰 
  239. *     BYTE e_bit[8] 輸出的密文 
  240. */ 
  241. void C_Des::endes(const BYTE m_bit[8], const BYTE k_bit[8], BYTE e_bit[8]) 
  242.   //換位表IP 
  243.   int ip[64] = { 
  244.         58,50,42,34,26,18,10,2, 
  245.         60,52,44,36,28,20,12,4, 
  246.         62,54,46,38,30,22,14,6, 
  247.         64,56,48,40,32,24,16,8, 
  248.         57,49,41,33,25,17,9,1, 
  249.         59,51,43,35,27,19,11,3, 
  250.         61,53,45,37,29,21,13,5, 
  251.         63,55,47,39,31,23,15,7 
  252.         }; 
  253.   //換位表IP_1 
  254.   int ip_1[64] = { 
  255.         40,8,48,16,56,24,64,32, 
  256.         39,7,47,15,55,23,63,31, 
  257.         38,6,46,14,54,22,62,30, 
  258.         37,5,45,13,53,21,61,29, 
  259.         36,4,44,12,52,20,60,28, 
  260.         35,3,43,11,51,19,59,27, 
  261.         34,2,42,10,50,18,58,26, 
  262.         33,1,41,9,49,17,57,25 
  263.         }; 
  264.   //放大換位表 
  265.   int e[48] = { 
  266.         32,1, 2, 3, 4, 5, 
  267.         4, 5, 6, 7, 8, 9, 
  268.         8, 9, 10,11,12,13, 
  269.         12,13,14,15,16,17, 
  270.         16,17,18,19,20,21, 
  271.         20,21,22,23,24,25, 
  272.         24,25,26,27,28,29, 
  273.         28,29,30,31,32,1 
  274.         }; 
  275.   BYTE m_bit1[8] = {0}; 
  276.   BYTE m_byte[64] = {0}; 
  277.   BYTE m_byte1[64] = {0}; 
  278.   BYTE key_n[16][8] = {0}; 
  279.   BYTE l_bit[17][8] = {0}; 
  280.   BYTE r_bit[17][8] = {0}; 
  281.   BYTE e_byte[64] = {0}; 
  282.   BYTE e_byte1[64] = {0}; 
  283.   BYTE r_byte[64] = {0}; 
  284.   BYTE r_byte1[64] = {0}; 
  285.   int i, j; 
  286.  
  287.   //根據密鑰生成16個子密鑰 
  288.   GenSubKey(k_bit, key_n); 
  289.   //將待加密字串變換成01串 
  290.   ASCII2Bin(m_bit, m_byte); 
  291.   //按照ip表對待加密字串進行位變換 
  292.   for(i = 0; i < 64; i++) 
  293.     m_byte1[i] = m_byte[ip[i] - 1]; 
  294.   //位變換後的待加密字串 
  295.   Bin2ASCII(m_byte1, m_bit1); 
  296.   //將位變換後的待加密字串分成兩組,分別爲前4字節L和後4字節R,作爲迭代的基礎(第0次迭代) 
  297.   for(i = 0; i < 4; i++) 
  298.     l_bit[0][i] = m_bit1[i], r_bit[0][i] = m_bit1[i + 4]; 
  299.  
  300.   //16次迭代運算 
  301.   for(i = 1; i <= 16; i++) 
  302.   { 
  303.     //R的上一次的迭代結果作爲L的當前次迭代結果 
  304.     for(j = 0; j < 4; j++) 
  305.         l_bit[i][j] = r_bit[i-1][j]; 
  306.  
  307.     ASCII2Bin(r_bit[i-1], r_byte); 
  308.     //將R的上一次迭代結果按E表進行位擴展得到48位中間結果 
  309.     for(j = 0; j < 48; j++) 
  310.         r_byte1[j] = r_byte[e[j] - 1]; 
  311.     Bin2ASCII(r_byte1, r_bit[i-1]); 
  312.  
  313.     //與第I-1個子密鑰進行異或運算 
  314.     for(j = 0; j < 6; j++) 
  315.         r_bit[i-1][j] = r_bit[i-1][j] ^ key_n[i-1][j]; 
  316.  
  317.     //進行S選擇,得到32位中間結果 
  318.     SReplace(r_bit[i - 1]); 
  319.      
  320.     //結果與L的上次迭代結果異或得到R的此次迭代結果 
  321.     for(j = 0; j < 4; j++) 
  322.     { 
  323.         r_bit[i][j] = l_bit[i-1][j] ^ r_bit[i-1][j]; 
  324.     } 
  325.   } 
  326.   //組合最終迭代結果 
  327.   for(i = 0; i < 4; i++) 
  328.     e_bit[i] = r_bit[16][i], e_bit[i + 4] = l_bit[16][i]; 
  329.    
  330.   ASCII2Bin(e_bit, e_byte); 
  331.   //按照表IP-1進行位變換 
  332.   for(i = 0; i < 64; i++) 
  333.     e_byte1[i] = e_byte[ip_1[i] - 1]; 
  334.   //得到最後的加密結果 
  335.   Bin2ASCII(e_byte1, e_bit); 
  336.  
  337. /* 
  338. *   undes 函數說明: 
  339. *     DES解密,與加密步驟完全相同,只是迭代順序是從16到1 
  340. *   返回: 
  341. *     無 
  342. *   參數: 
  343. *     const BYTE m_bit[8] 輸入的密文 
  344. *     const BYTE k_bit[8] 輸入的密鑰 
  345. *     BYTE e_bit[8] 輸出解密後的原文 
  346. */ 
  347. void C_Des::undes(const BYTE m_bit[8], const BYTE k_bit[8], BYTE e_bit[8]) 
  348.   //換位表IP 
  349.   int ip[64] = { 
  350.         58,50,42,34,26,18,10,2, 
  351.         60,52,44,36,28,20,12,4, 
  352.         62,54,46,38,30,22,14,6, 
  353.         64,56,48,40,32,24,16,8, 
  354.         57,49,41,33,25,17,9,1, 
  355.         59,51,43,35,27,19,11,3, 
  356.         61,53,45,37,29,21,13,5, 
  357.         63,55,47,39,31,23,15,7 
  358.         }; 
  359.   //換位表IP_1 
  360.   int ip_1[64] = { 
  361.         40,8,48,16,56,24,64,32, 
  362.         39,7,47,15,55,23,63,31, 
  363.         38,6,46,14,54,22,62,30, 
  364.         37,5,45,13,53,21,61,29, 
  365.         36,4,44,12,52,20,60,28, 
  366.         35,3,43,11,51,19,59,27, 
  367.         34,2,42,10,50,18,58,26, 
  368.         33,1,41,9,49,17,57,25 
  369.         }; 
  370.   //放大換位表 
  371.   int e[48] = { 
  372.         32,1, 2, 3, 4, 5, 
  373.         4, 5, 6, 7, 8, 9, 
  374.         8, 9, 10,11,12,13, 
  375.         12,13,14,15,16,17, 
  376.         16,17,18,19,20,21, 
  377.         20,21,22,23,24,25, 
  378.         24,25,26,27,28,29, 
  379.         28,29,30,31,32,1 
  380.         }; 
  381.   BYTE m_bit1[8] = {0}; 
  382.   BYTE m_byte[64] = {0}; 
  383.   BYTE m_byte1[64] = {0}; 
  384.   BYTE key_n[16][8] = {0}; 
  385.   BYTE l_bit[17][8] = {0}; 
  386.   BYTE r_bit[17][8] = {0}; 
  387.   BYTE e_byte[64] = {0}; 
  388.   BYTE e_byte1[64] = {0}; 
  389.   BYTE l_byte[64] = {0}; 
  390.   BYTE l_byte1[64] = {0}; 
  391.   int i = 0, j = 0; 
  392.  
  393.   //根據密鑰生成16個子密鑰 
  394.   GenSubKey(k_bit, key_n); 
  395.   //將待加密字串變換成01串 
  396.   ASCII2Bin(m_bit, m_byte); 
  397.   //按照ip表對待加密字串進行位變換 
  398.   for(i = 0; i < 64; i++) 
  399.     m_byte1[i] = m_byte[ip[i] - 1]; 
  400.   //位變換後的待加密字串 
  401.   Bin2ASCII(m_byte1, m_bit1); 
  402.   //將位變換後的待加密字串分成兩組,分別爲前4字節R和後4字節L,作爲迭代的基礎(第16次迭代) 
  403.   for(i = 0; i < 4; i++) 
  404.     r_bit[16][i] = m_bit1[i], l_bit[16][i] = m_bit1[i + 4]; 
  405.  
  406.   //16次迭代運算 
  407.   for(i = 16; i > 0; i--) 
  408.   { 
  409.     //L的上一次的迭代結果作爲R的當前次迭代結果 
  410.     for(j = 0; j < 4; j++) 
  411.         r_bit[i-1][j] = l_bit[i][j]; 
  412.  
  413.     ASCII2Bin(l_bit[i], l_byte); 
  414.     //將L的上一次迭代結果按E表進行位擴展得到48位中間結果 
  415.     for(j = 0; j < 48; j++) 
  416.         l_byte1[j] = l_byte[e[j] - 1]; 
  417.     Bin2ASCII(l_byte1, l_bit[i]); 
  418.  
  419.     //與第I-1個子密鑰進行異或運算 
  420.     for(j = 0; j < 6; j++) 
  421.         l_bit[i][j] = l_bit[i][j] ^ key_n[i-1][j]; 
  422.  
  423.     //進行S選擇,得到32位中間結果 
  424.     SReplace(l_bit[i]); 
  425.      
  426.     //結果與R的上次迭代結果異或得到L的此次迭代結果 
  427.     for(j = 0; j < 4; j++) 
  428.     { 
  429.         l_bit[i-1][j] = r_bit[i][j] ^ l_bit[i][j]; 
  430.     } 
  431.   } 
  432.   //組合最終迭代結果 
  433.   for(i = 0; i < 4; i++) 
  434.     e_bit[i] = l_bit[0][i], e_bit[i + 4] = r_bit[0][i]; 
  435.    
  436.   ASCII2Bin(e_bit, e_byte); 
  437.   //按照表IP-1進行位變換 
  438.   for(i = 0; i < 64; i++) 
  439.     e_byte1[i] = e_byte[ip_1[i] - 1]; 
  440.   //得到最後的結果 
  441.   Bin2ASCII(e_byte1, e_bit); 
  442.  
  443. /* 
  444. *   SReplace 函數說明: 
  445. *     S選擇 
  446. *   返回: 
  447. *     無 
  448. *   參數: 
  449. *     BYTE s_bit[8] 輸入暨選擇後的輸出 
  450. */ 
  451. void C_Des::SReplace(BYTE s_bit[8]) 
  452.   int p[32] = { 
  453.         16,7,20,21, 
  454.         29,12,28,17, 
  455.         1,15,23,26, 
  456.         5,18,31,10, 
  457.         2,8,24,14, 
  458.         32,27,3,9, 
  459.         19,13,30,6, 
  460.         22,11,4,25 
  461.         }; 
  462.   BYTE s[][4][16] ={  
  463.                 { 
  464.                 14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7, 
  465.                 0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8, 
  466.                 4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0, 
  467.                 15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13 
  468.                 }, 
  469.                 { 
  470.                 15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10, 
  471.                 3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5, 
  472.                 0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15, 
  473.                 13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9 
  474.                 }, 
  475.                 { 
  476.                 10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8, 
  477.                 13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1, 
  478.                 13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7, 
  479.                 1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12 
  480.                 }, 
  481.                 { 
  482.                 7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15, 
  483.                 13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9, 
  484.                 10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4, 
  485.                 3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14 
  486.                 }, 
  487.                 { 
  488.                 2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9, 
  489.                 14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6, 
  490.                 4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14, 
  491.                 11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3, 
  492.                 }, 
  493.                 { 
  494.                 12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11, 
  495.                 10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8, 
  496.                 9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6, 
  497.                 4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13 
  498.                 }, 
  499.                 { 
  500.                 4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1, 
  501.                 13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6, 
  502.                 1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2, 
  503.                 6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12 
  504.                 }, 
  505.                 { 
  506.                 13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7, 
  507.                 1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2, 
  508.                 7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8, 
  509.                 2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11 
  510.                 } 
  511.             }; 
  512.   BYTE s_byte[64] = {0}; 
  513.   BYTE s_byte1[64] = {0}; 
  514.   BYTE row = 0, col = 0; 
  515.   BYTE s_out_bit[8] = {0}; 
  516.  
  517.   //轉成二進制字符串處理 
  518.   ASCII2Bin(s_bit, s_byte); 
  519.   for(int i = 0; i < 8; i++) 
  520.   { 
  521.     //0、5位爲row,1、2、3、4位爲col,在S表中選擇一個八位的數 
  522.     row = s_byte[i * 6] * 2 + s_byte[i * 6 + 5]; 
  523.     col = s_byte[i * 6 + 1] * 8 + s_byte[i * 6 + 2] * 4 + s_byte[i * 6 + 3] * 2 + s_byte[i * 6 + 4]; 
  524.     s_out_bit[i] = s[i][row][col]; 
  525.   } 
  526.   //將八個選擇的八位數據壓縮表示 
  527.   s_out_bit[0] = (s_out_bit[0] << 4) + s_out_bit[1]; 
  528.   s_out_bit[1] = (s_out_bit[2] << 4) + s_out_bit[3]; 
  529.   s_out_bit[2] = (s_out_bit[4] << 4) + s_out_bit[5]; 
  530.   s_out_bit[3] = (s_out_bit[6] << 4) + s_out_bit[7]; 
  531.   //轉成二進制字符串處理 
  532.   ASCII2Bin(s_out_bit, s_byte); 
  533.   //換位 
  534.   for(i = 0; i < 32; i++) 
  535.     s_byte1[i] = s_byte[p[i] - 1]; 
  536.   //生成最後結果 
  537.   Bin2ASCII(s_byte1, s_bit); 
  538.  
  539. };
RAS 算法:
  1. // C_RSA.h: interface for the C_RSA class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #if !defined(AFX_C_RSA_H__DFA1ACD6_44FD_49A6_BCE5_9EB1A6A6CC1D__INCLUDED_)
  5. #define AFX_C_RSA_H__DFA1ACD6_44FD_49A6_BCE5_9EB1A6A6CC1D__INCLUDED_
  6. #if _MSC_VER > 1000
  7. #pragma once
  8. #endif // _MSC_VER > 1000
  9. #include <string>
  10. using namespace std;
  11. class C_RSA  
  12. {
  13. public:
  14.     struct S_CODE
  15.     {
  16.         int nEncryptCode;
  17.         int nDecryptCode;
  18.         int nN;
  19.     };
  20.     typedef S_CODE ENCRYPTTYPE;
  21. public:
  22.     C_RSA();
  23.     virtual ~C_RSA();
  24. public:
  25.     /// First produce the encrypt code & decrypt code
  26.     ENCRYPTTYPE & ProduceEncryptInFo(int nP, int nQ);
  27.     /// Encrypt the proclaim 
  28.     bool Encrypt(string &strContent, string & strEncryptContent);
  29.     /// Decrypt the content
  30.     bool Decrypt(string & strEncryptContent, string &strContent,  int nDecryptCode, int nN);
  31.     /// Auto produce encrypt code & decrypt code
  32.     ENCRYPTTYPE & AutoProduceEncryptInFo(void);
  33. private:
  34.     bool IsPrime(int nX);
  35.     int  Gcd(int nA, int nB);
  36.     void Euler(int nE, int nFin);
  37.     void ProduceEncryCode(int nFin);
  38.     int  Power(int nA, int nN, int nM);
  39.     
  40. private:
  41.     int m_nP;   //P factor
  42.     int m_nQ;   //Q factor
  43.     ENCRYPTTYPE m_nEncrytInFo; // information
  44.     
  45. };
  46. #endif // !defined(AFX_C_RSA_H__DFA1ACD6_44FD_49A6_BCE5_9EB1A6A6CC1D__INCLUDED_)
實現:
  1. // C_RSA.cpp: implementation of the C_RSA class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "RSA.h"
  6. #include "C_RSA.h"
  7. #include "math.h"
  8. #ifdef _DEBUG
  9. #undef THIS_FILE
  10. static char THIS_FILE[]=__FILE__;
  11. #define new DEBUG_NEW
  12. #endif
  13. //////////////////////////////////////////////////////////////////////
  14. // Construction/Destruction
  15. //////////////////////////////////////////////////////////////////////
  16. C_RSA::C_RSA()
  17. {
  18. }
  19. C_RSA::~C_RSA()
  20. {
  21. }
  22. inline
  23. bool C_RSA::IsPrime(int nX)
  24. {
  25.     int i;
  26.     int nTop = static_cast<int>(sqrt(nX));
  27.     nTop += 1;  // safe
  28.     
  29.     for (i = 2; i <= nTop; i++)
  30.     {
  31.         if (nX % i == 0)
  32.         {
  33.             break;
  34.         }
  35.     }
  36.     if (i > nTop)
  37.     {
  38.         return true;
  39.     }
  40.     return false;
  41. }
  42. inline
  43. int  C_RSA::Power(int nA, int nN, int nM)
  44. {
  45.     int nZ = 1, nTemp;
  46.     for (nTemp = nA; nN > 0; nN >>= 1)
  47.     {
  48.         if (nN % 2 == 1)
  49.         {
  50.             nZ = (nZ * nTemp) % nM;
  51.         }
  52.         nTemp = (nTemp * nTemp) % nM;
  53.     }
  54.     return nZ;
  55. }
  56. int C_RSA::Gcd(int nA, int nB)
  57. {
  58.     
  59.     if (nA == 0)
  60.     {
  61.         return nB;
  62.     }
  63.     else
  64.     {
  65.         return Gcd(nB % nA, nA);
  66.     }   
  67.     
  68. }
  69. inline
  70. void C_RSA::ProduceEncryCode(int nFin)
  71. {
  72.     for (int i = 3; i < nFin; ++i)
  73.     {
  74.         if (IsPrime(i) && 1 == Gcd(nFin, i))
  75.         {
  76.             m_nEncrytInFo.nEncryptCode = i;
  77.             break;
  78.         }
  79.     }
  80. }
  81. C_RSA::ENCRYPTTYPE & C_RSA::AutoProduceEncryptInFo(void)
  82. {
  83.     int nP, nQ;
  84.     while(true)
  85.     {
  86.         srand(time(0));
  87.         nP = rand() % 100;
  88.         nQ = rand() % 100;
  89.         if (IsPrime(nQ) && IsPrime(nP))
  90.             break;
  91.     }
  92.     return ProduceEncryptInFo(nP, nQ);
  93. }
  94. C_RSA::ENCRYPTTYPE& C_RSA::ProduceEncryptInFo(int nP, int nQ)
  95. {
  96.     m_nP = nP;
  97.     m_nQ = nQ;
  98.     m_nEncrytInFo.nN = m_nP * m_nQ;
  99.     int nFin = (m_nP - 1) * (m_nQ - 1);
  100.     
  101.     ProduceEncryCode(nFin);
  102.     Euler(m_nEncrytInFo.nEncryptCode, nFin);
  103.     return m_nEncrytInFo;
  104. }
  105. inline
  106. void C_RSA::Euler(int nE, int nFin)
  107. {
  108.     int u1 = 1;
  109.     int u2 = 0;
  110.     int u3 = nFin;
  111.     int v1 = 0;
  112.     int v2 = 1;
  113.     int v3 = nE;
  114.     int v = 1;
  115.     int t1, t2, t3;
  116.     int q;
  117.     int uu, vv;
  118.     int inverse, z;
  119.     while (v3 != 0)
  120.     {
  121.         q = u3 / v3;
  122.         t1 = u1 - q * v1;
  123.         t2 = u2 - q * v2;
  124.         t3 = u3 - q * v3;
  125.         u1 = v1;
  126.         u2 = v2;
  127.         u3 = v3;
  128.         v1 = t1;
  129.         v2 = t2;
  130.         v3 = t3;
  131.         z =  1;
  132.     }
  133.     uu = u1;
  134.     vv = u2;
  135.     
  136.     if (vv < 0)
  137.     {
  138.         inverse = vv + nFin;
  139.     }
  140.     else
  141.     {
  142.         inverse = vv;
  143.     }
  144.     m_nEncrytInFo.nDecryptCode = inverse;   
  145. }
  146. bool C_RSA::Encrypt(string &strContent, string & strEncryptContent)
  147. {
  148.     if (strContent.empty())
  149.     {
  150.         return false;
  151.     }
  152.     strEncryptContent = "";
  153.     string::size_type nIndex = 0;
  154.     string::size_type nSize = strContent.size();
  155.     for (nIndex = 0;  nIndex < nSize; ++nIndex)
  156.     {
  157.         char szBuffer[1024] = {0};
  158.         int nECode = Power(strContent[nIndex], 
  159.             m_nEncrytInFo.nEncryptCode,
  160.             m_nEncrytInFo.nN);
  161.         sprintf(szBuffer, "%d%s", nECode, "+");
  162.         strEncryptContent += szBuffer;
  163.         
  164.     }
  165.     return true;
  166. }
  167. bool C_RSA::Decrypt(string & strEncryptContent, string &strContent, int nDecryptCode, int nN)
  168. {
  169.     if (strEncryptContent.empty())
  170.     {
  171.         return false;
  172.     }
  173.     strContent = "";
  174.     unsigned size = strEncryptContent.size();
  175.     char *pstrEnCode  =  new char [size];
  176.     CopyMemory(pstrEnCode, strEncryptContent.c_str(), size);
  177.     char seps[]   = "+";
  178.     char *token;
  179.     token = strtok( pstrEnCode, seps );
  180.     while( token != NULL )
  181.     {
  182.         int nCode = atoi(token);
  183.         char nChar = static_cast<char>(Power(nCode, nDecryptCode, nN));
  184.         strContent += nChar;    
  185.         token = strtok( NULL, seps );
  186.     }
  187.     delete[] pstrEnCode;
  188.     return true;
  189. }
    
結束了,以文記之!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章