以下内容搜集自互联网
在以下的环境测试成功:
Windows XP Professional Version 2002 Service Pack 3
java version "1.4.1_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_02-b06)
Java HotSpot(TM) Client VM (build 1.4.1_02-b06, mixed mode)
OpenSSL 0.9.8e 23 Feb 2007
JadTool [size: 16,249 bytes]
申请证书申请证书首先需要生成密钥对,密钥对中的私钥用来加密JAR文件的摘要,公钥用来申请证书。另外可以自己制作CA。整个过程可以用两个工具完成:jdk的keytool,openssl。Keytool可以管理密钥对和证书,但是只能生成自签名的证书,要生成多证书链需要openssl。
1) 生成密钥对
keytool -genkey -alias myalias -validity 365 -keyalg RSA -keysize 2048 -keypass password -keystore mykeystore.ks
得到密钥对,存放在mykeystore.ks中,用myalias标识
2) 如果不是生成自签名的证书,跳过这一条;如果只需要自签名的证书
keytool -selfcert -alias myalias -keypass password -keystore mykeystore.ks [Optional]
keytool -export -alias myalias -file mycert.cer -keystore mykeystore.ks
得到自签名证书:mycert.cer,整个过程完成。
注意:生成自签名证书在jdk1.4.1_02下测试成功,但在jdk1.6.0_11测试失败;而用openssl + keytool生成多证书链在两个版本jdk都成功。
3) 生成证书签名请求
keytool -certreq -alias myalias -sigalg MD5withRSA -file mycsr.csr -keypass password -keystore mykeystore.ks
得到签名请求:mycsr.csr
4) 将证书签名请求发送给CA,如Verisign和Thawte,等待CA验证请求并颁发证书,拿到CA颁发的证书,则整个过程完成。如果自己制作CA,跳过这一条。
5) 制作CA
新建目录 demoCA、demoCA/certs、demoCA/newcerts;在demoCA建立一个空文件 index.txt;在demoCA建立一个文本文件 serial, 没有扩展名,内容是一串字符,例如 0000。
6) 生成CA的自签名证书
openssl req -new -x509 -keyout ca.key -out ca.crt [-config openssl.cnf]
得到两个文件:ca.key和ca.crt
7) 用CA私钥签名
openssl ca -in mycsr.csr -out mycert.crt -cert ca.crt -keyfile ca.key -notext [-config openssl.cnf]
-notext表示不要把证书文件的明文内容输出到文件中去,否则用keytool导入到keystore会出错。
得到证书:mycert.crt,这是CA颁发的证书
8) 导入信任的CA根证书
keytool -import -v -trustcacerts -alias rootcert -file ca.crt -keystore mykeystore.ks
9) 导入CA签名后的证书
keytool -import -v -alias myalias -file mycert.crt -keystore mykeystore.ks
10) 查看证书
keytool -list -v -keystore mykeystore.ks
签署midlet使用JadTool签署midlet。
java -jar JadTool.jar -addcert -alias myalias -keystore mykeystore.ks -inputjad JAD.jad -outputjad JAD.jad
上面的操作将证书的内容复制到JAD文件,作为MIDlet-Certificate-1-1的值。(如果一个证书是某些中间证书签发的,需要添加MIDlet-Certificate-1-2,MIDlet-Certificate-1-3等)
java -jar JadTool.jar -addjarsig -jarfile JAR.jar -keypass password -alias myalias -keystore mykeystore.ks -inputjad JAD.jad -outputjad JAD.jad
采用SHA-1算法,对JAR文件计算摘要(Digest),然后使用私钥(该私钥与MIDlet-Certificate-1-1中的公钥对应)对JAR文件的摘要进行加密(RSA加密),其计算结果作为MIDlet-Jar-RSA-SHA1的值。
认证
出处鉴定安装时,设备可以通过其本身已经安装的CA根证书来验证MIDlet套件中的证书链,即JAD文件中的属性MIDlet-Certificate-<n>-<m>。如果能通过MIDlet-Certificate-1-1-> MIDlet-Certificate-1-2-> MIDlet-Certificate-1-3->Root CA Certificate的验证,即表明此证书是值得信赖的,从而表明该证书中声明的所有者(Owner)确实是这个人。因此也就表明该MIDlet的出处确实是该证书的所有者Owner。
验证MIDlet-Certificate-1-1是由MIDlet-Certificate-1-2签发的,需要以下几个步骤:
(1) 检验 MIDlet-Certificate-1-1和MIDlet-Certificate-1-2 的时间有效性;
(2) 检验 MIDlet-Certificate-1-1 的 Issuer name(颁发者) 是否等于 MIDlet-Certificate-1-2 的 Subject name(主题);
(3) 使用MIDlet-Certificate-1-2 的公钥对 MIDlet-Certificate-1-1中的签名信息进行解密,得到摘要1;
(4) 使用MIDlet-Certificate-1-2 中的签名算法,对MIDlet-Certificate-1-1 的 Issuer name 进行SHA-1计算,得到摘要2;
(5) 比较摘要1和2是否一致,如果一致,则可信;否则,MIDlet-Certificate-1-1不是由MIDlet-Certificate-1-2签发。
完整性认证验证完出处后,需要验证midlet是否完整,防止该midlet在发布过程中被有意或无意地更改。
(1) 从MIDlet-Certificate-1-1证书中提取公钥;
(2) 使用该公钥对MIDlet-Jar-RSA-SHA1进行解密,得到JAR文件的摘要1;
(3) 使用SHA-1算法,对JAR文件重新进行计算,生成摘要2;
(4) 将摘要1和摘要2进行对比,如果一致则通过完整性认证;否则表示该midlet已经被更改。
非对称加密需要两个密钥:公开密钥(public key)和私有密钥(private key)。公开密钥与私有密钥是一对,如果用公开密钥加密数据,只有用对应的私有密钥才能解密;如果用私有密钥加密数据,只有用对应的公开密钥才能解密。因为加密和解密使用的是两个不同的密钥,所以叫非对称。非对称加密算法不仅可以加密数据,也可以签名数据。
签名是指用非对称加密中的私有密钥加密某些数据。
证书包含一个唯一名和一个公钥,唯一名表示一个具有与证书的公钥匹配的私钥的实体,通过用私钥对证书签名并将签名放到证书中而将两者结合到一起。
证书是非对称加密的应用,假如有一对密钥:公钥和私钥,那么证书就是这个公钥,而证书需要用私钥签名后才能获得认证。一个由匹配证书公钥的私钥签名的证书称为自签名证书。根证书颁发机构(Root certification authority,CA)的证书就属于这一类。但证书通常是由其它实体的私钥签名,这构成了两证书链,验证证书就需要CA的公钥。
证书需要用根CA的私钥签名,它也可以用一个中介的私钥签名,这个私钥的证书是用 CA 的私钥签名的,这是一个三证书链的例子:用户证书、中介证书和CA证书。但是在链中可以有多个中介,因此证书链可以有任意的长度。
证书也可以包含额外信息,称为extension。Extension可以指定证书的用途以及其他内容。根据证书的用途,某些extension有可能非常重要。
X.509证书的具体内容参考http://java.sun.com/j2se/1.4.2/docs/guide/security/cert3.html
签名的midlet和没有签名的midlet区别:签名的midlet对应的JAD文件有两个属性:
MIDlet-Certificate-<n>-<m>, MIDlet-Jar-RSA-SHA1
MIDlet-Certificate-<n>-<m>的值就是证书的内容,MIDlet-Jar-RSA-SHA1表示使用公钥加密后的JAR文件摘要。
Domain表示权限的集合。手机的功能可以按照类别划分,例如Net Access, Messaging等。每一类功能可以有不同的权限级别:Not allowed, Ask every time, Ask first time, Always allowed。那么一个domain表示所有功能的对应权限级别的集合。
MIDlet-Permissions是JAD的一个属性,表示必须得到某些功能的许可。
如果JAD文件有这个属性,那么MIDlet-Certificate-<n>-<m>, MIDlet-Jar-RSA-SHA1也必须存在,即签名的midlet才有这个属性。
假如该属性的值是:javax.microedition.io.Connector.file.read,那么安装成功后的midlet肯定可以访问文件。
签名的直接目的是为了获得MIDlet-Permissions描述的功能的权限,在这之前,必须用手机中的证书所包含的公钥验证其它两个属性:
MIDlet-Certificate-<n>-<m>, MIDlet-Jar-RSA-SHA1,而手机中的每个证书都会对应一个domain,如果验证成功,midlet则会获得对应的domain。另外MIDlet-Permissions列举的功能如果至少有一个在domain中是不允许访问,则安装失败。