在我的應用程序中,我們使用了CRYPTO提供程序來創建隨機數。但它在Android N中被刪除。如果應用程序依靠setSeed()從字符串派生鍵,那麼我們應該切換到使用SecretKeySpec直接加載原始密鑰字節或使用真正的密鑰派生函數(KDF)。根據下面的鏈接使用新的加密/解密算法更新Android Live應用程序
Caused by: java.security.NoSuchProviderException: no such provider: Crypto - Android N
現在我的問題是,使用應用程序與舊的算法(SHA1PRNG &加密提供)所有現有的用戶。所有應用程序數據已使用以下算法進行加密,並保存在「共享首選項」和「SQLITE」中。
如果我給新Encrpt應用更新/解密算法,然後應用程序可能會崩潰時進行解密免於SQLITE數據和共享偏好
任何人都可以提出一個方法來遷移舊的Encrpt /解密算法,以新的,而不影響用戶。
public static String encrypt(String seed, String clearText) throws Exception {
byte[] rawKey = getRawKey(seed.getBytes(STR_ENCODE_UTF8));
byte[] result = encryptDecrypt(rawKey, clearText.getBytes(STR_ENCODE_UTF8), Cipher.ENCRYPT_MODE);
return new String(Base64.encode(toHex(result).getBytes(STR_ENCODE_UTF8), Base64.DEFAULT)).trim();
}
public static String decrypt(String seed, String encrypted) throws Exception {
String decodedStr = new String(Base64.decode(encrypted.trim(), Base64.DEFAULT));
byte[] rawKey = getRawKey(seed.getBytes(STR_ENCODE_UTF8));
byte[] enc = toByte(decodedStr);
byte[] result = encryptDecrypt(rawKey, enc, Cipher.DECRYPT_MODE);
return new String(result);
}
private static byte[] getRawKey(byte[] seed) throws NoSuchAlgorithmException, NoSuchProviderException {
KeyGenerator kGen = KeyGenerator.getInstance(KEY_GENERATOR_ALGORITHM);
SecureRandom sr = SecureRandom.getInstance(STR_SHA1PRNG, CRYPTO);
sr.setSeed(seed);
kGen.init(128, sr);
SecretKey sKey = kGen.generateKey();
byte[] raw = sKey.getEncoded();
return raw;
}
謝謝Maarten ....只是另一個問題...爲了給用戶提供向後兼容性和遷移舊的加密數據,我需要SHA1PRNG_SecureRandomImpl。我在哪裏可以得到它? 1.在我的應用程序中嵌入實現將有任何版權問題? 2.是否有任何依賴,我們可以在我們的gradle中添加使用實現3.或者任何可用的jar文件,我可以在我的應用程序中包含下一個版本 – Ananth
https://raw.githubusercontent.com/apache/harmony/java6 /classlib/modules/security/src/main/java/common/org/apache/harmony/security/provider/crypto/SHA1PRNG_SecureRandomImpl.java將是主要的嫌疑犯。我會測試它,看看我能否從中獲得相同的字節;它沒有太多的依賴關係。你當然可以做同樣的事情。 –
https://github.com/apache/harmony/blob/java6/ classlib/modules/security/src/main/java/common/org/apache/and/security/provider /原始的,可能更容易 –