之前工作上需要用C++把軟件生成的用戶序列號用des加密cbc的模式,加密后為二進制,轉化為十六進制,然后提供給java寫的授權碼管理平台。 java平台會根據用戶序列號,生成一個授權碼,授權碼是用rsa 私加公解的模式加密的,加密后為二進制,然后轉為safeBase64格式。授權碼拿來在C++的軟件上授權,C++首先將safeBase64格式轉為base64格式,再轉為二進制,然后rsa解密出來得到明文。
現在回頭整理那段時間的工作。小吐槽一下,想想碰到的坑,腦瓜疼。看了我碰到的坑,你們也能理清楚不少疑惑。
先說DES加解密。java告訴用des,自己沒接觸過,網上找了一段代碼,調用openssl庫實現的des加解密,ecb模式的,折騰一番,實現了加密解密。跟java一碰,發現完全對不上。java查看代碼,發現庫函數有cbc的字樣,用的cbc模式。ok嘛,接着實現cbc模式。頭疼的是找遍了百度和谷歌,都沒有找到有實現cbc模式的C++代碼。怎么辦呢,我就對照着ecb的實現,和cbc模式加密的理論,自己做。幸運的是,做出來了。來實現cbc模式的加解密, 在調用openssl庫的接口時,需要傳入密匙和IV向量。網上的代碼有的IV向量是隨意的,有的是全零。然后我發現,IV向量的值並非隨心所欲就能實現加密解密。然后我用了網上的一個數組值,自己可以加密解密了。然后我把密匙設置為跟java一致,結果卻不美好,加密的結果跟java不相同,也不能把java的密文解密出來。然后呢,java調用的庫函數,只需要提供一個密匙KEY,因此java也不清楚問題出在哪。跟java反復的討論中,java同事廷謀哥說,把IV向量設置為密匙KEY試試,一試便成功了。需要注意的是java默認加密的填充方式為pkcs5padding,C++需要自己實現。
再說說RSA加解密。java告訴用rsa, 也是自己沒接觸過。網上找代碼,copy了一份,公鑰解密私鑰解密, 隨機生成密匙的代碼。整理下來,可以加解密了。問題是如果明文過長,加解密的結果是不對了,表面看能加密,解密為空,實際上加密的結果是不完整的。好嘛,辛辛苦苦實現了,盡管不完美,但是能簡單用,趕緊把隨機生成秘鑰的代碼注釋掉,換上java的秘鑰。~~~呵呵呵,又不行了。一步步刨坑,rsa生成的秘鑰有長度得區別,不同的長度能實現加密的明文是不同的。rsa加解密是分“公鑰加密私鑰解密”、“私鑰加密公鑰解密”的。並且,公加私解的密文是變動的,私加公解密文是固定的, rsa加解密是需要分片的。另外呢,java默認生成的密匙,公鑰和私鑰都是pkcs#8, 而C++調用openssl生成的密匙,公鑰和私鑰都是pkcs#1格式。腦瓜疼吧,再疼一下。java把生成的秘鑰和加密后的密文是轉為safaBase64格式的。這些在C++這邊都是需要自己實現的。需要注意的是java默認加密的填充方式為pkcs1padding,openssl在這一點跟java是一致的。最后一個小關注點是所有采用UTF8編碼。
==============================================================
進入正題
==============================================================
一、openssl庫
I)庫下載
百度下載OpenSSL-Win32軟件,安裝后,安裝目錄有 lib文件夾 include文件夾
II)庫使用__我的環境是VS2010
項目屬性中,按照 ../openssl/include/openssl;的路徑配置; cpp文件中,按照#include "openssl/rsa.h"的方式調用
二、DES加密 cbc模式
三、RSA加密
附1: RSA密匙格式在線轉換工具 DES/RSA加解密系列在線工具
附2:C++二進制字符串轉十六進制字符串 C++十六進制字符串轉二進制字符串
附3:C++二進制字符串轉Base64字符串 C++Base64字符串轉二進制字符串 C++base64格式和nonSafeBase64格式轉換
未完待續...