android.security.KeyStoreException:集成 freeRASP 库时目的不兼容

问题描述 投票:0回答:1

将库 freeRASP Android(版本 8.3.0)添加到我们的项目后,当尝试调用安全端点时,我们从 Retrofit/OkHttp 或 KeyStore 异常中收到 SSLException,并且我们的 api 调用失败。 我们尝试更新到 9.0.0,但这并没有解决问题。

javax.net.ssl.SSLHandshakeException: Read error: ssl=0xb400007aa9f06888: 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:732 0x7aa3ed3791:0x00000000)

使用以下设备进行测试

  • 设备:Pixel 7 Pro
  • 操作系统版本:Android 14
  • freeRASP 版本:8.3.0 和 9.0.0

应用程序配置:

  • minSdk版本是26
  • targetSdk版本是34

我们拥有的 Android 10 至 14 的所有其他测试设备(三星、Pixel、华为、OnePlus、Fairphone)也会发生这种情况

为了记录在我们的项目中,我们有以下库 Retrofit 2.10.0、Moshi 1.15.1、Koin 3.5.3、OkHttp 4.12.0、BouncyCastle,我们通过

.certificatePinner
在应用程序中安装了 proguard、SSL 固定
 OkHttpClient
,我们还有一个带有 TLS 协议的自定义
sslSocketFactory

此外,在尝试登录应用程序时,我们还遇到以下问题。

Preferred provider doesn't support key:
    java.security.InvalidKeyException: Keystore operation failed
    at android.security.keystore2.KeyStoreCryptoOperationUtils.getInvalidKeyException(KeyStoreCryptoOperationUtils.java:128)
    at android.security.keystore2.KeyStoreCryptoOperationUtils.getExceptionForCipherInit(KeyStoreCryptoOperationUtils.java:152)
    at android.security.keystore2.AndroidKeyStoreCipherSpiBase.ensureKeystoreOperationInitialized(AndroidKeyStoreCipherSpiBase.java:360)
    at android.security.keystore2.AndroidKeyStoreCipherSpiBase.engineInit(AndroidKeyStoreCipherSpiBase.java:188)
    at javax.crypto.Cipher.tryTransformWithProvider(Cipher.java:2985)
    at javax.crypto.Cipher.tryCombinations(Cipher.java:2892)
    at javax.crypto.Cipher$SpiAndProviderUpdater.updateAndGetSpiAndProvider(Cipher.java:2797)
    at javax.crypto.Cipher.chooseProvider(Cipher.java:774)
    at javax.crypto.Cipher.init(Cipher.java:1144)
    at javax.crypto.Cipher.init(Cipher.java:1085)
    at com.android.org.conscrypt.CryptoUpcalls.rsaOpWithPrivateKey(CryptoUpcalls.java:180)
    at com.android.org.conscrypt.CryptoUpcalls.rsaSignDigestWithPrivateKey(CryptoUpcalls.java:139)
    at com.android.org.conscrypt.NativeCrypto.ENGINE_SSL_read_direct(Native Method)
    at com.android.org.conscrypt.NativeSsl.readDirectByteBuffer(NativeSsl.java:568)
    at com.android.org.conscrypt.ConscryptEngine.readPlaintextDataDirect(ConscryptEngine.java:1095)
    at com.android.org.conscrypt.ConscryptEngine.readPlaintextData(ConscryptEngine.java:1079)
    at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:876)
    at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:747)
    at com.android.org.conscrypt.ConscryptEngine.unwrap(ConscryptEngine.java:712)
    at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.processDataFromSocket(ConscryptEngineSocket.java:896)
    at com.android.org.conscrypt.ConscryptEngineSocket$SSLInputStream.-$$Nest$mprocessDataFromSocket(Unknown Source:0)
    at com.android.org.conscrypt.ConscryptEngineSocket.doHandshake(ConscryptEngineSocket.java:236)
    at com.android.org.conscrypt.ConscryptEngineSocket.startHandshake(ConscryptEngineSocket.java:218)
    at jD.k.g(Unknown Source:105)
    at jD.k.c(Unknown Source:168)
    at jD.e.a(Unknown Source:708)
    at jD.a.a(Unknown Source:57)
    at kD.f.b(Unknown Source:125)
    at hD.a.a(Unknown Source:142)
    at kD.f.b(Unknown Source:125)
    at kD.a.a(Unknown Source:176)
    at kD.f.b(Unknown Source:125)
    at kD.g.a(Unknown Source:144)
    at kD.f.b(Unknown Source:125)
    at jD.i.f(Unknown Source:100)
    at jD.f.run(Unknown Source:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644)
    at java.lang.Thread.run(Thread.java:1012)
Caused by: android.security.KeyStoreException: Incompatible purpose (internal Keystore code: -3 message: system/security/keystore2/src/security_level.rs:310

Caused by:
    0: system/security/keystore2/src/enforcements.rs:563: the purpose is not authorized.
    1: Error::Km(r#INCOMPATIBLE_PURPOSE)) (public error code: 13 internal Keystore code: -3)
    at android.security.KeyStore2.getKeyStoreException(KeyStore2.java:416)
    at android.security.KeyStoreSecurityLevel.createOperation(KeyStoreSecurityLevel.java:122)
    at android.security.keystore2.AndroidKeyStoreCipherSpiBase.ensureKeystoreOperationInitialized(AndroidKeyStoreCipherSpiBase.java:355)
    ... 36 more
Could not find provider for algorithm: RSA/ECB/NoPadding

我们的应用程序中有基于证书的身份验证。在登录/注册期间,我们创建证书并将其存储到密钥库中。然后,我们通过 OkHttp 等方式使用证书...

删除 RASP 库解决了我们的安全端点问题。 这是初始化代码:

安全检测助手.kt

package com.xxx.lib.security.presentation

import android.content.Context
import com.aheaditec.talsec_security.security.api.Talsec
import com.aheaditec.talsec_security.security.api.TalsecConfig
import com.aheaditec.talsec_security.security.api.ThreatListener
import com.xxx.lib.BuildConfig.ANDROID_SUPPORT_MAIL
import com.xxx.lib.security.presentation.SecurityThreatDetectedError.Reason.DEBUGGER_DETECTED
import com.xxx.lib.security.presentation.SecurityThreatDetectedError.Reason.EMULATOR_DETECTED
import com.xxx.lib.security.presentation.SecurityThreatDetectedError.Reason.HOOK_DETECTED
import com.xxx.lib.security.presentation.SecurityThreatDetectedError.Reason.OBFUSCATION_ISSUES_DETECTED
import com.xxx.lib.security.presentation.SecurityThreatDetectedError.Reason.ROOT_DETECTED
import com.xxx.lib.security.presentation.SecurityThreatDetectedError.Reason.TAMPER_DETECTED
import com.xxx.lib.security.presentation.SecurityThreatDetectedError.Reason.UNTRUSTED_INSTALLATION_SOURCE_DETECTED

class SecurityDetectionHelper(
    private val context: Context,
) : ThreatListener.ThreatDetected, SecurityDetectionHelperInterface {

    private var onThreatDetected: (error: SecurityThreatDetectedError) -> Unit = {}
    private var isEnabled: Boolean = false

    private val supportedAlternativeStores = arrayOf(
        "dev.firebase.appdistribution",
    )

    private val expectedSigningCertificateHashBase64 = arrayOf(
        // App signing
        "xxx",
        // Upload key certificate
        "xxx",
        // Internal test certificate
        "xxx",
    )

    private val config: TalsecConfig
        get() = TalsecConfig(
            PACKAGE_NAME,
            expectedSigningCertificateHashBase64,
            ANDROID_SUPPORT_MAIL,
            supportedAlternativeStores,
            isEnabled,
        )

    override fun onRootDetected() {
        onThreatDetected(SecurityThreatDetectedError(ROOT_DETECTED))
    }

    override fun onDebuggerDetected() {
        onThreatDetected(SecurityThreatDetectedError(DEBUGGER_DETECTED))
    }

    override fun onEmulatorDetected() {
        onThreatDetected(SecurityThreatDetectedError(EMULATOR_DETECTED))
    }

    override fun onTamperDetected() {
        onThreatDetected(SecurityThreatDetectedError(TAMPER_DETECTED))
    }

    override fun onUntrustedInstallationSourceDetected() {
        onThreatDetected(SecurityThreatDetectedError(UNTRUSTED_INSTALLATION_SOURCE_DETECTED))
    }

    override fun onHookDetected() {
        onThreatDetected(SecurityThreatDetectedError(HOOK_DETECTED))
    }

    override fun onDeviceBindingDetected() {
        // do nothing
    }

    override fun onObfuscationIssuesDetected() {
        onThreatDetected(SecurityThreatDetectedError(OBFUSCATION_ISSUES_DETECTED))
    }

    override fun initSecurityDetection(isEnabled: Boolean, onThreatDetected: (error: SecurityThreatDetectedError) -> Unit) {
        this.onThreatDetected = onThreatDetected
        this.isEnabled = isEnabled
        ThreatListener(this).registerListener(context)
        Talsec.start(context, config)
    }

    companion object {
        private const val PACKAGE_NAME = "xxx"
    }
}

MainActivity.kt

class MainActivity : BaseActivity(R.layout.xxx_activity_main) {
    ...
    private val securityDetectionHelper: SecurityDetectionHelperInterface by inject()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        securityDetectionHelper.initSecurityDetection(THREAT_DETECTION_ENABLED, ::showAppBlockedDialog)
        ....
    }
    ...
}

我尝试:

  • 更改应用程序中我们的安全提供商的顺序:
    Security.insertProviderAt(BouncyCastleProvider(), 1)
  • 在 freeRASP 中排除一些库:
implementation (libs.talsecSecurityCommunity) {
    exclude group: 'com.squareup.okhttp3', module: 'okhttp'
    exclude group: 'org.bouncycastle'
}
android ssl okhttp bouncycastle android-keystore
1个回答
0
投票

freeRASP 识别并解决了其设备绑定检测控制与 TLS/SSL 之间的冲突。他们发现 AndroidKeyStore 存在问题,这可能会导致设备绑定检测错误。作为临时解决方案,他们发布了禁用设备绑定的特殊软件版本。

请使用以下依赖项:

implementation 'com.aheaditec.talsec.security:TalsecSecurity-Community:9.6.0-NO_DB'

请参阅https://github.com/talsec/Free-RASP-Android/issues/31了解详细信息

© www.soinside.com 2019 - 2024. All rights reserved.