如何修复 Proguard 删除 java.security 代码
How to fix Proguard removes java.security code
我在我的项目中使用 java.security.PublicKey
但是,当我启用 proguard 时,出现以下错误:
java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.String java.security.PublicKey.getAlgorithm()' on a null object reference
经过一番调查,我发现它落在
val entry = KeyStore.PrivateKeyEntry(keyPair.private, arrayOf(certificate)) <--- this line
keyStore.setEntry(alias, entry, keyProtection)
如何让它发挥作用?
将此添加到混淆器文件不起作用:
-keep class java.security.** { *; }
-keepclassmembers class java.security.** { *; }
-keep public interface java.security.Key {*;}
-keep public interface java.security.PublicKey {*;}
-keepclassmembers class * implements java.security.PublicKey {
public <methods>;
}
经过更多调查后,我发现 KeyStore.PrivateEntry() 的构造函数中更具体的一行导致了问题
它是
Certificate[] clonedChain = chain.clone();
clonedChain[0].publicKey is left null
如何让它也克隆 public 密钥?
问题是已弃用的代码。
我使用已弃用的 spongycastle 代码生成自签名证书。
在 proguard 上时,所述证书中的 public 密钥变为空。
我改成如下:
api 'com.madgag.spongycastle:core:1.58.0.0'
api 'com.madgag.spongycastle:prov:1.58.0.0'
api 'com.madgag.spongycastle:bcpkix-jdk15on:1.58.0.0'
api 'com.madgag.spongycastle:bcpg-jdk15on:1.58.0.0'
然后:
fun KeyPair.toSelfSignedCertificate(principal: String, signatureAlgorithm: String, validity: Int): X509Certificate? {
val x500Name = X500Name("CN=$principal")
val today = Calendar.getInstance()
val notBefore = today.timeInMillis
today.add(Calendar.YEAR, validity)
val notAfter = today.timeInMillis
val sigGen: ContentSigner = JcaContentSignerBuilder(signatureAlgorithm).build(private)
val publicKeyInfo = SubjectPublicKeyInfo.getInstance(ASN1Sequence.getInstance(public.encoded))
val certGen = X509v3CertificateBuilder(x500Name,
RSAKeyGenParameterSpec.F4,
Date(notBefore),
Date(notAfter),
x500Name,
publicKeyInfo)
val certHolder: X509CertificateHolder = certGen.build(sigGen)
return JcaX509CertificateConverter().getCertificate(certHolder)
}
而且效果很好。
我在我的项目中使用 java.security.PublicKey
但是,当我启用 proguard 时,出现以下错误:
java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.String java.security.PublicKey.getAlgorithm()' on a null object reference
经过一番调查,我发现它落在
val entry = KeyStore.PrivateKeyEntry(keyPair.private, arrayOf(certificate)) <--- this line
keyStore.setEntry(alias, entry, keyProtection)
如何让它发挥作用?
将此添加到混淆器文件不起作用:
-keep class java.security.** { *; }
-keepclassmembers class java.security.** { *; }
-keep public interface java.security.Key {*;}
-keep public interface java.security.PublicKey {*;}
-keepclassmembers class * implements java.security.PublicKey {
public <methods>;
}
经过更多调查后,我发现 KeyStore.PrivateEntry() 的构造函数中更具体的一行导致了问题
它是
Certificate[] clonedChain = chain.clone();
clonedChain[0].publicKey is left null
如何让它也克隆 public 密钥?
问题是已弃用的代码。
我使用已弃用的 spongycastle 代码生成自签名证书。 在 proguard 上时,所述证书中的 public 密钥变为空。
我改成如下:
api 'com.madgag.spongycastle:core:1.58.0.0'
api 'com.madgag.spongycastle:prov:1.58.0.0'
api 'com.madgag.spongycastle:bcpkix-jdk15on:1.58.0.0'
api 'com.madgag.spongycastle:bcpg-jdk15on:1.58.0.0'
然后:
fun KeyPair.toSelfSignedCertificate(principal: String, signatureAlgorithm: String, validity: Int): X509Certificate? {
val x500Name = X500Name("CN=$principal")
val today = Calendar.getInstance()
val notBefore = today.timeInMillis
today.add(Calendar.YEAR, validity)
val notAfter = today.timeInMillis
val sigGen: ContentSigner = JcaContentSignerBuilder(signatureAlgorithm).build(private)
val publicKeyInfo = SubjectPublicKeyInfo.getInstance(ASN1Sequence.getInstance(public.encoded))
val certGen = X509v3CertificateBuilder(x500Name,
RSAKeyGenParameterSpec.F4,
Date(notBefore),
Date(notAfter),
x500Name,
publicKeyInfo)
val certHolder: X509CertificateHolder = certGen.build(sigGen)
return JcaX509CertificateConverter().getCertificate(certHolder)
}
而且效果很好。