我需要在Android中生成一个椭圆密钥对,并将其存储到KeyStore以保护私钥不被提取。
我能够使用Spongycastle库生成密钥对,但我无法在KeyStore中导入密钥对。首先,因为我没有证书,其次,即使我尝试创建证书,也没有导入密钥。
我使用KeyGenParameterSpec
生成密钥对,但在版本23以下的API中无法访问。
总结一下我的问题,是否有一种非黑客的方式如何使用通用的Android资源?或者根本不可能在版本Lollipop上使用椭圆曲线键并降低?
答案 0 :(得分:4)
Android keystore system的文档是section on supported key generation algorithms。它声明:
在API Level 23之前,可以使用KeyPairGenerator生成EC密钥 算法" RSA"初始化KeyPairGeneratorSpec,其键类型为 设置为" EC"使用setKeyType(String)。 EC曲线名称不能 使用此方法指定 - 自动选择NIST P曲线 根据请求的密钥大小。
如果您可以忍受这些限制,那么您可以将Android Keystore用于API级别,直至API 19.看起来您可以使用API 18,但是设置密钥大小和密钥类型的必要方法可以在API级别19之前不存在。用于构建API级别19到22的参数规范的类的名称是KeyPairGeneratorSpec.Builder
。这与用于API级别23及更高级别的类KeyGenParameterSpec.Builder
非常相似,所以请注意不要混淆两者。
以下是一小段代码,说明了上述内容。它应该在API 19上运行。
private void createEcKey() throws Exception {
Calendar start = Calendar.getInstance();
Calendar end = Calendar.getInstance();
end.add(Calendar.YEAR, 1);
KeyPairGeneratorSpec spec =
new KeyPairGeneratorSpec.Builder(this)
.setAlias("myKey")
.setKeySize(256)
.setKeyType("EC")
.setSubject(new X500Principal("CN=Dodgy Stuff"))
.setSerialNumber(BigInteger.valueOf(123456789L))
.setStartDate(start.getTime())
.setEndDate(end.getTime())
.build();
KeyPairGenerator kpg = KeyPairGenerator.getInstance(
"RSA", "AndroidKeyStore");
kpg.initialize(spec);
KeyPair keyPair = kpg.generateKeyPair();
ECPublicKey ecPublicKey = (ECPublicKey) keyPair.getPublic();
ECPrivateKey ecPrivateKey = (ECPrivateKey) keyPair.getPrivate();
//
// The following will throw an Exception if uncommented, because
// the private key is not allowed to leave the protection of
// the Androud Keystore boundary.
//
// byte [] privEncoded = ecPrivateKey.getEncoded();
}
答案 1 :(得分:0)
生成secp256r1密钥对代码:
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