• Java與C++通過DES、blowfish互相加解密

    1
    Java C/C++ Go 16560 次瀏覽

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

    DES、blowfish掃盲:

    1.des的常見模式分為四種 ECB / CBC / CFB / OFB     這里使用默認的ECB

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

    加 密算法是按塊進行加密的, DES ,是 64Bit 一個塊的進行加密,就是每次加密 8 個字節,因此每次輸入八個字節的明文輸出八個字節密文,如果是 16 個字節,那么分成兩個塊依次進行加密,問題就出現在這里,如果明文是 1234567812345678,分塊分別進行加密,那么加密的結果類似“C4132737962C519C C4132737962C519C”,可以看出明文的規律,這就是 ECB 加密模式,密文可以看出明文的規律

    CBC/CFB/OFB:

    為 了解決這個問題,有了其他的加密模式:CBC 加密模式(密碼分組連接),CFB加密模式(密碼反饋模式),OFB加密模式(輸出反饋模式)CBC 是要求給一個初始化的向量,然后將每個輸出與該向量作運算,并將運算的結果作為下一個加密塊的初始化向量,CFB 和 OFB 則不需要提供初始化向量,直接將密碼或者輸出作為初始化向量進行運算;這樣就避免了明文的規律出現在密文中;當然缺點是解密時需要保證密文的正確性,如果 網絡傳輸時發生了一部分錯誤,則后面的解密結果就可能是錯誤的;(ECB模式僅影響傳輸錯誤的那個塊);

    2.上面提到des是以64bit作為單位塊單位來進行加密的,如果加密的內容長度剛好不是64bit塊的倍數,則需要做填充(padding)

    常 用的填充算法是 PKCS#7,該填充方法是將每一個補充的字節內容填充為填充的字節個數;例如明文長度是 100 , 分組的大小是32個字節,那么需要分為四組,補充28個字節,那么補充的字節全部補充為'\0x28',如果分組的大小是 8 個字節,那么 PKCS#7 的填充方式和 PKCS#5 是完全一致的;另外還有一個規定,就是如果明文剛剛好進行分組,那么需要補充一個獨立的分組出來,例如 DES ,如果明文為 8 個字節,那么需要補充為 16 個字節進行運算,這樣的好處是進行解密后,將解密出來的最后一個字節取出來,并將解密結果的長度減去該值,就是原來明文的長度;

    當然你也可以選擇NoPadding模式,自己對加密內容的字節數做處理,確保它的長度是64bit的倍數

    (以上規則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

    相似問題

    相關經驗

    相關資訊

    相關文檔

  • sesese色