签名Android应用程序会引发IOException:找到冗余长度字节

k4emjkb1  于 2023-03-06  发布在  Android
关注(0)|答案(7)|浏览(88)

我们正在开发Cordova应用程序,在签署Android版本的应用程序时遇到困难。
使用以下命令

jarsigner -keystore keystore.p12 -storetype pkcs12 android-release-unsigned.apk 1

给出以下异常

java.io.IOException: DerInputStream.getLength(): Redundant length bytes found

它来自OpenJDK apparently中的这一行,添加它是为了修复CVE-2016-5546,尽管我对加密的了解不足以真正理解它。
用openssl导出证书并创建一个新的p12,这样可以正常工作,但会更改签名,这意味着play store会拒绝上传。
我们的密钥库来自另一家公司,我们最初外包的应用程序开发。
任何jarsigner或keytool命令都会抛出相同的异常,我认为这是有意义的,因为它们都使用相同的Javalib

tvz2xvvm

tvz2xvvm1#

在很多情况下,问题出在Java版本上。如果你有旧的PKCS12.p12文件(像我的),你需要Java6来读取它。旧的密钥使用较弱的加密,我认为是1024位加密。
因此,只需像这样使用keytool命令行(我需要获得SHA1密钥):

"C:\Program Files\Java\jdk1.6.0_45\bin\keytool" -exportcert -keystore cert.p12 -storepass <yourpass> -list -v -storetype PKCS12
wtzytmuj

wtzytmuj2#

我们也遇到过同样的问题,我们发现JDK 1.8.0_112没有你说的bug,所以我们是这样解决的:
首先,我们使用以下命令(Java\jdk1.8.0_112\bin\keytool.exe)将temp_keystore.p12转换为mycert.keystore

keytool -importkeystore -srckeystore temp_keystore.p12 -destkeystore mycert.keystore -srcstoretype pkcs12

然后使用以下命令(Java\jdk1.8.0_112\bin\jarsigner.exe)

jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore mycert.keystore ReadyForSigning.apk 1

以签署apk。(命令末尾的“1“是别名)
PS.:从.p12转换到.keystore可能没有必要。

fcipmucu

fcipmucu3#

我花了几个小时来寻找这个问题的解决方案。尝试了五种不同的JDK,都没有效果。我从以前的开发者那里"继承"了一个非常流行的Playstore应用程序的旧PKCS12证书,JDK 8 + 9不会使用它。Olexandr的解决方案也没有帮助。
最后,几乎是靠运气,我设法找到了一个解决方案here,Weijung Wang的回答。它涉及到使用openssl导出和重新导入证书。然后我重新导入了JKS密钥库中的P12密钥库,现在它可以在JDK 8上工作。
引用:
王伟军添加评论-2017 - 02 - 28 15:55
Openssl可以在提取私钥时删除多余的0。我们可以使用以下两个命令来规范化受影响的pkcs12文件:

  1. openssl pkcs12-输入pkcs12-文件-输出密钥和证书-节点-传入传入:abcXYZ
  2. openssl pkcs12-输入密钥和证书-导出-输出新的pkcs12-文件-传递传递:abcXYZ
omtl5h9j

omtl5h9j4#

我也遇到过同样的错误,Olexandr的解决方案不起作用,因为在JDK8(更新151)上使用keytool会在阅读证书时抛出错误,证书是用JDK7生成的。根据Anders的回答,使用OpenSSL可以(粘贴命令行以供将来参考):

openssl pkcs12 -in android.p12 -out android_fixed.cert -nodes -passin pass:your_p12_password
openssl pkcs12 -in android_fixed.cert -export -out android_cert.p12 -passout pass:your_p12_password
goqiplq2

goqiplq25#

我使用JDK 6生成了密钥库。作为解决方法,我一直使用JDK 1.8.0_112,方法是在[Project Structure] - [SDK Location] - [JDK location]下设置JDK。
我已经解决了以下步骤(使用macOS)。
使用JDK 1.8.0_112转换为PKCS 12

/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home/bin/keytool -importkeystore -srckeystore original.keystore -destkeystore 1.8.0_112.p12 -deststoretype PKCS12 -storepass ***** -destkeypass *****

使用OpenSSL进行处理(感谢Weijung Wang和Anders Emil)

openssl pkcs12 -in 1.8.0_112.p12 -out 1.8.0_112.cert -nodes -passin pass:*****
openssl pkcs12 -in 1.8.0_112.cert -export -out 1.8.0_112.export.p12 -passout pass:*****

使用JDK 1.8.0_161转换为JKS。
这里我需要指定-destkeypass、-srcalias和-destalias。注意,在openSSL命令之后,别名是“1”,因此需要设置别名。

/Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home/bin/keytool -importkeystore -srckeystore 1.8.0_112.export.p12 -srcstoretype pkcs12 -destkeystore 1.8.0_112.keystore -deststoretype jks -deststorepass ***** -destkeypass ***** -srcalias 1 -destalias youralias

所以指纹的结果是这样的。

Original keystore:
     SHA1: 6C:9E:...:C5:8A

Original apk:
     SHA1: DA:4C:...:3F:02

Modified keystore:
     SHA1: C8:4A:...:2A:23

Modified apk:
     SHA1: DA:4C:...:3F:02
ecfsfe2w

ecfsfe2w6#

@Water的解决方案对我不起作用,生成的apk签名和原来的不一样。
我终于得到了它的工作升级到谷歌的新应用程序签名上传的私钥与pepk工具生成,并要求他们的支持重置上传密钥.

yh2wf1be

yh2wf1be7#

我找到了一个很棒的解决方案
因为这个原因,我也手动签署了我的APK,但现在Google要求targetSDK=30,它也要求使用V2签名方案。这是我不知道如何手动完成的事情。
但我找到了一个解决办法!
只需在文件-〉项目结构-〉JDK位置中将Android Studio使用的JDK设置为稍旧的内容即可。默认情况下,它使用其嵌入式JDK,但您可以将其指向任何内容。例如,我使用的是1.8.0_45。现在,我可以再次直接使用构建-〉生成已签名的APK来处理我的旧“损坏”密钥库!
有一天Android Studio可能会再次需要最新的“bug”JDK,但现在我已经准备好了。

相关问题