在Android上,我沒有任何問題加密消息並獲得iv。Android上的基於密碼的AES加密和CryptoJS的解密
String Test = "Lorem ipsum dolor sit amet, ...";
String password = "test";
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(password.getBytes("UTF8"));
kgen.init(256, sr);
SecretKey skey = kgen.generateKey();
Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec skeySpec = new SecretKeySpec(skey.getEncoded(), "AES");
c.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] decrypted = c.doFinal(Test.getBytes());
decrypted = Base64.encodeBase64(decrypted);
byte[] iv = Base64.encodeBase64(c.getIV());
Log.d("encryptString", new String(decrypted));
Log.d("encryptString iv", new String(iv));
輸出例如:
encryptString: 2NVoJzMkPphwUJc2h/4LfsmAwyJlejbWKGLG2ACNbaI=
encryptString iv: YX5SF+cFwzv1I4OiGrJk3A==
當我動過的JavaScript側I第一base64編碼轉換爲字節。然後通過CryptoJS AES Decrypt函數運行它。
var decrypt = CryptoJS.enc.Base64.parse("2NVoJzMkPphwUJc2h/4LfsmAwyJlejbWKGLG2ACNbaI=");
var iv = CryptoJS.enc.Base64.parse("YX5SF+cFwzv1I4OiGrJk3A==");
var password = "test";
var encrypted = CryptoJS.AES.decrypt(decrypt.toString(), password, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
輸出總是空的。 Android上還有其他東西,我還需要傳遞給CryptoJS?
如果您僅使用對稱加密,則需要在服務器和客戶端使用完全相同的密鑰。如果您將加密密鑰從服務器發送到客戶端或其他方式需要加密對稱加密密鑰。最簡單的方法是使用TLS。如果你使用TLS,那麼數據和密鑰都是加密的,所以你不需要自己加密。這不提供任何安全性,只是一點混淆。您應該閱讀:https://www.nccgroup.trust/us/about-us/newsroom-and-events/blog/2011/august/javascript-cryptography-considered-harmful/ –
切勿使用SHA1PRNG或其他'SecureRandom'實現從密碼派生密鑰。它不會總是有效,因爲PRNG的密碼可能不是隨機性的唯一來源。請使用PBKDF2來從密碼派生密鑰。供參考:https://stackoverflow.com/a/20134336/1816580 –
關鍵是以完全不同的方式派生。 CryptoJS使用EVP_BytesToKey,Android使用* something *隨API版本更改。只需使用兩者都支持的相同程序(即PBKDF2)。 –