Android与Ant签署

使用Ant,我试图在发布模式下构build一个Android应用程序进行分发。 我的问题是在签字过程中。 我使用“导出Android应用程序”向导通过Eclipse创build了一个密钥仓库和别名,如果通过Eclipse导出应用程序,该应用程序将被正确签名。 当我尝试通过Ant完成相同的过程时,我在我的build.properties文件中引用了我的keystore和别名:

key.store=C:\\Users\\a512091\\.android\\release.keystore key.alias=application key.store.password=android key.alias.password=android 

构build过程是成功的,我得到一个Application-release.apk文件。 我非常喜欢这个APK与jarsigner和所有文件都有“sm”标签。 这是输出的尾部:

 jar verified. Warning: This jar contains entries whose certificate chain is not validated. 

当我尝试将这个APK安装到模拟器或设备时,我得到以下内容:

 Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES] 

Logcat显示我的CSS文件和图像资产的签名问题:

 11-07 11:06:20.060: WARN/PackageParser(58): Exception reading assets/www/css/base.css in /data/app/vmdl48898.tmp 11-07 11:06:20.060: WARN/PackageParser(58): java.lang.SecurityException: META-INF/XXXXX.SF has invalid digest for assets/www/res/droidhdpi/favorite_off.png in /data/app/vmdl48898.tmp 11-07 11:06:20.060: WARN/PackageParser(58): at java.util.jar.JarVerifier.verifyCertificate(JarVerifier.java:369) 11-07 11:06:20.060: WARN/PackageParser(58): at java.util.jar.JarVerifier.readCertificates(JarVerifier.java:272) 11-07 11:06:20.060: WARN/PackageParser(58): at java.util.jar.JarFile.getInputStream(JarFile.java:392) 11-07 11:06:20.060: WARN/PackageParser(58): at android.content.pm.PackageParser.loadCertificates(PackageParser.java:337) 11-07 11:06:20.060: WARN/PackageParser(58): at android.content.pm.PackageParser.collectCertificates(PackageParser.java:508) 11-07 11:06:20.060: WARN/PackageParser(58): at com.android.server.PackageManagerService.installPackageLI(PackageManagerService.java:5885) 11-07 11:06:20.060: WARN/PackageParser(58): at com.android.server.PackageManagerService.access$2100(PackageManagerService.java:134) 11-07 11:06:20.060: WARN/PackageParser(58): at com.android.server.PackageManagerService$5.run(PackageManagerService.java:4743) 11-07 11:06:20.060: WARN/PackageParser(58): at android.os.Handler.handleCallback(Handler.java:587) 11-07 11:06:20.060: WARN/PackageParser(58): at android.os.Handler.dispatchMessage(Handler.java:92) 11-07 11:06:20.060: WARN/PackageParser(58): at android.os.Looper.loop(Looper.java:123) 11-07 11:06:20.060: WARN/PackageParser(58): at android.os.HandlerThread.run(HandlerThread.java:60) 11-07 11:06:20.069: ERROR/PackageParser(58): Package com.xxxxx.xxxxx has no certificates at entry assets/www/css/base.css; ignoring! 

如果您有Ant版本<1.8.3( ant -version ),请尝试以下方法解决JDK 7的问题(基于上一个答案):

  1. 将signjarjdk7添加到ANDROID_SDK \ tools \ ant \ build.xml

     <macrodef name="signjarjdk7"> <attribute name="jar" /> <attribute name="signedjar" /> <attribute name="keystore" /> <attribute name="storepass" /> <attribute name="alias" /> <attribute name="keypass" /> <attribute name="verbose" /> <sequential> <exec executable="jarsigner" failonerror="true"> <!-- Magic key, always verbose --> <arg line="-verbose -digestalg SHA1 -sigalg MD5withRSA" /> <arg line="-keystore @{keystore} -storepass @{storepass} -keypass @{keypass}" /> <arg line="-signedjar &quot;@{signedjar}&quot;" /> <arg line="&quot;@{jar}&quot; @{alias}" /> </exec> </sequential> </macrodef> 
  2. 'signjar'replace为同一个build.xml中的'release'目标中的'signjarjdk7'

注:您必须为您的项目(在project.properties或local.properties中)定义“key.store.password”“key.alias.password” propeties。

更新1:

如果你已经安装了Ant 1.8.3(或更高版本),你有一个更好的解决scheme:

打开你的ANDROID_SDK \ tools \ ant \ build.xml并在原始的“signjar”调用中添加两个新的参数 – sigalg和digestalg –

 <signjar sigalg="MD5withRSA" digestalg="SHA1" jar="${out.packaged.file}" signedjar="${out.unaligned.file}" keystore="${key.store}" storepass="${key.store.password}" alias="${key.alias}" keypass="${key.alias.password}" verbose="${verbose}" /> 

更新2:似乎这个答案已被弃用,最新版本的Android SDK工具中的“signjar”被replace为“signapk”。

听起来您可能正在使用JDK 7(1.7.0),所以尝试使用jarsigner签名时添加这些选项:

 -digestalg SHA1 -sigalg MD5withRSA 

根据Android开发者文档 ,您应该将这些属性放在ant.properties文件中:

 $ cat ant.properties key.store=C:\\Users\\a512091\\.android\\release.keystore key.alias=application key.store.password=android key.alias.password=android 

长期的解决scheme是修补Ant的签名任务:

https://issues.apache.org/bugzilla/show_bug.cgi?id=52344

新的属性被添加到Ant 1.8.3的签名中,但是Android的构build脚本(从r19开始)还没有被修改来使用它们:

http://code.google.com/p/android/issues/detail?id=19567

同时,“presetdef”可能会提供一个解决方法:

  <presetdef name="signjar"> <signjar sigalg="MD5withRSA" digestalg="SHA1" /> </presetdef> 

使用Ubuntu 14.04 (Trusty Tahr)和Windows,创build一个“.keystore”文件。

这个文件需要被生成,这可以通过Java自带的keytool命令来完成。 它通常可以在'C:\ Program Files \ Java \ jre7 \ bin'中find。 还必须将其添加到PATHvariables中。

转到您的项目的根目录并使用此命令:

生成.keystore文件:

 $ keytool -genkey -v -keystore key-name.keystore -alias alias-name -keyalg RSA -keysize 2048 -validity 10000 

在“platforms / android /”ant.properties文件夹中创build一个名为ant.properties的文件。

 key.store=D:\\path\\to\\the\\project\\keyname.keystore key.alias=alias-name 

创build构buildAPK文件:

 $ cordova build android --release 

如果您的版本比1.8.3和Java 7版本的老版本卡住了(比如我),下面是一个解决方法:

 <exec executable="${java.bin.path}/jarsigner"> <arg value="-signedjar"/> <arg value="signed-${app.apk.name}"/> <arg value="-keystore"/> <arg value="my.keystore"/> <arg value="-storepass"/> <arg value="passwd"/> <arg value="-sigalg"/> <arg value="MD5withRSA"/> <arg value="-digestalg"/> <arg value="SHA1"/> <arg value="${app.apk.name}"/> <arg value="my_keystore"/> </exec> <!-- Where old version was: --> <signjar alias="my_keystore" keystore="my.keystore" storepass="passwd" preservelastmodified="true" signedjar="signed-${app.apk.name}"> <path> <fileset dir="." includes="${app.apk.name}" /> </path> </signjar>