2014-06-26 36 views
1

我目前正在嘗試加密和解密java字符串。 factory.generateSecret的執行過程中SecretKeyFactory在傳遞PBEKeySpec時產生密文錯誤

public static String AESencryptString(String clearStr) throws Exception { 
    String cipherStr = null; 

    //génération de la clé de cryptage AES 
    SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 
    PBEKeySpec spec = new PBEKeySpec(KEY.toCharArray()); 
    Log.d("test", ""+ spec); 
    SecretKey tmp = factory.generateSecret(spec); 
    SecretKey key = new SecretKeySpec(tmp.getEncoded(), "AES"); 

    //cryptage du mot de passe 
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
    cipher.init(Cipher.ENCRYPT_MODE, key); 
    byte[] cipherByteArray = cipher.doFinal(clearStr.getBytes("UTF-8")); 

    //convertion du mot de passe en String pour l'enregistrement en base 
    cipherStr = new String(Base64.encode(cipherByteArray, 0)); 

    return cipherStr; 
} 

public static String AESdecryptString(String cipherStr) throws Exception { 
    String clearStr = null; 

    //génération de la clé de cryptage AES 
    SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 
    KeySpec spec = new PBEKeySpec(KEY.toCharArray()); 
    SecretKey tmp = factory.generateSecret(spec); 
    SecretKey key = new SecretKeySpec(tmp.getEncoded(), "AES"); 

    //décryptage du mot de passe 
    Cipher decipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
    decipher.init(Cipher.DECRYPT_MODE, key); 
    byte[] clearByteArray = decipher.doFinal(cipherStr.getBytes()); 

    //convertion du mot de passe en String pour l'enregistrement en base 
    clearStr = new String(Base64.encode(clearByteArray, 0)); 

    return clearStr; 
} 

拋出的錯誤是「InvalidKeySpec」 - >我知道,這個錯誤是由於缺少鹽,但是,如果我能:爲此我寫了下面的2種方法用一個密碼創建一個PBEKeySpec,它應該有一個使用它的方法,你能幫助找到它嗎?

我試着用SALT,只是爲了測試......並且它也不起作用,但錯誤是不一樣的。在這種情況下,錯誤引發「cipher.init」,我不知道這個錯誤是什麼,因爲調試器告訴我「」

請幫助我,因爲我會瘋了!

回答

1

創建當PBEKeySpec您必須使用構造函數四個參數:

PBEKeySpec(char[] password, byte[] salt, int iterationCount, int keyLength) 

注意:您可以存儲未加密的加鹽加密的文本之前。 iterationCount可以在應用程序中進行硬編碼。

byte[] salt = new byte[8]; 
new SecureRandom().nextBytes(salt); 
PBEKeySpec spec = new PBEKeySpec(KEY.toCharArray(), salt, 10000, 128); 

該示例對AES128使用128通常是足夠的。

+0

謝謝!但是我還有一個問題:如果在這種情況下我不能使用帶有一個參數的構造函數,那麼我可以使用它嗎? – neobagram

+0

這取決於使用的SecretKeyfactory。 PBEKeySpec是通用Java Crypto API的一部分。您可以實現一個SecretKeyFactory,該SecretKeyFactory可以使用僅包含密碼的PBEKeySpec。但在您的情況下,使用ScretKeyfactory「PBKDF2WithHmacSHA1」生成AES密鑰需要全部4個參數。 – Robert

+0

有沒有辦法用另一個接受一個參數PBEKeySpec的secretKeyFactory創建一個AES密鑰? – neobagram