Apk签名

1.jarsigner : 签名和验证jar文件 , ( https://docs.oracle.com/javase/9/tools/jarsigner.htm#JSWOR-GUID-925E7A1B-B3F3-44D2-8B49-0B3FA2C54864 ) , 使用keystore文件。
signapk.jar : 对android apk 签名 , 使用pk8,x509.pem文件。

Keytool 、 jarsigner对apk签名 :
keytool 是java 用于管理密钥和证书的工具,创建并管理密钥,创建并管理证书,作为CA为证书授权,导入导出证书。

2.签名:
a.对APK包中的每个文件做一次运算(Hash+Base64编码),将结果保存到META-INF/MANIFEST.MF文件中。
b.对MANIFEST.MF整个文件做一次运算(Hash+Base64编码),将结果保存到META-INF/CERT.SF文件的头属性中,再对MANIFEST.MF文件中的各个属性块做同样的运算(Hash+Base64编码),存放到CERT.SF的属性块中。
c.开发者用自己的私钥对CERT.SF进行签名,并将签名信息和包含公钥信息的数字证书一同保存到META-INF/CERT.RSA文件中。
d.CERT.RSA是一个PKCS7 格式的文件。

3.验签源码位置:
frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
frameworks/base/core/java/android/content/pm/PackageParser.java
libcore/luni/src/main/java/java/util/jar/StrictJarFile.java
libcore/luni/src/main/java/java/util/jar/JarVerifier.java
libcore/luni/src/main/java/java/util/jar/JarFile.java
libcore/luni/src/main/java/org/apache/harmony/security/utils/JarUtils.java

4.验签:
a.所有的验签动作都是在JarVerifier这个类里面完成的
b.在JarVerifier.verifyCertificate()方法中完成了以下两步:
使用CERT.RSA校验CERT.SF,看CERT.SF是否被篡改;
使用CERT.SF校验MANIFEST.MF,看MANIFEST.MF是否被篡改;
c.在JarVerifier.VerifierEntry.verify()方法中完成最后一步:
使用MANIFEST.MF来校验所有文件,看有没有文件被篡改,或者有没有文件被删
除,又或者有没有添加新的文件
d.但是反编译改动apk之后可以用自己的私钥重新签名,新的公钥和新的数字证书,但是只有相同签名和相同包名的apk才可以覆盖安装以前的程序并保留用户信息,要改动后自己签名的话得卸载之前的app才能安装,可能有“非官方应用”等其它警告

5.提取证书:
openssl pkcs7 -inform DER -in CERT.RSA -noout -print_certs -text

import sun.security.pkcs.PKCS7;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

public class Test {
public static void main(String[] args) throws CertificateException, IOException {
FileInputStream fis = new FileInputStream("/Users/***/Desktop/CERT.RSA");
PKCS7 pkcs7 = new PKCS7(fis);
X509Certificate publicKey = pkcs7.getCertificates()[0];
System.out.println(“issuer1:” + publicKey.getIssuerDN());
System.out.println(“subject2:” + publicKey.getSubjectDN());
System.out.println(publicKey.getPublicKey());
}
}

X509Certificate certificate = getCertificate();
String pubKey = certificate.getPublicKey().toString();
String signNumber = certificate.getSerialNumber().toString();
String subjectDN = certificate.getSubjectDN().toString();

6.获取apk指纹
keytool -list -printcert -jarfile app.apk
查看keystore的指纹
apk的签名指纹跟keystore中的指纹一致表明该包是用keystore来签名的
keytool -list -keystore android_sign.jks
keytool -printcert -file XXX.RSA

7.a、 Android签名机制其实是对APK包完整性和发布机构唯一性的一种校验机制。
b、Android签名机制不能阻止APK包被修改,但修改后的再签名无法与原先的签名保持一致。(拥有私钥的情况除外)。
c、APK包加密的公钥就打包在APK包内,且不同的私钥对应不同的公钥。换句话言之,不同的私钥签名的APK公钥也必不相同。所以我们可以根据公钥的对比,来判断私钥是否一致。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值