@@ -510,83 +510,80 @@ object PGPEncryptionHelper {
510510
511511 // 提取私钥(支持密码保护)
512512 android.util.Log .d(" PGPEncryptionHelper" , " Extracting private key, has password: ${password != null && password.isNotEmpty()} " )
513+ if (password != null && password.isNotEmpty()) {
514+ android.util.Log .d(" PGPEncryptionHelper" , " Password length: ${password.length} , password hash: ${password.hashCode()} " )
515+ }
513516 val passwordChars = password?.toCharArray() ? : " " .toCharArray()
517+
518+ // 尝试多个提供者策略,让 BouncyCastle 自动选择最佳实现
514519 val privateKey = try {
515- // 尝试使用BC提供者(虽然Android P+有限制,但某些操作可能仍可用)
520+ // 策略1: 不指定提供者,让 BouncyCastle 内部自动选择(推荐)
521+ // BouncyCastle 会根据可用性和算法支持自动选择合适的提供者
522+ android.util.Log .d(" PGPEncryptionHelper" , " Attempting to extract private key without explicit provider" )
516523 secretKey.extractPrivateKey(
517524 org.bouncycastle.openpgp.operator .jcajce.JcePBESecretKeyDecryptorBuilder ()
518- .setProvider( " BC " )
525+ // 不设置提供者,让 BouncyCastle 自动选择
519526 .build(passwordChars)
520527 ).also {
521- android.util.Log .d(" PGPEncryptionHelper" , " Successfully extracted private key using BC provider" )
528+ android.util.Log .d(" PGPEncryptionHelper" , " Successfully extracted private key using auto-selected provider" )
522529 }
523530 } catch (e: Exception ) {
524- android.util.Log .w(" PGPEncryptionHelper" , " Failed with BC : ${e.message} , trying AndroidOpenSSL " )
531+ android.util.Log .w(" PGPEncryptionHelper" , " Failed with auto provider : ${e.message} , trying BC explicitly " )
525532 try {
526- // 尝试AndroidOpenSSL
533+ // 策略2: 尝试明确使用 BC 提供者
527534 secretKey.extractPrivateKey(
528535 org.bouncycastle.openpgp.operator .jcajce.JcePBESecretKeyDecryptorBuilder ()
529- .setProvider(" AndroidOpenSSL " )
536+ .setProvider(" BC " )
530537 .build(passwordChars)
531538 ).also {
532- android.util.Log .d(" PGPEncryptionHelper" , " Successfully extracted private key using AndroidOpenSSL " )
539+ android.util.Log .d(" PGPEncryptionHelper" , " Successfully extracted private key using BC provider " )
533540 }
534541 } catch (e2: Exception ) {
535- android.util.Log .w(" PGPEncryptionHelper" , " Failed with AndroidOpenSSL : ${e2.message} , trying system default " )
542+ android.util.Log .w(" PGPEncryptionHelper" , " Failed with BC : ${e2.message} , trying Conscrypt " )
536543 try {
537- // 尝试不指定提供者,使用系统默认
538- secretKey.extractPrivateKey(
539- org.bouncycastle.openpgp.operator .jcajce.JcePBESecretKeyDecryptorBuilder ()
540- // 不设置提供者,让系统自动选择
541- .build(passwordChars)
542- ).also {
543- android.util.Log .d(" PGPEncryptionHelper" , " Successfully extracted private key using system default provider" )
544+ // 策略3: 尝试 Conscrypt 提供者(如果可用)
545+ val conscryptProvider = Security .getProvider(" Conscrypt" )
546+ if (conscryptProvider != null ) {
547+ android.util.Log .d(" PGPEncryptionHelper" , " Conscrypt provider found, attempting to use it" )
548+ secretKey.extractPrivateKey(
549+ org.bouncycastle.openpgp.operator .jcajce.JcePBESecretKeyDecryptorBuilder ()
550+ .setProvider(" Conscrypt" )
551+ .build(passwordChars)
552+ ).also {
553+ android.util.Log .d(" PGPEncryptionHelper" , " Successfully extracted private key using Conscrypt provider" )
554+ }
555+ } else {
556+ throw Exception (" Conscrypt provider not available" )
544557 }
545558 } catch (e3: Exception ) {
546- android.util.Log .e(" PGPEncryptionHelper" , " Failed to extract private key with password: ${e3.message} " , e3)
547- // 检查是否是密码错误(checksum mismatch 通常表示密码错误)
548- val isPasswordError = e3.message?.contains(" checksum" ) == true ||
549- e3.message?.contains(" mismatch" ) == true ||
550- e3.message?.contains(" wrong" ) == true
551-
552- // 如果密码错误,尝试空密码(向后兼容)
553- if (password != null && password.isNotEmpty() && isPasswordError) {
554- android.util.Log .d(" PGPEncryptionHelper" , " Checksum mismatch detected, trying with empty password (password may be incorrect)" )
555- try {
556- secretKey.extractPrivateKey(
557- org.bouncycastle.openpgp.operator .jcajce.JcePBESecretKeyDecryptorBuilder ()
558- .setProvider(" BC" )
559- .build(" " .toCharArray())
560- ).also {
561- android.util.Log .d(" PGPEncryptionHelper" , " Extracted with empty password using BC" )
562- }
563- } catch (e4: Exception ) {
564- android.util.Log .w(" PGPEncryptionHelper" , " Failed with empty password and BC: ${e4.message} , trying AndroidOpenSSL" )
565- try {
566- secretKey.extractPrivateKey(
567- org.bouncycastle.openpgp.operator .jcajce.JcePBESecretKeyDecryptorBuilder ()
568- .setProvider(" AndroidOpenSSL" )
569- .build(" " .toCharArray())
570- ).also {
571- android.util.Log .d(" PGPEncryptionHelper" , " Extracted with empty password using AndroidOpenSSL" )
572- }
573- } catch (e5: Exception ) {
574- android.util.Log .w(" PGPEncryptionHelper" , " Failed with empty password and AndroidOpenSSL: ${e5.message} , trying system default" )
575- secretKey.extractPrivateKey(
576- org.bouncycastle.openpgp.operator .jcajce.JcePBESecretKeyDecryptorBuilder ()
577- // 不设置提供者
578- .build(" " .toCharArray())
579- ).also {
580- android.util.Log .d(" PGPEncryptionHelper" , " Extracted with empty password using system default" )
581- }
582- }
559+ android.util.Log .w(" PGPEncryptionHelper" , " Failed with Conscrypt: ${e3.message} , trying AndroidOpenSSL" )
560+ try {
561+ // 策略4: 尝试 AndroidOpenSSL(虽然可能不支持 CFB 模式)
562+ secretKey.extractPrivateKey(
563+ org.bouncycastle.openpgp.operator .jcajce.JcePBESecretKeyDecryptorBuilder ()
564+ .setProvider(" AndroidOpenSSL" )
565+ .build(passwordChars)
566+ ).also {
567+ android.util.Log .d(" PGPEncryptionHelper" , " Successfully extracted private key using AndroidOpenSSL" )
583568 }
584- } else {
585- // 如果是密码错误,提供更明确的错误信息
569+ } catch (e4: Exception ) {
570+ android.util.Log .e(" PGPEncryptionHelper" , " All provider attempts failed. Last error: ${e4.message} " , e4)
571+ // 检查是否是密码错误(checksum mismatch 通常表示密码错误)
572+ val isPasswordError = e4.message?.contains(" checksum" , ignoreCase = true ) == true ||
573+ e4.message?.contains(" mismatch" , ignoreCase = true ) == true ||
574+ e4.message?.contains(" wrong" , ignoreCase = true ) == true ||
575+ e2.message?.contains(" checksum" , ignoreCase = true ) == true ||
576+ e2.message?.contains(" mismatch" , ignoreCase = true ) == true
577+
578+ android.util.Log .e(" PGPEncryptionHelper" , " Password error detected: $isPasswordError " )
579+ android.util.Log .e(" PGPEncryptionHelper" , " BC error: ${e2.message} " )
580+ android.util.Log .e(" PGPEncryptionHelper" , " Final error: ${e4.message} " )
581+
582+ // 如果是密码错误,提供明确的错误信息
586583 if (isPasswordError) {
587- throw Exception (" 私钥密码错误,请检查输入的密码是否正确" )
584+ throw Exception (" 私钥密码错误,请检查输入的密码是否正确。如果密码确实正确,可能是密钥格式不兼容。 " )
588585 } else {
589- throw Exception (" 私钥密码错误或私钥未加密。 错误信息: ${e3 .message} " )
586+ throw Exception (" 无法提取私钥。可能的原因:1) 密码错误 2) 密钥格式不兼容 3) 系统加密提供者限制。 错误信息: ${e4 .message} " )
590587 }
591588 }
592589 }
@@ -596,26 +593,47 @@ object PGPEncryptionHelper {
596593 // 创建解密器
597594 android.util.Log .d(" PGPEncryptionHelper" , " Creating data decryptor factory" )
598595 val dataDecryptorFactory = try {
599- // 首先尝试AndroidOpenSSL
596+ // 策略1: 不指定提供者,让 BouncyCastle 自动选择(推荐)
597+ // 这样可以避免 AndroidOpenSSL 不支持 CFB 模式的问题
598+ android.util.Log .d(" PGPEncryptionHelper" , " Attempting to create decryptor factory without explicit provider" )
600599 org.bouncycastle.openpgp.operator .jcajce.JcePublicKeyDataDecryptorFactoryBuilder ()
601- .setProvider( " AndroidOpenSSL " )
600+ // 不设置提供者,让 BouncyCastle 自动选择支持 CFB 的提供者
602601 .build(privateKey)
603602 } catch (e: Exception ) {
604- android.util.Log .w(" PGPEncryptionHelper" , " Failed with AndroidOpenSSL, trying system default : ${e.message} " )
603+ android.util.Log .w(" PGPEncryptionHelper" , " Failed with auto provider : ${e.message} , trying BC explicitly " )
605604 try {
606- // 尝试系统默认提供者
607- org.bouncycastle.openpgp.operator .jcajce.JcePublicKeyDataDecryptorFactoryBuilder ()
608- // 不设置提供者,让系统自动选择
609- .build(privateKey)
610- } catch (e2: Exception ) {
611- android.util.Log .w(" PGPEncryptionHelper" , " Failed with system default, trying BC: ${e2.message} " )
612- // 最后尝试BC(可能在某些设备上可用)
605+ // 策略2: 尝试明确使用 BC 提供者(通常支持 CFB 模式)
613606 org.bouncycastle.openpgp.operator .jcajce.JcePublicKeyDataDecryptorFactoryBuilder ()
614607 .setProvider(" BC" )
615608 .build(privateKey)
609+ } catch (e2: Exception ) {
610+ android.util.Log .w(" PGPEncryptionHelper" , " Failed with BC: ${e2.message} , trying Conscrypt" )
611+ try {
612+ // 策略3: 尝试 Conscrypt 提供者(如果可用)
613+ val conscryptProvider = Security .getProvider(" Conscrypt" )
614+ if (conscryptProvider != null ) {
615+ android.util.Log .d(" PGPEncryptionHelper" , " Conscrypt provider found, attempting to use it" )
616+ org.bouncycastle.openpgp.operator .jcajce.JcePublicKeyDataDecryptorFactoryBuilder ()
617+ .setProvider(" Conscrypt" )
618+ .build(privateKey)
619+ } else {
620+ throw Exception (" Conscrypt provider not available" )
621+ }
622+ } catch (e3: Exception ) {
623+ android.util.Log .w(" PGPEncryptionHelper" , " Failed with Conscrypt: ${e3.message} , trying AndroidOpenSSL as last resort" )
624+ // 策略4: 最后尝试 AndroidOpenSSL(虽然可能不支持 CFB,但作为最后备选)
625+ try {
626+ org.bouncycastle.openpgp.operator .jcajce.JcePublicKeyDataDecryptorFactoryBuilder ()
627+ .setProvider(" AndroidOpenSSL" )
628+ .build(privateKey)
629+ } catch (e4: Exception ) {
630+ android.util.Log .e(" PGPEncryptionHelper" , " All decryptor factory attempts failed" , e4)
631+ throw Exception (" 无法创建解密器。可能的原因:系统不支持所需的加密算法(AES/CFB模式)。错误信息: ${e4.message} " )
632+ }
633+ }
616634 }
617635 }
618- android.util.Log .d(" PGPEncryptionHelper" , " Created data decryptor factory" )
636+ android.util.Log .d(" PGPEncryptionHelper" , " Created data decryptor factory successfully " )
619637
620638 // 解密数据 - 使用PGPPublicKeyEncryptedData
621639 val publicKeyEncryptedDataForDecrypt = publicKeyEncryptedData
@@ -668,4 +686,5 @@ object PGPEncryptionHelper {
668686 throw Exception (" 解密失败: ${e.message} " , e)
669687 }
670688 }
689+
671690}
0 commit comments