在 API 调用中使用 AndroidKeyStore 创建 SSLContext KeyManagerFactory 时出错
我正在尝试使用 AndroidKeyStore 调用具有客户端身份验证的 API,但收到以下错误
W/CryptoUpcalls:找不到算法的提供者:RSA/ECB/NoPadding
android.security.KeyStoreException:不兼容的填充模式
fun createSSLContextAndroid(context: Context): SSLContext? {
val certificateFactory = CertificateFactory.getInstance("X.509")
val caCertificate =
certificateFactory.generateCertificate(context.resources.openRawResource(R.raw.ca))
val clientCertificate = certificateFactory.generateCertificate(context.resources.openRawResource(R.raw.android_new))
val keyStoreType = KeyStore.getDefaultType()
val keyStoreTrust = KeyStore.getInstance(keyStoreType)
keyStoreTrust.load(null, null)
keyStoreTrust.setCertificateEntry("mt", caCertificate)
val tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm()
val tmf = TrustManagerFactory.getInstance(tmfAlgorithm)
tmf.init(keyStoreTrust)
val ks = KeyStore.getInstance("AndroidKeyStore")
ks.load(null, null)
val certificateAlias = "certificate"
ks.setCertificateEntry(certificateAlias, clientCertificate)
val privateKeyEntry = ks.getEntry(Config.KEYSTORE_ALIAS, null) as KeyStore.PrivateKeyEntry
ks.setKeyEntry(Config.KEYSTORE_ALIAS, privateKeyEntry.privateKey, null, arrayOf(clientCertificate))
val kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())
kmf.init(ks, null)
val sslContext = SSLContext.getInstance("TLS")
sslContext.init(kmf.keyManagers, tmf.trustManagers, null)
return sslContext
}
使用以下代码生成密钥
fun initKeyGeneratorPair(): KeyPairGenerator {
val kpg: KeyPairGenerator = KeyPairGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_RSA,
"AndroidKeyStore"
)
kpg.initialize(
KeyGenParameterSpec.Builder(
Config.KEYSTORE_ALIAS,
KeyProperties.PURPOSE_SIGN or KeyProperties.PURPOSE_VERIFY or KeyProperties.PURPOSE_ENCRYPT or
KeyProperties.PURPOSE_DECRYPT
)
.setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
.setDigests(
KeyProperties.DIGEST_NONE,
KeyProperties.DIGEST_SHA256,
KeyProperties.DIGEST_SHA512
)
.setKeySize(4096)
.build()
)
return kpg
}
I am trying to call API with client authentication using AndroidKeyStore but I am getting the below error
W/CryptoUpcalls: Could not find provider for algorithm: RSA/ECB/NoPadding
android.security.KeyStoreException: Incompatible padding mode
fun createSSLContextAndroid(context: Context): SSLContext? {
val certificateFactory = CertificateFactory.getInstance("X.509")
val caCertificate =
certificateFactory.generateCertificate(context.resources.openRawResource(R.raw.ca))
val clientCertificate = certificateFactory.generateCertificate(context.resources.openRawResource(R.raw.android_new))
val keyStoreType = KeyStore.getDefaultType()
val keyStoreTrust = KeyStore.getInstance(keyStoreType)
keyStoreTrust.load(null, null)
keyStoreTrust.setCertificateEntry("mt", caCertificate)
val tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm()
val tmf = TrustManagerFactory.getInstance(tmfAlgorithm)
tmf.init(keyStoreTrust)
val ks = KeyStore.getInstance("AndroidKeyStore")
ks.load(null, null)
val certificateAlias = "certificate"
ks.setCertificateEntry(certificateAlias, clientCertificate)
val privateKeyEntry = ks.getEntry(Config.KEYSTORE_ALIAS, null) as KeyStore.PrivateKeyEntry
ks.setKeyEntry(Config.KEYSTORE_ALIAS, privateKeyEntry.privateKey, null, arrayOf(clientCertificate))
val kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm())
kmf.init(ks, null)
val sslContext = SSLContext.getInstance("TLS")
sslContext.init(kmf.keyManagers, tmf.trustManagers, null)
return sslContext
}
generate the key using the below code
fun initKeyGeneratorPair(): KeyPairGenerator {
val kpg: KeyPairGenerator = KeyPairGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_RSA,
"AndroidKeyStore"
)
kpg.initialize(
KeyGenParameterSpec.Builder(
Config.KEYSTORE_ALIAS,
KeyProperties.PURPOSE_SIGN or KeyProperties.PURPOSE_VERIFY or KeyProperties.PURPOSE_ENCRYPT or
KeyProperties.PURPOSE_DECRYPT
)
.setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
.setDigests(
KeyProperties.DIGEST_NONE,
KeyProperties.DIGEST_SHA256,
KeyProperties.DIGEST_SHA512
)
.setKeySize(4096)
.build()
)
return kpg
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我还没有发现此问题的确切原因,但对我来说,通过添加.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) 来稍微更改
KeyGenParameterSpec
有所帮助。 .我仍在寻找确切的原因以及这是否是合适的解决方案。更新:
经过更多研究和阅读 KeyGenParameterSpec 的文档后,它指出如果密钥要用于 TLS/SSL,通常需要执行以下操作:
如 setEncryptionPaddings 的文档中所示:
以及 setDigests:
I haven't discovered the exact cause of this issue yet, but for me it helped to change theKeyGenParameterSpec
a bit by adding.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.Im still searching for the exact cause and whether or not this is an appropriate solution.Update:
After more research and reading the documentation for KeyGenParameterSpec, it states that if the key is to be used for TLS/SSL, its usually neccesary to do the following:
As seen in the documentation for setEncryptionPaddings:
And for setDigests: