1、公钥和私钥的概念
在现代密码体制中加密和解密是采用不同的密钥(公开密钥),也就是公开密钥算法(也叫非对称算法、双钥算法)”,每个通信方均需要两个密钥,即公钥和私钥,这两把密钥可以互为加解密。公钥是公开的,不需要保密,而私钥是由个人自己持有,并且必须妥善保管和注意保密。
2、证书的概念
数字证书则是由证书认证机构(CA)对证书申请者真实之身份验证后,用CA的根证书对申请人的一些基本信息以及申请人的公钥进行签名(相当于加盖发证书机 构的公章)后形成的一个数字文件。CA完成签发证书后,会将证书发布在CA的证书库(目录服务器)中,任何人都可以查询和下载,因此数字证书和公钥一样是公开的。实际上,数字证书就是经过CA认证过的公钥。
原则:
- 一个公钥对应一个私钥。
- 密钥对中,让大家都知道的是公钥,不告诉大家,只有自己知道的,是私钥。
- 如果用其中一个密钥加密数据,则只有对应的那个密钥才可以解密。
- 如果用其中一个密钥可以进行解密数据,则该数据必然是对应的那个密钥进行的加密。
- 非对称密钥密码的主要应用就是公钥加密和公钥认证,而公钥加密的过程和公钥认证的过程是不一样的
3、基于公开密钥的加密过程
比如有两个用户Alice和Bob,Alice想把一段明文通过双钥加密的技术发送给Bob,Bob有一对公钥和私钥,那么加密解密的过程如下:
- Bob将他的公开密钥传送给Alice。
- Alice用Bob的公开密钥加密她的消息,然后传送给Bob。
- Bob用他的私人密钥解密Alice的消息。
Android中的签名:
是什么签名?
Android要求所有已安装的应用程序都使用数字证书做数字签名,数字证书的私钥由应用开发者持有,
Android使用证书作为标示应用程序作者的一种方式,并在应用程序之间建立信任的关系。 证书并不用来控制用户能否安装哪个应用。证书不需要由证书认证中心签名;完全可以使用自制签名证书。
没有正确签名的应用,Android系统不会安装或运行。此规则适用于在任何地方运行的Android系统,不管是在模拟器还是真实设备上。因为这个原因。在真机或模拟器上运行或者调试应用前,必须为其设置好签名。
为什么要有签名?
开发Android的人这么多,完全有可能把类名,包名命名成同样的名字,这个时候该如何区分?所以,这时候就需要签名来区分了,由于开发商可能通过使用相同的Package Name来混淆替换已经安装的程序,签名可以保证相当名字,但是签名不同的包不被替换。
发布过Android应用的朋友们应该都知道,Android APK的发布是需要签名的。签名机制在Android应用和框架中有着十分重要的作用。例如,Android系统禁止更新安装签名不一致的APK;如果应用需要使用system权限,必须保证APK签名与Framework签名一致。
签名策略
应用程序签名的一些方面可能会影响应用程序的开发过程, 尤其是当你计划发布多个应用时. 通常情况下, 对于所有开发者而言,推荐的策略是:在应用程序的整个生命周期,所有的应用程序使用相同的证书签名.
为什么这么做的原因:
- 应用程序升级 – 当发布应用的更新时, 如果想让用户无缝地升级到新版本, 需要继续使用相同的某个或者某一套证书来签名更新包.当系统安装应用的更新时, 它会比较现有版本和新版本的证书. 如果证书吻合, 包括证书数据和顺序都吻合, 那么系统允许更新.如果新版本所做的签名不是匹配的, 那么将需要给应用起一个不同的包名 — 在这种情况下, 用户相当于安装了一个完全的新程序.
- 应用程序模块化 – Android允许由相同证书签名的应用程序运行在相同的进程中, 此时系统会将它们作为单个应用程序对待.在这种方式中, 可以按模块化的方式部署应用, 用户可以根据需要独立地更新每一个模块.
- 代码/数据 的授权共享 – Android 提供模式匹配的权限控制机制,因此一个应用可以暴露功能给另一个用指定证书签名的应用. 通过用相同证书签名多个应用,以及使用模式匹配的权限检查,应用程序可以以安全的方式共享代码和数据.
- 另一个影响签名策略的重要考量是, 如何设置签名应用的key的有效期.
如果计划为某个单独的应用程序提供更新支持, 那么应该确认key的有效期要比应用的寿命长. 推荐25年或者更长的有效期.当key的有效期过期, 用户将再也不能无缝地更新到应用程序的新版本.
如果要使用相同的key为多个不同的应用签名, 应当确认key的有效期比所有这些应用的所有版本的生命周期还长,包括要比将来加到这个套件中的额外的关联应用的生命周期更长.
如果计划将应用程序发布到Android Market, 为应用签名的key的有效期必须在2033年10月22日以后.Market服务器强制执行这个规则, 来保证当新版本可用时, 用户可以无缝地更新Market应用.
当设计的时候, 须牢记这些要点, 以确保使用合适的证书来签名应用程序。
二、给Apk签名:
(1) Android的签名文件存放于系统源码的 build/target/product/security/目录下
该目录下有 media.pk8、media.x509.pem、platform.pk8、platform.x509.pem、shared.pk8、shared.x509.pem、testkey.pk8、testkey.x509.pem等签名文件,不同的签名文件,对应不同的权限。Android默认的签名文件为testkey.pk8、testkey.x509.pem。
(2) Android自带的签名工具为 signapk.jar, 可以在源码编译目录out中找到,具体路径为:out/host/linux-x86/framework/signapk.jar 以上APK具有系统权限,重新签名应该使用platform签名文件进行签名。
签名方法:将对应权限的签名文件platform.pk8、platform.x509.pem, 签名工具 signapk.jar, 以及需要签名的apk(假设 old.apk) 放到同一目录下,打开linux终端(windows cmd也可以),进入该目录,进行重新签名:
java -jar signapk.jar platform.x509.pem platform.pk8 old.apk new.apk
重新生成的new.apk就可以安装在我们的Android设备上了。
关于系统签名出现如下错误:
Exception in thread "main" java.lang.UnsatisfiedLinkError: org.conscrypt.NativeCrypto.get_cipher_names(Ljava/lang/String;)[Ljava/lang/String;
at org.conscrypt.NativeCrypto.get_cipher_names(Native Method)
at org.conscrypt.NativeCrypto.<clinit>(NativeCrypto.java:764)
at org.conscrypt.OpenSSLProvider.<init>(OpenSSLProvider.java:56)
at org.conscrypt.OpenSSLProvider.<init>(OpenSSLProvider.java:49)
at com.android.signapk.SignApk.main(SignApk.java:942)
加上启动参数 -Djava.library.path,链接相应的库,
例如:java -Djava.library.path=../lib64 -jar signapk.jar shared.x509.pem shared.pk8 GoogleServicesFramework.apk GoogleServicesFramework1.apk