我用下面的代碼來生成AES密鑰:上SecretKey的調用.getEncoded()返回null
KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder("db_enc_key", KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT);
KeyGenParameterSpec keySpec = builder
.setKeySize(256)
.setBlockModes("CBC")
.setEncryptionPaddings("PKCS7Padding")
.setRandomizedEncryptionRequired(true)
.setUserAuthenticationRequired(true)
.setUserAuthenticationValidityDurationSeconds(5 * 60)
.build();
KeyGenerator keyGen = KeyGenerator.getInstance("AES", "AndroidKeyStore");
keyGen.init(keySpec);
SecretKey sk = keyGen.generateKey();
,但每次我試圖讓通過sk.getEncoded關鍵的字節[]版本() ,該方法返回null。文檔說它應該返回編碼密鑰,如果密鑰不支持編碼,則返回null,但我不認爲密鑰不支持編碼。
我需要的byte [],因爲我要加密一個境界數據庫(我需要2 AES-256按鍵組合成字節數組)https://realm.io/docs/java/latest/#encryption]
官方文檔使用SecureRandom的,但也規定這是做這件事的一種愚蠢的方式,並且鑰匙從不儲存。因此,我想使用KeyStore安全地存儲兩個獨立的AES-256密鑰。
P.S .:代碼只是一個測試代碼而不是最終產品,所以對編碼風格的任何評論都是無用的。我目前只是試圖讓一個工作版本。
編輯:所以,我試圖將下面的代碼,它成功地產生AES密鑰(雖然只有16字節長度的):
SecretKey sk1 = KeyGenerator.getInstance("AES").generateKey();
當我使用的getEncoded()方法就可以了,我會甚至得到字節數組,所以自然我繼續並使用以下代碼將其保存到KeyStore中:
KeyStore.SecretKeyEntry entry = new KeyStore.SecretKeyEntry(sk1);
KeyStore.ProtectionParameter pp = new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_ENCRYPT).build();
keyStore.setEntry("db_enc_key_test", entry, pp);
這也適用。所以我試圖通過KeyStore.Entry entry2 = keyStore.getEntry("db_enc_key_test", null);
從密鑰庫中讀取密鑰,這也起作用。但是當我撥打entry2.getEncoded()
時,該方法會再次返回空值。這是一個密鑰存儲問題嗎?
edit2:所以我剛剛發現,在密鑰庫中生成的對稱密鑰在Android M中是不可移植的,這似乎是有意的,這使我陷入了一個問題,因爲我需要密鑰本身用於加密領域數據庫。
一些領域開發人員在這裏推薦一個最佳實踐?
是的,這聽起來像是目前最好的解決方法。謝謝。 – wickermoon