ECDH使用Android KeyStore生成私钥

Mol*_*ka 5 java android keystore

我正在尝试使用由 Android KeyStore Provider 生成的私有在 Android 中实现 ECDH。

public byte[] ecdh(PublicKey otherPubKey) throws Exception {

    try {
        ECPublicKey ecPubKey = (ECPublicKey) otherPubKey;
        KeyAgreement keyAgreement = KeyAgreement.getInstance("ECDH");
        PrivateKey pk = (PrivateKey) LoadPrivateKey("Backend");
        keyAgreement.init(pk);
        keyAgreement.doPhase(ecPubKey, true);

        return (keyAgreement.generateSecret());
    }
    catch (Exception e)
    {
        Log.e("failure", e.toString());
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,这个异常在 keyAgreement.init(pk) 中被捕获:

E/失败:java.security.InvalidKeyException:无法识别 EC 私钥:java.security.InvalidKeyException:EC 私钥没有编码

我之前使用以下方法成功生成了“后端”公钥/私钥对:

public void GenerateNewKeyPair(String alias)
        throws Exception {

    if (!keyStore.containsAlias(alias)) {
        // use the Android keystore
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_EC, ANDROID_KEYSTORE);
        keyGen.initialize(
                new KeyGenParameterSpec.Builder(
                        alias,
                        KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY | KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
                        .setAlgorithmParameterSpec(new ECGenParameterSpec("secp256r1"))
                        .setDigests(KeyProperties.DIGEST_SHA256,
                                KeyProperties.DIGEST_SHA384,
                                KeyProperties.DIGEST_SHA512)
                        .setRandomizedEncryptionRequired(true)
                        .build());
        // generates the keypair
        KeyPair keyPair = keyGen.generateKeyPair();
    }
Run Code Online (Sandbox Code Playgroud)

}

我使用以下方法加载私钥:

public PrivateKey LoadPrivateKey(String alias) throws Exception {
    PrivateKey key = (PrivateKey) keyStore.getKey(alias, null);
    return key;
}
Run Code Online (Sandbox Code Playgroud)

任何人都知道发生了什么并且可以帮助我了解如何解决它?谢谢!

dat*_*mNY 3

据我通过研究和反复试验所知,目前支持此功能。

我相信您能做的最好的事情就是使用存储在 AndroidKeyStore 中的 EC 密钥对对您在 AndroidKeyStore 外部生成的 EC 密钥对的公钥进行签名。然后,您可以将此签名的公钥与您的签名密钥证书一起发送给另一方,生成共享密钥(在 AndroidKeyStore 之外),然后将使用 KDF 派生的 SecretKey 存储在生成的密钥上。我建议使用这个非 AndroidKeyStore 生成的密钥对一次(因此仅用于派生密钥的目的),并在认为必要时重复此过程以重新生成密钥。

编辑:当我说“存储 SecretKey”时,我的意思是在 AndroidKeyStore 中。在这种情况下,该密钥最初将位于所谓的“正常世界”中,但这是您目前所能做的最好的事情。