关于加密、签名及证书

  去年在开发一个安卓小游戏的时候,还煞有其事地对apk包做了个人签名。当时只是照猫画虎的按书上说的步骤来做,也没深究为什么。最近比较详细的了解了一下java的安全机制,才发现原来有那么多一知半解的问题。

  先从非对称加密的公钥、私钥机制说起。所谓非对称就是指用私钥加密的内容要用公钥来解密(反过来用公钥加密也一样必须要用私钥来解密。公、私其实是对等的一对儿,并非指技术方面,而是针对发布范围来说的)

  有了这种加密、解密的唯一性,我们就可以有这样一些结论:用私钥/公钥加密的,只有通过对应的公钥/私钥来解密;而能用某个公钥/私钥解开的,一定是用其私钥/公钥加密的。有点绕嘴,其实不难理解。利用这个特性,我们就可以达到一些互为验证的目的。

  然后介绍一下相关操作。先说关于keystore的:

  Keystore是存储密钥对集合的文件,所以也叫密钥库文件(之前都不知道可以存储多个)。利用jdk工具是这样生成的:

  keytool -genkey -alias mykey1 -keypass <这个key的密码> -validity 1000 -keystore xxx.keystore

  如果这个xxx.keystore文件还不存在,那么会新生成一个,同时要求输入一个对xxx.keystore文件进行读写的密码。这个和keypass后的密码参数不需要相同。

  继续一条:

  keytool -genkey -alias mykey2 -keypass <这个key的密码> -validity 1000 -keystore xxx.keystore

  这个时候xxx.keystore文件已经存在了,所以这个命令是再追加进去一个密钥对。所以输入第一次设定的读写密码即可。

  从字面意义看会以为alias是个可有可无的别名,但其实不是,这个参数是必须的,是一对密钥的“正式”的名字。即便我们不输入这个参数:-alias mykey1,那么系统也会自动生成一个叫做mykey的密钥对名字;

  如果没有这个参数:-keypass <这个key的密码>,那么系统会提示输入。当然直接回车是设定为和库文件的读写密码相同。

  那么现在呢,实际上xxx.keystore里已经存了两个密钥对,mykey1和mykey2。可以用这个命令查看:

  Keytool –list –keystore xxx.keystore,当然查看也是需要输入密码的

  有了这些密钥对,即可以对jar文件进行签名了。命令是这样的:

  jarsigner -keystore xxx.keystore -storepass <文件读写密码> -keypass <这个key的密码> xxx.jar mykey1

  同样的,如果没有这个参数:-storepass <文件读写密码>,系统会要求输入。没有这个参数:-keypass <这个key的密码>,一种情况是mykey1的密码和库密码相同,那么就可以签名成功。如果不同,那就会报错。

  导出公钥为一个证书,命令是:

  Keytool –export –file xxx.cer –keystore xxx.keystore –alias mykey1,输入库密码后,会生成一个xxx.cer的证书文件。

  一个库里可以有多个密钥,但一个证书里只有一个公钥。用命令keytool -printcert -file xxx.cer查看证书,结果是库密钥列表中的一个。

  私钥一般用命令导不出来(也没有导出的必要)。但是可以用写代码来导出。

 

上一篇:安卓防火墙 PS DroidWall

下一篇:社会工程学的4个技巧