2015-12-28 59 views
-1

我已經使用DES加密來加密/解密數據。這段代碼工作正常。但是現在這個代碼在帶有填充錯誤的Linux盒子上失敗,在Windows盒子上我沒有看到這個問題。 這些是我的觀察鑑於最後的塊沒有正確填充DES

  • 舊的加密密鑰工作正常。產生的較新的導致不能在Linux機器上的Windows機器上的問題
  • 奔跑

任何人都可以讓我知道什麼可能導致這個問題?

這裏是我的代碼

/** 
* Generate the private key using the passed string. 
* 
* @param keyGeneratorString 
*   : The string which is to be used to generate the private key. 
* @return : SecretKey else null. 
*/ 
public SecretKey getKey(String keyGeneratorString) { 
    SecretKeyFactory keyFactory = null; 
    DESKeySpec keySpec = null; 
    try { 
     // only the first 8 Bytes of the constructor argument are used 
     // as material for generating the keySpec 
     keySpec = new DESKeySpec(keyGeneratorString.getBytes("UTF-8")); 
     // Get the DES encryption standard instance 
     keyFactory = SecretKeyFactory.getInstance("DES"); 
     // Generate and return the key. 
     return keyFactory.generateSecret(keySpec); 
    } catch (UnsupportedEncodingException uee) { 
     logger.error("****** Error while generating key : " 
       + uee.getMessage()); 
    } catch (InvalidKeyException ike) { 
     logger.error("****** Error while generating key : " 
       + ike.getMessage()); 
    } catch (NoSuchAlgorithmException e) { 
     logger.error("****** Error while generating key : " 
       + e.getMessage()); 
    } catch (InvalidKeySpecException e) { 
     logger.error("****** Error while generating key : " 
       + e.getMessage()); 
    } 
    // There was error while generating the key hence return null. 
    return null; 
} 

/** 
* Encrypt the string using the SecretKey. 
* 
* @param stringToBeEncrypted 
*   : The String to be encrypted. 
* @param key 
*   : The secret key to be used for encryption. 
* @return : Encrypted byte[] or null. 
*/ 
public byte[] encrypt(String stringToBeEncrypted, SecretKey key) { 
    Cipher cipherInst; 
    try { 
     cipherInst = Cipher.getInstance("DES/ECB/PKCS5Padding"); 
     cipherInst.init(Cipher.ENCRYPT_MODE, key);// cipher is not thread 
                // safe 
     byte[] encrypted = cipherInst.doFinal(stringToBeEncrypted 
       .getBytes()); 
     return encrypted; 
    } catch (NoSuchAlgorithmException e) { 
     logger.error("****** Error while encrypting : " 
       + e.getMessage()); 
    } catch (NoSuchPaddingException e) { 
     logger.error("****** Error while encrypting : " 
       + e.getMessage()); 
    } catch (InvalidKeyException e) { 
     logger.error("****** Error while encrypting : " 
       + e.getMessage()); 
    } catch (IllegalBlockSizeException e) { 
     logger.error("****** Error while encrypting : " 
       + e.getMessage()); 
    } catch (BadPaddingException e) { 
     logger.error("****** Error while encrypting : " 
       + e.getMessage()); 
    } 
    return null; 
} 

/** 
* Decrypt the string using the SecretKey. 
* 
* @param stringToBeDecrypted : byte[] to be decrypted. 
* @param key : The secret key to be used for decryption. 
* @return : Decrypted byte[] or null. 
*/ 
public byte[] decrypt(byte[] stringToBeDecrypted, SecretKey key) { 
    Cipher cipherInst; 
    try { 
     cipherInst = Cipher.getInstance("DES/ECB/PKCS5Padding"); 
     cipherInst.init(Cipher.DECRYPT_MODE, key); 
     byte[] original = cipherInst 
       .doFinal(stringToBeDecrypted); 
     return original; 
    } catch (NoSuchAlgorithmException e) { 
     logger.error("****** Error while decrypting : " 
       + e.getMessage()); 
    } catch (NoSuchPaddingException e) { 
     logger.error("****** Error while decrypting : " 
       + e.getMessage()); 
    } catch (InvalidKeyException e) { 
     logger.error("****** Error while decrypting : " 
       + e.getMessage()); 
    } catch (IllegalBlockSizeException e) { 
     logger.error("****** Error while decrypting : " 
       + e.getMessage()); 
    } catch (BadPaddingException e) { 
     logger.error("****** Error while decrypting : " 
       + e.getMessage()); 
    } 
    return null; 
} 
+1

看起來很好(除了使用DES,使用ECB和不驗證密文)。你如何在發送者和接收者之間傳輸字節?你似乎遇到了「新鑰匙」的問題。你能舉一個這樣一個新鑰匙的例子嗎? –

+0

檢查解密的最後一個塊以確定填充,只有幾個填充方法,並且只有一個確實應該使用:PKCS#7(或PKCS#5,相同的算法)。添加示例將從「好」和「壞」解密的最後一個塊開始。 – zaph

回答

2

將字符串轉換爲始終使用相同的編碼字節時要小心。此行

byte[] encrypted = cipherInst.doFinal(stringToBeEncrypted 
      .getBytes()); 

使用您的計算機的默認字符編碼,這在Linux和Windows之間可能會有所不同。像生成keySpec一樣使用「UTF8」等一致編碼。

byte[] encrypted = cipherInst.doFinal(stringToBeEncrypted 
      .getBytes("UTF-8")); 

請注意,「填充錯誤」通常不是這樣的事情;這是一個非常誤導性的錯誤信息。

+1

更改加密輸入編碼(或更確切地說,使用固定的編碼)不應改變解密錯誤上的任何內容。這是別的。 –

相關問題