一、生成金钥文件

创建私钥命令:
keytool -genkey -keystore <path>.keystore -keyalg RSA -validity <days> -alias <private key>
该命令位于jdk安装目录的bin目录下,用于创建签名用的私钥。
其中:
-genkey 表示创建私钥。
-keystore 后面跟私钥仓库的名称,如果指定的仓库不存在,则创建一个新的仓库文件。
-keyalg 表示加密方式,一般跟RSA即可。
-validity 表示有效期限,单位为天,可以指定36500,即100年。
-alias 表示要添加的私钥名称,这个名称会被添加并存储到仓库文件中。
命令执行后,需要再输入一些信息,最后输入Y确认。
其中涉及到两个密码,一个是私钥仓库的密码,一个是具体私钥的密码,可以相同。
当输入完私钥的密码后,命令执行完成。

签名命令:
jarsigner -verbose -keystore <path>.keystore -signedjar <signed>.apk <unsigned>.apk <private key>
该命令位于jdk安装目录的bin目录下,用于使用私钥对未签名APK进行签名。
其中:
-verbose 表示输出相关信息。
-keystore 后面跟签名时使用的私钥所在的仓库文件。
-signedjar 表示对文件进行签名,后面跟三个参数:
第一个为签名后的文件名。
第二个为未签名的文件名,可以使用Eclipse的插件Android Tools导出未签名APK。
第三个是使用的私钥名称。
命令执行后,需要输入相关密码,然后输出相关信息,直到命令结束。
另外需要注意的是,如果是JDK1.7的版本,需要在签名命令后边添加如下参数:
-digestalg SHA1 -sigalg MD5withRSA
否则,最后签名的APK不能被安装,会提示以下错误:
Failure [INSTALL_PARSE_FAILED_NO_CERTIFICATES]

对齐优化命令:
zipalign -v 4 <unaligned>.apk <aligned>.apk
该命令位于sdk安装目录下的tools目录下,用于对已签名APK进行对齐优化。
其中:
-v 表示对齐的字节数,一般指定为4即可。
后面紧跟的两个参数分别为未对齐优化的文件名和优化后的文件名。
对已签名文件进行对齐优化后,可以得到更好的执行速度。


Eclipse下使用ADT插件进行图形化的签名相关的操作

生成签名的APK:
该过程将包含生成私钥仓库、生成私钥、打包APK、为APK签名、对APK对齐优化等一系列操作。
Android工程目录下的bin目录下,由Eclipse自动生成的APK文件是使用了默认的debug签名的。
使用该方式签名的apk可以安装到设备上,但是不同的环境,可能debug签名不同,并不通用。
而且,debug签名的APK无法发布到Market上。
可以用如下方式导出一个APK并进行签名:
工程->右键->Export->Android->Export Android Application...
或者
工程->右键->Android Tools->Export Signed Application Package...
在打开的窗口中,如果想要修改导出的工程,可以点击Browse进行修改。点击Next继续。
这里有两个选项:
Use existing keystore 使用既存的私钥仓库文件。
Create new keystore 创建一个新的私钥仓库文件。
一般的,如果已经创建了一个仓库文件,选择第一项即可,否则,需要选择第二项,创建一个新的仓库文件。
1、创建一个新的仓库文件:
Location 私钥仓库文件的保存位置。
Password 私钥仓库的密码。
Confirm 再次确认私钥仓库的密码。
2、使用已有的仓库文件:
Location 既存私钥仓库文件的位置。
Password 既存私钥仓库的密码。
点击Next继续。
这里又有两个选项:
Use existing key 使用已经存在的私钥对APK进行签名。
Create new key 创建一个新的私钥用于对APK进行签名。
1、创建一个新的私钥:
选中Create new key后,点击Next继续。
在打开的窗口中,输入相关参数,其中:
Alias 私钥名称。
Password 私钥的密码。
Confirm 再次确认私钥密码。
Validity (years) 有效期,单位是年,与命令行执行时的单位不同。
下面的可选参数里,必须有一项不为空,其它可选参数可以不填。
2、使用已有的私钥:
Alias 下拉列表里会列出私钥仓库文件里存在的私钥,选择想要使用的私钥。
Password 输入选择的私钥对应的密码。
点击Next继续。
在新窗口中,选择签名后的文件保存的位置,点击Finish完成上述所有操作。

生成未签名的APK:
使用命令的方式对APK进行签名,该APK必须是未签名的。
如果对已签名文件进行再签名,不会成功。如下方式可以得到一个未签名的APK:
工程->右键->Android Tools->Export Unsigned Application Package...

另外,新的ADT会在工程目录下生成proguard.cfg文件,使用它可以在签名时混淆代码。
混淆代码可以加大反编译代码后的理解难度,起到保护代码的作用。
使用方法是,修改工程目录下的project.properties文件,在最后添加:
proguard.config=proguard.cfg


转自http://hi.baidu.com/gaogaf/item/8757c356ef718e9408be1777


代码混淆时出现的异常解决方法

情况1:

Proguard returned with error code 1. See console

Error: C:/Documents (系统找不到指定文件)

这个是因为有空格引起的,proguard进行发编译的时候是不允许有空格的。所以要注意工程所放位置是否有空格。

如果换了正确路径还不好用的话,直接删除proguard就好了

注意:SDK和程序路径最好不要有空格符


情况2:

Proguard returned with error code 1. See console

异常:

java.lang.ArrayIndexOutOfBoundsException

解决办法:将proguard.cfg中的"-dontpreverify"改成“-dontoptimize”

把项目中生成的proguard文件夹(此时文件夹是空的)删掉,然后再重新运行项目,就OK 了。


情况3:

[2011-10-21 13:22:32 - ZMKSMarket_Build_v1.0] Proguard returned with error code 1. See console

[2011-10-21 13:22:32 - ZMKSMarket_Build_v1.0] java.io.IOException: Can't read proguard.ClassPathEntry@106082

[2011-10-21 13:22:32 - ZMKSMarket_Build_v1.0] at proguard.InputReader.readInput(InputReader.java:230)

[2011-10-21 13:22:32 - ZMKSMarket_Build_v1.0] at proguard.InputReader.readInput(InputReader.java:200)

[2011-10-21 13:22:32 - ZMKSMarket_Build_v1.0] at proguard.InputReader.readInput(InputReader.java:178)

[2011-10-21 13:22:32 - ZMKSMarket_Build_v1.0] at proguard.InputReader.execute(InputReader.java:100)

[2011-10-21 13:22:32 - ZMKSMarket_Build_v1.0] at proguard.ProGuard.readInput(ProGuard.java:195)

[2011-10-21 13:22:32 - ZMKSMarket_Build_v1.0] at proguard.ProGuard.execute(ProGuard.java:78)

[2011-10-21 13:22:32 - ZMKSMarket_Build_v1.0] at proguard.ProGuard.main(ProGuard.java:499)


抛出这样的异常的原因是第三方jar的引用路径不对,没有找到这个需要忽略混淆的jar包。


仔细想了一下,我的是直接保存的,保存路径里确实没出现空格,最符合我的应该就是第三种情况了,(因为自己这报出的错和上面的不大一样,所以只好分析下了)。混淆,难道是我之前那里不对?

想到自己写的程序是可以运用到4.0的,因为2.3的和4.0的总归不一样了,就想是不是这里出现什么差错了,所以直接尝试找4.0的是怎么混淆:

其实Android 4.0要用ProGuard比2.3更简单:在Eclipse中打开工程目录下的project.properties文件,该文件中有以下两行:


To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):


proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt


根据这段说明,只要将proguard.config前面的#去掉,就可以利用ProGuard来混淆代码了!当然,默认的设置是不带优化功能的,可以用以下设置来加上代码优化功能:

proguard.config=${sdk.dir}/tools/proguard/proguard-android-optimize.txt:proguard-project.txt

然后只要经过数字签名之类的编译后,代码就是混淆的了。

注意:如果用Eclipse里的Run或Build Project/Build All来生成Apk,是不会混淆代码的

情况四

conversion to dalvik format failed with error 1

更新一下tools就可以了


命令行jarsigner签字和解决找不到证书链错误

1、签名失败


$jarsigner -verbose -keystore /Volumes/Study/resourcesLib/Qunero-achivements/AndroidApp/QuLordy-signed-key -signedjar ./signed_XiaomiVerify.apk ./XiaomiVerify.apk qulordy输入密钥库的口令短语: jarsigner: 找不到 qulordy 的证书链。qulordy 必须引用包含专用密钥和相应的公共密钥证书链的有效密钥库密钥条目。

2、查看帮助


复制代码

$jarsigner -h

用法:jarsigner [选项] jar 文件别名(key的别名)

      jarsigner -verify [选项] jar 文件


[-keystore <url>]           密钥库位置


[-storepass <口令>]         用于密钥库完整性的口令


[-storetype <类型>]         密钥库类型


[-keypass <口令>]           专用密钥的口令(如果不同)


[-sigfile <文件>]           .SF/.DSA 文件的名称


[-signedjar <文件>]         已签名的 JAR 文件的名称


[-digestalg <算法>]    摘要算法的名称


[-sigalg <算法>]       签名算法的名称


[-verify]                   验证已签名的 JAR 文件


[-verbose]                  签名/验证时输出详细信息


[-certs]                    输出详细信息和验证时显示证书


[-tsa <url>]                时间戳机构的位置


[-tsacert <别名>]           时间戳机构的公共密钥证书


[-altsigner <类>]           替代的签名机制的类名


[-altsignerpath <路径列表>] 替代的签名机制的位置


[-internalsf]               在签名块内包含 .SF 文件


[-sectionsonly]             不计算整个清单的散列


[-protected]                密钥库已保护验证路径


[-providerName <名称>]      提供者名称


[-providerClass <类>        加密服务提供者的名称

 [-providerArg <参数>]] ... 主类文件和构造函数参数

172323304.png


4、重新签名:

复制代码

$jarsigner -verbose -keystore /Volumes/Study/resourcesLib/Qunero-achivements/AndroidApp/QuLordy-signed-key -signedjar ./signed_XiaomiVerify.apk ./XiaomiVerify.apk 'qulordy key'

输入密钥库的口令短语:

  正在添加: META-INF/MANIFEST.MF

  正在添加: META-INF/QULORDY_.SF

  正在添加: META-INF/QULORDY_.RSA

 正在签名: AndroidManifest.xml

 正在签名: classes.dex

  正在添加: res/

  正在添加: res/drawable/

 正在签名: res/drawable/icon.png

  正在添加: res/layout/

 正在签名: res/layout/main.xml

 正在签名: resources.arsc

来自:http://www.cnblogs.com/QuLory/p/3141039.html


最近1个项目中 需要导入移动MM的第三方计费包,混淆时用到了如下脚本,可屏蔽警告,不混淆第三方包指定内容。

非常有效


proguard.cfg 文件


-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-ignorewarnings //这1句是屏蔽警告,脚本中把这行注释去掉
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

//这1句是导入第三方的类库,防止混淆时候读取包内容出错,脚本中把这行注释去掉

-libraryjars libs/mmbilling.jar

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService

-keepclasseswithmembernames class * {
   native <methods>;
}

-keepclasseswithmembernames class * {
   public <init>(android.content.Context, android.util.AttributeSet);
}

-keepclasseswithmembernames class * {
   public <init>(android.content.Context, android.util.AttributeSet, int);
}

-keepclassmembers enum * {
   public static **[] values();
   public static ** valueOf(java.lang.String);
}

-keep class * implements android.os.Parcelable {
 public static final android.os.Parcelable$Creator *;
}


//这4句是不混淆第三方包中的指定内容,脚本中把这行注释去掉

-keep class com.ccit.** {*; }  
-keep class ccit.** { *; }
-keep class com.aspire.**
-keep class mm.vending.**