java與C++經過des、blowfish互相加解密

在簡單的服務器端與客戶端通訊的應用中,這種作法比較常見java

DES、blowfish掃盲:c++

1.des的常見模式分爲四種 ECB / CBC / CFB / OFB     這裏使用默認的ECB算法

ECB的缺陷:能從密文看出明文的規律服務器

加密算法是按塊進行加密的, DES ,是 64Bit 一個塊的進行加密,就是每次加密 8 個字節,所以每次輸入八個字節的明文輸出八個字節密文,若是是 16 個字節,那麼分紅兩個塊依次進行加密,問題就出如今這裏,若是明文是 1234567812345678,分塊分別進行加密,那麼加密的結果相似「C4132737962C519C C4132737962C519C」,能夠看出明文的規律,這就是 ECB 加密模式,密文能夠看出明文的規律 網絡

CBC/CFB/OFB:ide

爲了解決這個問題,有了其餘的加密模式:CBC 加密模式(密碼分組鏈接),CFB加密模式(密碼反饋模式),OFB加密模式(輸出反饋模式)CBC 是要求給一個初始化的向量,而後將每一個輸出與該向量做運算,並將運算的結果做爲下一個加密塊的初始化向量,CFB 和 OFB 則不須要提供初始化向量,直接將密碼或者輸出做爲初始化向量進行運算;這樣就避免了明文的規律出如今密文中;固然缺點是解密時須要保證密文的正確性,若是網絡傳輸時發生了一部分錯誤,則後面的解密結果就多是錯誤的;(ECB模式僅影響傳輸錯誤的那個塊); 加密

2.上面提到des是以64bit做爲單位塊單位來進行加密的,若是加密的內容長度恰好不是64bit塊的倍數,則須要作填充(padding)spa

經常使用的填充算法是 PKCS#7,該填充方法是將每個補充的字節內容填充爲填充的字節個數;例如明文長度是 100 , 分組的大小是32個字節,那麼須要分爲四組,補充28個字節,那麼補充的字節所有補充爲'\0x28',若是分組的大小是 8 個字節,那麼 PKCS#7 的填充方式和 PKCS#5 是徹底一致的;另外還有一個規定,就是若是明文剛恰好進行分組,那麼須要補充一個獨立的分組出來,例如 DES ,若是明文爲 8 個字節,那麼須要補充爲 16 個字節進行運算,這樣的好處是進行解密後,將解密出來的最後一個字節取出來,並將解密結果的長度減去該值,就是原來明文的長度; code

固然你也能夠選擇NoPadding模式,本身對加密內容的字節數作處理,確保它的長度是64bit的倍數ip

(以上規則blowfish也一樣使用)

代碼:

java

import java.security.Key; import java.security.Security; import javax.crypto.Cipher; public class DESPlus { static String strDefaultKey = "initkey"; static Cipher encryptCipher = null; static Cipher decryptCipher = null; static { Security.addProvider(new com.sun.crypto.provider.SunJCE()); Key key = null; try { key = getKey(strDefaultKey.getBytes()); encryptCipher = Cipher.getInstance("DES"); encryptCipher.init(Cipher.ENCRYPT_MODE, key); decryptCipher = Cipher.getInstance("DES"); decryptCipher.init(Cipher.DECRYPT_MODE, key); }catch(Exception e){ e.printStackTrace(); } } public DESPlus(){ } public static byte[] encrypt(byte[] arrB) throws Exception { return encryptCipher.doFinal(arrB); } public static byte[] decrypt(byte[] arrB) throws Exception { return decryptCipher.doFinal(arrB); } private static Key getKey(byte[] arrBTmp) throws Exception { byte[] arrB = new byte[8]; for (int i = 0; i < arrBTmp.length && i < arrB.length; i++) { arrB[i] = arrBTmp[i]; } Key key = new javax.crypto.spec.SecretKeySpec(arrB, "DES"); return key; } }

c++

int Encrypt( unsigned char * inbuf , unsigned char * * outbuf , int inlen , unsigned char * key, unsigned char * iv ) { BIO *bio, *mbio, *cbio; unsigned char *dst; int outlen; mbio = BIO_new( BIO_s_mem( ) ); cbio = BIO_new( BIO_f_cipher( ) ); BIO_set_cipher( cbio , EVP_des_ecb( ) , key , iv , 1 ); bio = BIO_push( cbio , mbio ); BIO_write( bio , inbuf , inlen ); BIO_flush( bio ); outlen = BIO_get_mem_data( mbio , (unsigned char **) & dst ); * outbuf = ( unsigned char * ) malloc( outlen ); memcpy( * outbuf , dst , outlen ); BIO_free_all( bio ); return outlen; }

附上C++的openssl庫

http://115.com/file/clfbpkt2

相關文章
相關標籤/搜索