2014-11-05 524 views
1

我搜索了很多,但我還沒有找到一個很好的解決方案如何解決這個問題。我有一個應用程序,它必須使用AES 256來解密長的十六進制字符串。用十六進制字符串加密和解密

爲了測試它,我創建了一個測試方法,將長文本加密爲十六進制,然後將其轉換並解密。

如果我運行此方法,我總是得到以下錯誤:鑑於最終塊沒有正確填充。我在解密方法中收到此錯誤。

的測試方法看起來像這樣:

@Test 
public void testEncAndDecRequestWithHexString() throws UnsupportedEncodingException { 
    CryptoHelper cryptoHelper = new CryptoHelper("AES256"); 
    String paramStr = "ABCB28BCEE5947B8AECE3386871EC0DF&{D5CA99D2-506B-4864-8971-E87821D6B105}&7523429"; 

    //encrypt the param string 
    byte[] paramByteEnc = cryptoHelper.encryptBytesToBytes(paramStr.getBytes("ASCII"), PARAM_KEY, PARAM_IV); 

    //convert it to hex 
    String encryptedHexStr = cryptoHelper.byteArrayToHexStr(paramByteEnc); 

    //convert it back to a byte array 
    byte[] encryptedHexBytes = cryptoHelper.hexStrToByteArray(encryptedHexStr); 

    // decrypt it 
    byte[] paramByteDecrypted = cryptoHelper.decryptBytesToBytes(encryptedHexBytes, encryptedHexBytes.length, PARAM_KEY, PARAM_IV); 

    String decryptedStr = new String(paramByteDecrypted); 

    assertEquals("ABCB28BCEE5947B8AECE3386871EC0DF&{D5CA99D2-506B-4864-8971-E87821D6B105}&7523429", decryptedStr); 
} 

的CryptHelper類有下列方法:

@Override 
public byte[] encryptBytesToBytes(byte[] plainData, byte[] key, byte[] iv) { 
    try { 
     initCipher(Cipher.ENCRYPT_MODE, key, iv); 
     return aesCipher.doFinal(plainData); 

    } catch (IllegalBlockSizeException | BadPaddingException e) { 
     log.severe(e.getMessage()); 
    } 

    return null; 
}  

@Override 
public byte[] decryptBytesToBytes(byte[] encryptedBytes, int length, 
     byte[] key, byte[] iv) { 
    try { 
     initCipher(Cipher.DECRYPT_MODE, key, iv); 
     return aesCipher.doFinal(encryptedBytes, 0, length); 
    } catch (IllegalBlockSizeException | BadPaddingException e) { 
     e.printStackTrace(); 
    } 
    return null; 
} 

private void initCipher(int mode, byte[] keyBytes, byte[] ivBytes) { 
    try { 

     // create shared secret and init cipher mode 
     SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES"); 
     aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
     aesCipher.init(mode == Cipher.ENCRYPT_MODE ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, secretKeySpec, new IvParameterSpec(ivBytes)); 
    } catch (InvalidAlgorithmParameterException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException e) { 
     e.printStackTrace(); 
    } 
} 

public String byteArrayToHexStr(byte[] encrypted) { 
    StringBuilder hex = new StringBuilder(); 
    for (byte b : encrypted) { 
     hex.append(String.format("%02X", b)); 
    } 
    return new String(hex.toString()); 
} 

public byte[] hexStrToByteArray(String hex) { 
    StringBuilder sb = new StringBuilder(); 

    for (int i = 0; i < hex.length() - 1; i += 2) { 
     String output = hex.substring(i, (i + 2)); 
     int decimal = Integer.parseInt(output, 16); 
     sb.append((char) decimal); 
    } 

    String temp = sb.toString(); 
    return temp.getBytes(); 
} 

我用同樣的密鑰和初始化向量用於解密處理,所以這個問題是不錯誤的鍵或初始化向量。我也確信,這裏的每個功能都正確地完成了他們的工作。如果您不使用函數hexStrToByteArray()和byteArrayToHexStr(),並只使用加密字節進行解密,則不會出現問題。我認爲有一個編碼/解碼問題,但我不知道如何在Java中處理它。如果我使用getBytes(「UTF-8」)和新的String(byte [],「UTF-8」),我得到一個IllegalBlockSizeException。

我希望你能幫助我發現我是否正確的做法以及做錯了什麼。

+0

'hexString.append(Integer.toHexString(0xFF的&digestBytes [1]));' 這是怎麼了我將該字節轉換爲十六進制。 – 2014-11-05 16:42:21

+1

不知道其** **問題,但你的'byteArrayToHexStr/hexStrToByteArray'不能正確處理負值。 – 2014-11-05 16:49:16

+0

@DavidSoroko:byteArrayToHexStr看起來正確,另一種方法看起來不正確。 – 2014-11-05 23:35:10

回答

3

這是一個清楚的跡象,表明如果庫函數已經被定義,則不應該編寫庫函數。使用Bouncy Castle,Guava或Apache編解碼器的十六進制編解碼器(直到Oracle終於看到燈並在java.util包中提供一個燈)。

如果你實現它自己,請不要爲字節字符搞錯:

public byte[] hexStrToByteArray(String hex) { 
    ByteArrayOutputStream baos = new ByteArrayOutputStream(hex.length()/2); 

    for (int i = 0; i < hex.length(); i += 2) { 
     String output = hex.substring(i, i + 2); 
     int decimal = Integer.parseInt(output, 16); 
     baos.write(decimal); 
    } 
    return baos.toByteArray(); 
} 
+0

你在開玩笑嗎?剛剛用ByteArrayOutputStream替換了StringBuilder,然後一切正常?好的,謝謝! :d – user1885888 2014-11-06 08:02:32