昨天看了一下Android中的签名机制,这里介绍一下Android中签名用的Key的产生方法和签名的原理。
产生Key
o 产生RSA私钥(private key)
openssl genrsa -3 -out testkey.pem 2048
-3 是算法的参数(public exponent)。
2048 是私钥长度。
testkey.pem 是输出的文件。
o 产生PKCS#10格式的认证请求。所谓认证请求就是发给认证机构认证的一个请求,它主要包括一个公钥和一些相关信息(如组织名称和联系人邮件地址)。
openssl req -new -x509 -key testkey.pem -out testkey.x509.pem -days 10000 /
-subj ‘/C=US/ST=California/L=Mountain [email protected].com’
如果不提供最后两个参数,openssl会提示你输入相关信息,这里的信息可以根据你自己的实际情况填写。如:
openssl req -new -x509 -key testkey.pem -out testkey.x509.pem -days 10000
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter ‘.’, the field will be left blank.
—–
Country Name (2 letter code) [GB]:CN
State or Province Name (full name) [Berkshire]:GuangDong
Locality Name (eg, city) [Newbury]:ShenZhen
Organization Name (eg, company) [My Company Ltd]:Topwise
Organizational Unit Name (eg, section) []:Broncho
Common Name (eg, your name or your server’s hostname) []:broncho.cn
Email Address []:[email protected]
o 把私钥的格式转换成PKCS #8(Private-Key Information Syntax Standard.)
openssl pkcs8 -in testkey.pem -topk8 -outform DER -out testkey.pk8 -nocrypt
私钥是不能让别人知道的,否则就起不到保密的作用了。私钥通常是要加密保存的,但这里指定了-nocryp,表示不加密。
Android提供了一个脚本mkkey.sh用来简化上面的步骤:
if ["$1" == ""]; then
??? echo "Create a test certificate key."
??? echo "Usage: $0 NAME"
??? echo "Will generate NAME.pk8 and NAME.x509.pem"
??? echo "? /C=US/ST=California/L=Mountain [email protected].com"
??? return
fi
?
openssl genrsa -3 -out $1.pem 2048
?
openssl req -new -x509 -key $1.pem -out $1.x509.pem -days 10000 /
??? -subj '/C=US/ST=California/L=Mountain [email protected].com'
?
openssl pkcs8 -in $1.pem -topk8 -outform DER -out $1.pk8 -nocrypt
签名
Android提供了为jar/zip文件签名的程序signapk.jar 。
它的用法如下:
Usage: signapk publickey.x509[.pem] privatekey.pk8 input.jar output.jar
第一个参数是公钥,即前面第二步产生的testkey.x509.pem。
第二个参数是私钥,即前面第三步产生的testkey.pk8。
第三个参数是要签名的文件。
第四个参数是输出的文件(即签名后的文件)。
如:java -jar signapk.jar testkey.x509.pem testkey.pk8 update.zip update-signed.zip
现在我们来看看签名到底做了些什么:
o 先为输入的jar/zip文件中的所有文件生成SHA1数字签名(除了CERT.RSA,CERT.SF和MANIFEST.MF)
??????? for (JarEntry entry: byName.values()) {
??????????? String name = entry.getName();
??????????? if (!entry.isDirectory() && !name.equals(JarFile.MANIFEST_NAME) &&
??????????????? !name.equals(CERT_SF_NAME) && !name.equals(CERT_RSA_NAME) &&
??????????????? (stripPattern == null ||
???????????????? !stripPattern.matcher(name).matches())) {
??????????????? InputStream data = jar.getInputStream(entry);
??????????????? while ((num = data.read(buffer)) > 0) {
??????????????????? md.update(buffer, 0, num);
??????????????? }
?
??????????????? Attributes attr = null;
??????????????? if (input != null) attr = input.getAttributes(name);
??????????????? attr = attr != null ? new Attributes(attr) : new Attributes();
??????????????? attr.putValue("SHA1-Digest", base64.encode(md.digest()));
??????????????? output.getEntries().put(name, attr);
??????????? }
??????? }
并把数字签名信息写入MANIFEST.MF
??????????? je = new JarEntry(JarFile.MANIFEST_NAME);
??????????? je.setTime(timestamp);
??????????? outputJar.putNextEntry(je);
??????????? manifest.write(outputJar);
o 对manifest签名并写入CERT.SF
??????????? // CERT.SF
??????????? Signature signature = Signature.getInstance("SHA1withRSA");
??????????? signature.initSign(privateKey);
??????????? je = new JarEntry(CERT_SF_NAME);
??????????? je.setTime(timestamp);
??????????? outputJar.putNextEntry(je);
??????????? writeSignatureFile(manifest,
??????????????????? new SignatureOutputStream(outputJar, signature));
o 把对输出文件的签名和公钥写入CERT.RSA。
??????????? // CERT.RSA
??????????? je = new JarEntry(CERT_RSA_NAME);
??????????? je.setTime(timestamp);
??????????? outputJar.putNextEntry(je);
??????????? writeSignatureBlock(signature, publicKey, outputJar);
签名的作用
签名的主要目的为了检测文件是否被别人修改了。但它并不能禁止别人修改,因为你完全重新生成签名,但是你生成的签名和原来是不一样的。
详细解决方案
Android中的签字机制
热度:99 发布时间:2016-04-28 07:40:22.0
相关解决方案
- android 读取byte[]中的元素解决方案
- android 标题栏兑现方式
- android 中Activity向BroadcastReceiver发送数据,该怎么解决
- Android 4.0 为什么模拟器老是提示小弟我谷歌拼音输入法已停止
- android:getSharedPreferences() 这是哪个类的方法解决思路
- android 怎么判断一个程序是否联网
- android RadioButton如何设置默认选中
- android 怎么重新设置锚点
- android 图片对象获取的有关问题
- android 关于服务连接的疑义
- android 怎么实现对view的放大和缩小
- android ID,该如何处理
- 准备复习2-3个月,看java+android,请问有经验者,怎么看效果最好》
- android UI线程与AsyncTask的有关问题
- android(java) 中文乱码的有关问题
- android 动态设立控件高度
- Android test project 编译方法
- android 4.03启动出错,显示"Encryption Unsuccessful"该如何解决
- Android 下面的listView的动态效果怎么实现的?求源代码,多谢
- Android?Palm?Symbian?Windows Mobile?学哪个有“钱图”?解决方案
- Android 开发语言,该怎么解决
- 单个人去做手机开发选什么平台好?android,iphone?解决办法
- Android 虚拟机崩溃的有关问题
- 想学学移动平台的开发 android 还是windows phone7好啊该怎么处理
- Android 上的如何读写设备文件
- Android 2.2 API 汉语文档系列(3) —— AccessibilityService
- 【先睹为快】ArcGIS Android SDK上一版本新特性
- ArcGIS for Android app v2.0.4公布
- android.hardware.USB种介绍
- android linux开发 在线电子书解决方案