2013-03-05 81 views
0

我在這裏有一個簡單的代碼,代碼使用sun.misc.BASE64Encoder和sun.misc.BASE64Decoder,這些在Eclipse Java 7.0中不可用,我想使代碼如此它使用了Apache下議院底座64,仍然做同樣的事情,sun.misc.BASE64到apache commons

變量

private static final String ALGORITHM = "AES"; 
private static final byte[] keyValue = "2H5a1r5i6s3h8C1h".getBytes(); 

原始代碼

public static String AESencrypt(String valueToEnc) throws Exception { 
    Key key = new SecretKeySpec(keyValue, ALGORITHM); 
    Cipher c = Cipher.getInstance(ALGORITHM); 
    c.init(Cipher.ENCRYPT_MODE, key); 
    byte[] encValue = c.doFinal(valueToEnc.getBytes()); 
    String encryptedValue = new BASE64Encoder().encode(encValue); 
    return encryptedValue; 
} 

public static String AESdecrypt(String encryptedValue) throws Exception { 
    Key key = new SecretKeySpec(keyValue, ALGORITHM); 
    Cipher c = Cipher.getInstance(ALGORITHM); 
    c.init(Cipher.DECRYPT_MODE, key); 
    byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedValue); 
    byte[] decValue = c.doFinal(decordedValue); 
    String decryptedValue = new String(decValue); 
    return decryptedValue; 
} 

試圖修改Apache的公共代碼

public static String AESencrypt(String valueToEnc) throws Exception { 
    Key key = new SecretKeySpec(keyValue, ALGORITHM); 
    Cipher c = Cipher.getInstance(ALGORITHM); 
    c.init(Cipher.ENCRYPT_MODE, key); 
    byte[] encValue = c.doFinal(valueToEnc.getBytes()); 
    String encryptedValue = new Base64().encodeBase64(encValue).toString(); 
    return encryptedValue; 
} 

public static String AESdecrypt(String encryptedValue) throws Exception { 
    Key key = new SecretKeySpec(keyValue, ALGORITHM); 
    Cipher c = Cipher.getInstance(ALGORITHM); 
    c.init(Cipher.DECRYPT_MODE, key); 
    byte[] decordedValue = new Base64().decodeBase64(encryptedValue); 
    byte[] decValue = c.doFinal(decordedValue); 
    String decryptedValue = new String(decValue); 
    return decryptedValue; 
} 

原來的代碼工作正常,新的代碼拋出以下異常,

異常線程 「main」 javax.crypto.IllegalBlockSizeException : 當用加密密碼 在com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:750) at com.sun.crypto.provider.CipherCore.doFinal(Ciph)解密時,輸入長度必須是16的倍數erCore.java:676) 處 trial2.encrypt.AESdecrypt com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:313) 在javax.crypto.Cipher.doFinal(Cipher.java:2087) (encrypt.java:28)在 trial2.encrypt.main(encrypt.java:37) Java結果:1

我怎樣才能解決這個問題,而不改變初始密碼太多了,這裏的幾行並沒有問題。是否有可能完全消除Base64encoding一步,使其只這樣的加密工作:

public static String AESencrypt(String valueToEnc) throws Exception { 
    Key key = new SecretKeySpec(keyValue, ALGORITHM); 
    Cipher c = Cipher.getInstance(ALGORITHM); 
    c.init(Cipher.ENCRYPT_MODE, key); 
    byte[] encValue = c.doFinal(valueToEnc.getBytes()); 
    return encValue.toString(); 
} 

public static String AESdecrypt(String encryptedValue) throws Exception { 
    Key key = new SecretKeySpec(keyValue, ALGORITHM); 
    Cipher c = Cipher.getInstance(ALGORITHM); 
    c.init(Cipher.DECRYPT_MODE, key); 
    byte[] decValue = c.doFinal(encryptedValue.getBytes()); 
    String decryptedValue = new String(decValue); 
    return decryptedValue; 
} 

上面的代碼也有類似的異常,如第二碼:

異常線程「main」 javax.crypto.IllegalBlockSizeException: 當使用填充密碼 解密時,輸入長度必須是16的倍數com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:750) at com.sun.crypto.provider.CipherCore .doFinal(CipherCore.java:676) at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:313) at javax.crypto.Cipher.doFinal(Cipher.java:2087)at trial2.encrypt.AESdecrypt(encrypt.java:26)at trial2.encrypt.main(encrypt.java:35)Java結果:1

請幫忙TYVM

+0

建議:去掉密碼並做一些測試。它們是否產生相同的值等等,這應該是可以解決的! – 2013-03-05 12:31:31

+0

永遠不會*使用Sun內部類,它們可能會在沒有警告的情況下被刪除或更改。它們不是官方Java API的一部分。請注意,如果您選擇特定的JRE或JDK而不是運行時環境,則這些類將再次可用(同樣,因爲運行時環境僅將這些類用於實現目的而不是API) – 2013-03-05 23:19:48

+1

不要只將「AES」指定爲算法,如它可能會爲特定提供商返回不同的默認值。在Sun/Oracle默認情況下,它會返回「AES/ECB/PKCS5Padding」,這是不安全的(保密的最低要求模式是CBC模式)。 – 2013-03-05 23:21:41

回答

2

的錯誤是在你的加密方法。下面的代碼是錯誤的:

byte[] encValue = c.doFinal(valueToEnc.getBytes()); 
String encryptedValue = new Base64().encodeBase64(encValue).toString(); 

要調用一個字節數組,你想要什麼,不會做toString()!相反,請嘗試:

byte[] encValue = c.doFinal(valueToEnc.getBytes()); 
String encryptedValue = Base64.encodeBase64String(encValue); 

這應該可以正常工作。

+0

似乎工作,是否有必要進行base64encoding步驟?我的意思是我不明白它做了什麼。 – chettyharish 2013-03-05 12:50:32

+2

如果您希望將密文存儲爲字符串,base64編碼步驟是您可以使用的選項之一。另一個通常選擇的選項是base16(a.k.a十六進制)。根據您的使用情況,您可以將密文保留爲字節數組。通常情況下,轉換爲字符串僅用於傳輸數據,特別是在Web環境中。 – 2013-03-05 13:18:33

+0

ty的幫助,猜猜我需要做到保存到數據庫。 – chettyharish 2013-03-05 15:26:44

相關問題