问题描述
基于Android java updating certificate and private keys in Android KeyStore的解决方案
我正在尝试使用服务器签名证书与后端连接
// csrRepository.keyPair() returning key pair (pub and private) from AndroidKeyStore
// certificateRepository.getCertificate(CERT_ALIAS) as X509Certificate returning certificate signed by server
val csrKeyPair = csrRepository.keyPair()
val clientCert = certificateRepository.getCertificate(CERT_ALIAS) as X509Certificate
val keyManager = object : X509KeyManager {
override fun getClientAliases(keyType: String?,issuers: Array<out Principal>?): Array<String> {
Timber.i("getClientAliases ")
return arrayOf("csr_alias")
}
override fun chooseClientAlias(
keyType: Array<out String>?,issuers: Array<out Principal>?,socket: Socket?
): String {
Timber.i("chooseClientAlias ")
return "csr_alias"
}
override fun getServerAliases(keyType: String?,issuers: Array<out Principal>?): Array<String>? {
Timber.i("getServerAliases ")
return null
}
override fun chooseServerAlias(
keyType: String?,socket: Socket?
): String? {
Timber.i("chooseServerAlias ")
return null
}
override fun getCertificateChain(alias: String?): Array<X509Certificate> {
Timber.i("getCertificateChain ")
return arrayOf(clientCert)
}
override fun getPrivateKey(alias: String?): PrivateKey {
Timber.i("getPrivateKey ")
return csrKeyPair.private
}
}
val trustServerCertificates: x509trustmanager = object : x509trustmanager {
@Throws(CertificateException::class)
override fun checkClientTrusted(chain: Array<X509Certificate>,authType: String) {
Timber.i("checkClientTrusted ")
// do nothing,this method doesn't get called
}
override fun checkServerTrusted(chain: Array<X509Certificate>,authType: String) {
Timber.i("checkServerTrusted ")
// code to validate server's cert in here
}
override fun getAcceptedissuers(): Array<X509Certificate> {
Timber.i("getAcceptedissuers ")
return emptyArray() // any issuer
}
}
val sslContext = SSLContext.getInstance("TLS")
.apply {
init(arrayOf(keyManager),arrayOf(trustServerCertificates),null)
}
val openConnection: HttpsURLConnection =
URL(url).openConnection() as HttpsURLConnection
openConnection.sslSocketFactory = sslContext.socketFactory
openConnection.connect()
到目前为止我仍然遇到同样的错误
W/CryptoUpcalls: Preferred provider doesn't support key:
java.security.InvalidKeyException: Keystore operation Failed
at android.security.KeyStore.getInvalidKeyException(KeyStore.java:1362)
at android.security.KeyStore.getInvalidKeyException(KeyStore.java:1402)
at android.security.keystore.KeyStoreCryptoOperationUtils.getInvalidKeyExceptionForInit(KeyStoreCryptoOperationUtils.java:54)
at android.security.keystore.KeyStoreCryptoOperationUtils.getExceptionForCipherInit(KeyStoreCryptoOperationUtils.java:89)
at android.security.keystore.AndroidKeyStoreCipherSpiBase.ensureKeystoreOperationInitialized(AndroidKeyStoreCipherSpiBase.java:265)
at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineInit(AndroidKeyStoreCipherSpiBase.java:109)
at javax.crypto.Cipher.tryTransformWithProvider(Cipher.java:2984)
at javax.crypto.Cipher.tryCombinations(Cipher.java:2891)
at javax.crypto.Cipher$SpiAndProviderUpdater.updateAndGetSpiAndProvider(Cipher.java:2796)
at javax.crypto.Cipher.chooseProvider(Cipher.java:773)
at javax.crypto.Cipher.init(Cipher.java:1143)
at javax.crypto.Cipher.init(Cipher.java:1084)
at com.android.org.conscrypt.CryptoUpcalls.rsaOpWithPrivateKey(CryptoUpcalls.java:173)
at com.android.org.conscrypt.CryptoUpcalls.rsaSignDigestWithPrivateKey(CryptoUpcalls.java:132)
at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
at com.android.org.conscrypt.NativeSsl.doHandshake(NativeSsl.java:387)
at com.android.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(ConscryptFileDescriptorSocket.java:226)
at com.android.okhttp.internal.io.RealConnection.connectTls(RealConnection.java:196)
at com.android.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:153)
at com.android.okhttp.internal.io.RealConnection.connect(RealConnection.java:116)
at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:186)
at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:128)
at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:97)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:289)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:232)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:465)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:131)
at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.connect(DelegatingHttpsURLConnection.java:90)
at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:30)
at xxx.yyy.zzz.feature.main.MainActivity$onCreate$2.invokeSuspend(MainActivity.kt:171)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.dispatchedTask.run(dispatchedTask.kt:106)
at kotlinx.coroutines.scheduling.Coroutinescheduler.runSafely(Coroutinescheduler.kt:571)
at kotlinx.coroutines.scheduling.Coroutinescheduler$Worker.executeTask(Coroutinescheduler.kt:750)
at kotlinx.coroutines.scheduling.Coroutinescheduler$Worker.runWorker(Coroutinescheduler.kt:678)
at kotlinx.coroutines.scheduling.Coroutinescheduler$Worker.run(Coroutinescheduler.kt:665)
Caused by: android.security.KeyStoreException: Incompatible digest
at android.security.KeyStore.getKeyStoreException(KeyStore.java:1292)
at android.security.KeyStore.getInvalidKeyException(KeyStore.java:1402)
at android.security.keystore.KeyStoreCryptoOperationUtils.getInvalidKeyExceptionForInit(KeyStoreCryptoOperationUtils.java:54)
at android.security.keystore.KeyStoreCryptoOperationUtils.getExceptionForCipherInit(KeyStoreCryptoOperationUtils.java:89)
at android.security.keystore.AndroidKeyStoreCipherSpiBase.ensureKeystoreOperationInitialized(AndroidKeyStoreCipherSpiBase.java:265)
at android.security.keystore.AndroidKeyStoreCipherSpiBase.engineInit(AndroidKeyStoreCipherSpiBase.java:109)
at javax.crypto.Cipher.tryTransformWithProvider(Cipher.java:2984)
at javax.crypto.Cipher.tryCombinations(Cipher.java:2891)
at javax.crypto.Cipher$SpiAndProviderUpdater.updateAndGetSpiAndProvider(Cipher.java:2796)
at javax.crypto.Cipher.chooseProvider(Cipher.java:773)
at javax.crypto.Cipher.init(Cipher.java:1143)
at javax.crypto.Cipher.init(Cipher.java:1084)
at com.android.org.conscrypt.CryptoUpcalls.rsaOpWithPrivateKey(CryptoUpcalls.java:173)
at com.android.org.conscrypt.CryptoUpcalls.rsaSignDigestWithPrivateKey(CryptoUpcalls.java:132)
at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
at com.android.org.conscrypt.NativeSsl.doHandshake(NativeSsl.java:387)
at com.android.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(ConscryptFileDescriptorSocket.java:226)
at com.android.okhttp.internal.io.RealConnection.connectTls(RealConnection.java:196)
at com.android.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:153)
at com.android.okhttp.internal.io.RealConnection.connect(RealConnection.java:116)
at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:186)
at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:128)
at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:97)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:289)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:232)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:465)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:131)
at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.connect(DelegatingHttpsURLConnection.java:90)
at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:30)
at xxx.yyy.zzz.feature.main.MainActivity$onCreate$2.invokeSuspend(MainActivity.kt:171)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.dispatchedTask.run(dispatchedTask.kt:106)
at kotlinx.coroutines.scheduling.Coroutinescheduler.runSafely(Coroutinescheduler.kt:571)
at kotlinx.coroutines.scheduling.Coroutinescheduler$Worker.executeTask(Coroutinescheduler.kt:750)
at kotlinx.coroutines.scheduling.Coroutinescheduler$Worker.runWorker(Coroutinescheduler.kt:678)
at kotlinx.coroutines.scheduling.Coroutinescheduler$Worker.run(Coroutinescheduler.kt:665)
E/MainActivity$$special$$inlined$CoroutineExceptionHandler: javax.net.ssl.SSLHandshakeException: Handshake Failed
at com.android.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(ConscryptFileDescriptorSocket.java:288)
at com.android.okhttp.internal.io.RealConnection.connectTls(RealConnection.java:196)
at com.android.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:153)
at com.android.okhttp.internal.io.RealConnection.connect(RealConnection.java:116)
at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:186)
at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:128)
at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:97)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:289)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:232)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:465)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:131)
at com.android.okhttp.internal.huc.DelegatingHttpsURLConnection.connect(DelegatingHttpsURLConnection.java:90)
at com.android.okhttp.internal.huc.HttpsURLConnectionImpl.connect(HttpsURLConnectionImpl.java:30)
at xxx.yyy.zzz.feature.main.MainActivity$onCreate$2.invokeSuspend(MainActivity.kt:171)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.dispatchedTask.run(dispatchedTask.kt:106)
at kotlinx.coroutines.scheduling.Coroutinescheduler.runSafely(Coroutinescheduler.kt:571)
at kotlinx.coroutines.scheduling.Coroutinescheduler$Worker.executeTask(Coroutinescheduler.kt:750)
at kotlinx.coroutines.scheduling.Coroutinescheduler$Worker.runWorker(Coroutinescheduler.kt:678)
at kotlinx.coroutines.scheduling.Coroutinescheduler$Worker.run(Coroutinescheduler.kt:665)
Caused by: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x7cb92cf908: Failure in SSL library,usually a protocol error
error:04000044:RSA routines:OPENSSL_internal:internal error (external/conscrypt/common/src/jni/main/cpp/conscrypt/native_crypto.cc:740 0x7cb0789e6b:0x00000000)
at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
at com.android.org.conscrypt.NativeSsl.doHandshake(NativeSsl.java:387)
at com.android.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(ConscryptFileDescriptorSocket.java:226)
... 19 more
根据
W/CryptoUpcalls:首选提供商不支持密钥:
和
引起:android.security.KeyStoreException:不兼容的摘要
我想我以错误的方式生成了密钥对,但是在混合了不同属性的植物后,我现在不知道如何使连接运行
这是我的密钥生成器类
class KeyPairGen constructor(
private val provider: String
) {
fun generate(alias: String) {
val keyPairGenerator =
KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA,provider)
val keyGenParameterSpec = buildKeyGenParameterSpec(alias)
keyPairGenerator.initialize(keyGenParameterSpec)
keyPairGenerator.generateKeyPair()
}
private fun buildKeyGenParameterSpec(alias: String) =
KeyGenParameterSpec.Builder(alias,KeyProperties.PURPOSE_SIGN or KeyProperties.PURPOSE_VERIFY)
.setDigests(KeyProperties.DIGEST_SHA256)
.setKeySize(KEY_SIZE)
.setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
.build()
companion object {
private const val KEY_SIZE = 2048
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)