如何使用secp256r1类型的椭圆曲线密钥对在Android中加密和解密数据?

时间:2019-07-18 05:22:18

标签: android encryption kotlin elliptic-curve

我需要使用NIST P-256椭圆曲线来加密和解密数据。现在已经生成了密钥对,但是如何使用它们进行加密和解密?

官方网站只说了如何使用此ec密钥对进行签名/验证,但我想知道如何使用此ec密钥对进行加密/解密。

网站:https://developer.android.com/reference/android/security/keystore/KeyGenParameterSpec#example:-nist-p-256-ec-key-pair-for-signingverification-using-ecdsa

生成NIST P-256密钥对代码:

        val kpg: KeyPairGenerator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore")
        val parameterSpec =
            KeyGenParameterSpec.Builder("container", KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
                .setAlgorithmParameterSpec(ECGenParameterSpec("secp256r1"))
                .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA384, KeyProperties.DIGEST_SHA512)
                .build()
        kpg.initialize(parameterSpec)
        val keyPair = kpg.generateKeyPair()

        val ecPublicKey = keyPair.public as ECPublicKey
        val ecPrivateKey = keyPair.private as ECPrivateKey

2 个答案:

答案 0 :(得分:1)

AndroidKeyStore当前不支持使用EC密钥加密或解密,仅支持RSA密钥。

要使用EC密钥进行加密,您需要使用ECDH加上密钥派生函数(KDF)来计算可用于数据的共享对称密钥,或使用内部进行加密的ECIES。但是从Android 10开始,AndroidKeyStore不支持任何一种操作模式。也许在Android 11中也是如此。

目前,您可以使用具有适当填充模式的RSA(建议使用OAEP)对对称密钥进行加密,也可以使用本机Java cryto提供程序。不幸的是,这不会使用安全的硬件来生成,存储或使用密钥,而是会在应用程序的处理空间中完成所有这些操作。有一个示例here

(出于价值,我是拥有AndroidKeyStore的Google工程师。几年来我一直在计划增加对ECDH的支持,但一直被优先级更高的其他功能所取代。我会去解决的。)

答案 1 :(得分:0)

不建议将公钥加密用于加密。通常的做法是混合加密,其中交换块密码密钥,然后执行对称加密。

在交换密钥后,最常见的问题是身份验证和完整性。现代做法是使用经过身份验证的加密模式作为AES-GCM。 GCM模式为您提供身份验证和完整性。您可以看到一个实现here