Android:在KeyStore中存储SecretKey

Raj*_*ran 11 encryption android keystore secret-key android-keystore

我使用SecretKey加密应用程序中的敏感数据.目前我将我的SecretKey以Base64编码格式存储在DB或SharedPrefs中,这不是在根电话上存储Secret的安全位置.因此,我想将我的SecretKey移动到Android KeyStore.我面临的问题是当我尝试使用Google的示例代码时,它需要一个PrivateKey而不是SecretKey.我无法找到一种方法将我的SecretKey存储在KeyStore中并获取它以供以后使用.我试过这个:

private static void writeSecretKeyToKeystore(SecretKey secretKey, Context context) {
KeyStore keyStore = null;
try {
  keyStore = KeyStore.getInstance("AndroidKeyStore");
  keyStore.load(null);
  KeyStore.SecretKeyEntry secretKeyEntry = new KeyStore.SecretKeyEntry(secretKey);
  keyStore.setKeyEntry("Key", secretKeyEntry.getSecretKey().getEncoded(), null);
} catch (KeyStoreException e) {
  e.printStackTrace();
} catch (CertificateException e) {
  e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
  e.printStackTrace();
} catch (IOException e) {
  e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)

当我尝试上面的代码时,它会抛出异常Operation not supported because encoding is unknown.

任何示例代码都会有很大帮助.

dev*_*max 6

WRONG
java.security.KeyStore可以存储对称和非对称密钥.你只需要实例化KeyStore.SecretKeyEntry在构造函数中传递你的SecretKey,然后使用KeyStore #setEntry方法来保存它:

keyStore.setEntry(
     "key1",
     new KeyStore.SecretKeyEntry(secretKey),
     new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
             .setBlockMode(KeyProperties.BLOCK_MODE_GCM)
             .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
             .build());
Run Code Online (Sandbox Code Playgroud)

要恢复使用:

SecretKey keyStoreKey = (SecretKey) keyStore.getKey("key1", null);
Run Code Online (Sandbox Code Playgroud)

更新
经过一些研究后,我惊讶地发现,AndroidKeyStore不支持对称密钥.(参见讨论:https://groups.google.com/forum/#!topic/android- Developers/gbmIRKRbfq8)

  • 这不适用于 API < 23。我正在开发一个从 Lollipop 开始的应用程序。我使用这个代码 keyStore.setEntry("key1", new KeyStore.SecretKeyEntry(secretKey), new KeyStoreParameter.Builder(context).setEncryptionRequired(true).build()); 但它不起作用。不过赞成你的回答。 (2认同)