使用Openssl进行PKI实践(含多级证书详细步骤)

Openssl是Linux下的基础安全工具

先简要介绍一些基础知识:

Openssl功能主要有:对称加密(DES、3DES、AES等),非对称加密(RSA),散列(MD5、SHA1等)以及证书的相关操作(创建、申请、颁发、吊销等)

PKI体系成为公钥加密体系,组成部分包括:认证中心、注册中心、证书库、证书废止列表。

Openssl常用证书格式:X509、PKCS7、PKCS12。

证书文件常用存储格式:PEM(BASE64)、PFX或P12(二进制)

 

本文主要实践点:

1、根CA相关操作(私钥生成、生成自认证证书)

2、用户证书相关操作(私钥生成、生成证书签发请求文件、根CA同意请求签发该证书)

3、次级CA证书相关操作(从根CA得到次级CA证书和次级CA私钥之后,再给下属用户签发证书)

实验环境:

RHEL 6.3(KVM虚拟机) rootca.testlibq.com

RHEL 6.3(KVM虚拟机) apache.testlibq.com(以APACHE服务器为次级CA)

Windows XP(KVM虚拟机) xp.testlibq.com(以展示证书)

实验步骤:

1、生成根CA证书

登录到ROOTCA机器

cd /etc/pki/CA/private

openssl genrsa -des3 -out rootca.key 1024

#生成ROOTCA私钥,rootca.key格式为PEM

[设置rootca私钥密码,例如输入rootca]

touch /etc/pki/CA/index.txt   #创建证书数据库文件

echo “01” > /etc/pki/CA/serial  #创建证书序号文件

openssl req -new -x509 -key rootca.key -out /etc/pki/CA/rootca.crt

#生成ROOTCA证书(类型为X509),rootca.crt格式为PEM

[输入rootca私钥密码:rootca]

[填入一堆证书信息]

 

由于/etc/pki/tls/openssl.cnf中设置了CA的私钥和证书路径,所以这里使用软链接。

ln -s /etc/pki/CA/private/rootca.key /etc/pki/CA/private/cakey.pem

ln -s /etc/pki/CA/rootca.crt /etc/pki/CA/cacert.pem

这样,CA便设置好了。

查看证书和私钥可以用以下命令:

openssl rsa -in /etc/pki/CA/private/rootca.key -text -noout

openssl x509 -in /etc/pki/CA/rootca.crt -text -noout

 

2、用户证书的相关操作

PS:

用户证书可以在用户端生成私钥和请求文件,然后传递至CA,由CA签发后,发给用户。

也可以由根CA生成用户私钥和请求文件,然后签发后把私钥和证书发给用户。

这里演示后者。

登录到rootca机器(接实验1)

cd /etc/pki/CA/private

openssl genrsa -des3 -out a.key 1024  #生成用户私钥

[set password of a.key]

openssl req -new -key a.key -out a.csr  #生成用户请求文件

[input password of a.key]

[输入一堆证书信息]

openssl ca -in a.csr

[y,y]

 

生成证书位于/etc/pki/CA/newcerts/01.pem

PS:

该证书类型为X509,若需要PKCS12类型证书,请使用

openssl pkcs12 -export -in /etc/pki/CA/newcerts/01.pem -inkey /etc/pki/CA/private/a.key -out a.pfx[输入私钥密码][设置传输密码]

 

3、生成证书链

此节内容网上文章较少,我研究了好久才搞出来。

 

首先上面两个实验是连着做的,第三个实验请把上面的环境清除。

登录到ROOTCA

cd /etc/pki/CA/private

touch ../index.txt

echo “01” > ../serial

openssl genrsa -des3 -out rootca.key 1024 [rootca]

ln -s rootca.key cakey.pem

openssl req -new -x509 -key rootca.key -out /etc/pki/CA/rootca.crt -extensions v3_ca

ln -s /etc/pki/CA/rootca.crt /etc/pki/CA/cacert.pem

这里查看一下rootca证书:

openssl x509 -in /etc/pki/CA/rootca.crt -text -noout

确定extensions中,有basicConstraint CA:TRUE,那么代表正确。

PS:basicConstraint称为基础约束,若有CA:TRUE,证明该证书具有CA效力。(所以上述实验1、2中并不严谨,这点在需要证书链的场合尤为重要)

cd /etc/pki/CA/private

openssl genrsa -des3 -out apache.key 1024 [apache]

openssl req -new -key /etc/pki/CA/private/apache.key -out apache.csr

[apache][一堆证书信息]

openssl ca -in apache.csr -extensions v3_ca[y,y]

PS:这个extensions至关重要,关系到apache这个证书有没有资格再颁发证书给用户。

 

登录到apache主机

rsync rootca.testlibq.com:/etc/pki/CA/private/apache.key /etc/pki/CA/private/apache.key

[root password of rootca.testlibq.com]

rsync rootca.testlibq.com:/etc/pki/CA/newcerts/01.pem /etc/pki/CA/apache.crt

[root password of rootca.testlibq.com]

ln -s /etc/pki/CA/private/apache.key /etc/pki/CA/private/cakey.pem

ln -s /etc/pki/CA/apache.crt /etc/pki/CA/cacert.pem

下面制作用户证书

cd /etc/pki/CA

touch index.txt

echo “01” > serial

openssl genrsa -des3 -out private/user1.key 1024 [user1]

openssl req -new -key private/user1.key -out private/user1.csr[user1][一堆证书信息]

openssl ca -in private/user1.csr -extensions usr_cert[y,y]

PS:这里-extensions usr_cert不必要。

制作证书链

rsync rootca.testlibq.com:/etc/pki/CA/rootca.crt /etc/pki/CA/certs/rootca.crt

[root password of rootca.testlibq.com]

将rootca的证书和apache的证书整合到一个文件

cd /etc/pki/CA/certs

cp /etc/pki/CA/apache.crt chain.pem

cat rootca.crt >> chain.pem

验证证书链

openssl verify -CAfile /etc/pki/CA/certs/chain.crt /etc/pki/CA/newcerts/01.pem

(若显示Verify OK,表示验证证书链成功)

转换用户证书为PKCS12

openssl pkcs12 -export -in /etc/pki/CA/newcerts/01.pem -inkey /etc/pki/CA/private/user1.key -out /etc/pki/CA/private/user1.pfx -chain -CAfile /etc/pki/CA/certs/chain.crt

最后将user1.pfx复制到Windows中,导入证书,便于展示。

结果如图:

 

from : http://liboqiu.blog.51cto.com/1932711/1123537

How does Android’s app/signature verification work?

from : http://stackoverflow.com/questions/10938298/how-does-androids-app-signature-verification-work/10942302#comment18434028_10942302

I want to preface this question with two things so I can narrow down where my actual question is:

a) I’ve done software dev before, though never for android

b) I’m familiar with PKI and encryptions and hashing and digital signatures and blah blah blah

That being said I’m having trouble tracking down more information about where and how Android verifies app creators. I’ve heard a lot of different information so I’m trying to synthesize to get a better idea of the workflow.

I know that every app developer gets their own private/public key pair and they sign their apps by hashing the APK (with SHA-1 most of the time if I’m not mistaken) and there you go. You upload it and (I believe) the public key goes in META INF inside the APK. This much I understand.

My question is how this relates to when a user downloads the app itself. I know the phone checks to make sure that the app is validly signed, and that the signature also has information about author and etc included. But I’ve also read that apps are self signed and that Google Play (or whatever they’re calling the Market now) doesn’t implement a CA, and that there’s no identity authentication? But my question is what, then, stops people from uploading an app under another developers name (crowdsourcing aside)?

If the phone only checks for valid signatures does that imply that the only means of authentication is done when the app is uploaded? And if that’s the case how does the app market check it? Is it the usual – use the private key on file and verify the signature? Or does the developer have to provide the market with their private key to authenticate?

asked Jun 7 ’12 at 19:08
Fewmitz
17518
When you sign the apk you have to provide the private password. So in order for someone to post an app “as someone else” They would need access to their keystore / key files and passwords. And access to the Google Account that is linked to the market. –  FoamyGuy Jun 7 ’12 at 19:17
@Tim: I think he is asking: What is to prevent someone else from creating their own keypair and a self-signed certificate that also says “Fewmitz” in it. Is it somehow linked to an account somewhere? –  GregS Jun 7 ’12 at 22:36

add comment

In short, Android and Google Play essentially don’t care about what’s in actual certificate. Google Play will validate it indeed, and check if it is valid for 30 years or more, but they don’t really use (at least currently, AFAIK) the actual info in the cert. You could use your own name/company name in the CN, but no one will validate this, and users won’t see this info at all. What Android does is:

  • check the signature to make sure the APK hasn’t been tampered with
  • then compare the singing certificate as a binary blob to the one of the currently installed version of the app to make sure that the two versions have been signed with the same key/certificate (e.g., by the same person/company)
  • it does the same thing to enforce permission if you are using using sharedUid or signature permissions with two or more apps.

So, to answer your question, someone can easily create a certificate with your name on it, but Android and Google Play don’t really care. As long as they don’t have your private key, they won’t be able produce an app signature that is the same as yours and thus they wouldn’t be able to overwrite/update your app with theirs, or get any special permissions.

answered Jun 8 ’12 at 2:19
Nikolay Elenkov
30.8k33046
So, does that mean that if use two certificates with the same public-private key pair but different subject names, they both would be valid? Basically when I sign my app with my private key, are my details like subject name etc taken into account anywhere? –  Ashwin Nov 20 ’12 at 13:55
It doesn’t care about the actual ‘details’ (certificate DN, serial number, etc.), but just compares the certificates as binary blobs. Since they are different, you can’t update an app originally signed with cert1 with another signed with cert2. –  Nikolay Elenkov Nov 20 ’12 at 14:04
By saying “It doesn’t care about the actual ‘details’ (certificate DN, serial number, etc.),” do you mean that those details are never used? Because ultimately as you yourself told “compares the certificates as binary blobs” – that means it takes the certificate details into account. –  Ashwin Nov 20 ’12 at 14:07
Of course it means no such thing. Think memcmp() or Arrays.equals(). Do those take certificate details into account? –  Nikolay Elenkov Nov 20 ’12 at 14:11
yeah ok. So the certificates are compared, but the details are never used(other than for comparison) right? Thanks:) –  Ashwin Nov 20 ’12 at 14:30

show 2 more comments

Android APK的数字签名的作用和意义

1. 什么是数字签名?
 
数字签名就是为你的程序打上一种标记,来作为你自己的标识,当别人看到签名的时候会知道它是与你相关的
2. 为什么要数字签名?
 最简单直接的回答: 系统要求的。
 Android系统要求每一个Android应用程序必须要经过数字签名才能够安装到系统中,也就是说如果一个Android应用程序没有经过数字签名,是没有办法安装到系统中的!
 Android通过数字签名来标识应用程序的作者和在应用程序之间建立信任关系,不是用来决定最终用户可以安装哪些应用程序。
 这个数字签名由应用程序的作者完成,并不需要权威的数字证书签名机构认证,它只是用来让应用程序包自我认证的。 
3. 数字证书的机制?
Android使用Java的数字证书相关的机制来给apk加盖数字证书,要理解android的数字证书,需要先了解以下数字证书的概念和java的数字证书机制。
4. 程序使用相同的数字证书的好处
(1)有利于程序升级
当新版程序和旧版程序的数字证书相同时,Android系统才会认为这两个程序是同一个程序的不同版本。如果新版程序和旧版程序的数字证书不相同,则Android系统认为他们是不同的程序,并产生冲突,会要求新程序更改包名。
(2)有利于程序的模块化设计和开发。
Android系统允许拥有同一个数字签名的程序运行在一个进程中,Android程序会将他们视为同一个程序。所以开发者可以将自己的程序分模块开发,而用户只需要在需要的时候下载适当的模块。
(3)可以通过权限(permission)的方式在多个程序间共享数据和代码。
Android提供了基于数字证书的权限赋予机制,应用程序可以和其他的程序共享概功能或者数据给那那些与自己拥有相同数字证书的程序。如果某个权限(permission)的protectionLevel是signature,则这个权限就只
能授予那些跟该权限所在的包拥有同一个数字证书的程序。

5. 在签名时,需要考虑数字证书的有效期

(1)数字证书的有效期要包含程序的预计生命周期,一旦数字证书失效,持有改数字证书的程序将不能正常升级。

(2)如果多个程序使用同一个数字证书,则该数字证书的有效期要包含所有程序的预计生命周期。

(3)Android Market强制要求所有应用程序数字证书的有效期要持续到2033年10月22日以后。
6. 数字证书的要点:

Android数字证书包含以下几个要点:

             (1)所有的应用程序都必须有数字证书,Android系统不会安装一个没有数字证书的应用程序

             (2)Android程序包使用的数字证书可以是自签名的,不需要一个权威的数字证书机构签名认证

             (3)如果要正式发布一个Android ,必须使用一个合适的私钥生成的数字证书来给程序签名,而不能使用adt插件或者ant工具生成的调试证书来发布。

             (4)数字证书都是有有效期的,Android只是在应用程序安装的时候才会检查证书的有效期。如果程序已经安装在系统中,即使证书过期也不会影响程序的正常功能。

             (5)Android使用标准的java工具 Keytool and Jarsigner 来生成数字证书,并给应用程序包签名。

              6)使用zipalign优化程序。
数字签名的两种模式
我们都知道Android系统不会安装运行任何一款未经数字签名的apk程序,无论是在模拟器上还是在实际的物理设备上。所以我们会有一个疑问,为何在日常开发过程中我没有进行任何签名的操作,程序都会在模拟器和真机上运行?下面我们来讲讲
APK程序的两种模式: 调试模式(debug mode)和发布模式(release mode)

1. 调试模式(debug mode)  : 在调试模式下, ADT会自动的使用debug密钥为应用程序签名,因此我们可以直接运行程序。

debug密钥:   一个名为debug.keystore的文件
存放位置 :     C:\Users\Xiaopeng\.android\debug.keystore        Xiaopeng对应替换为自己操作系统的用户名
两个风险:
      debug签名的应用程序有这样两个风险:
     1)debug签名的应用程序不能在Android Market上架销售,它会强制你使用自己的签名;
     2)debug.keystore在不同的机器上所生成的可能都不一样,就意味着如果你换了机器进行apk版本升级,那么将会出现上面那种程序不能覆盖安装的问题。
          不要小视这个问题,如果你开发的程序只有你自己使用,当然无所谓,卸载再安装就可以了。但要是你的软件有很多使用客户,这就是大问题了,就相当于软件不具备升级功能! 
所以一定要有自己的数字证书来签名;
2. 发布模式(release mode) : 当要发布程序时,开发者就需要使用自己的数字证书给apk包签名
 
使用自己的数字证书给APK签名的两种方法:
 

(1)通过DOS命令来对APK签名。

(2)使用ADT Export Wizard进行签名
转载请注明来源: 毕小朋 — http://blog.csdn.net/wirelessqa

Android中的签名机制

转载时请注明出处和作者联系方式
文章出处:http://www.limodev.cn/blog
作者联系方式:李先静 <xianjimli at hotmail dot com>

昨天看了一下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 View/O=Android/OU=Android/CN=Android/emailAddress=android@android.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 []:bronchosales@gmail.com

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 View/O=Android/OU=Android/CN=Android/emailAddress=android@android.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 View/O=Android/OU=Android/CN=Android/emailAddress=android@android.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() &amp;&amp; !name.equals(JarFile.MANIFEST_NAME) &amp;&amp;
!name.equals(CERT_SF_NAME) &amp;&amp; !name.equals(CERT_RSA_NAME) &amp;&amp;
(stripPattern == null ||
!stripPattern.matcher(name).matches())) {
InputStream data = jar.getInputStream(entry);
while ((num = data.read(buffer)) &gt; 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 APK 签名比对

转载请注明出处:http://www.blogjava.net/zh-weir/archive/2011/07/19/354663.html

Android APK 签名比对

发布过Android应用的朋友们应该都知道,Android APK的发布是需要签名的。签名机制在Android应用和框架中有着十分重要的作用。

例如,Android系统禁止更新安装签名不一致的APK;如果应用需要使用system权限,必须保证APK签名与Framework签名一致,等等。在《APK Crack》一文中,我们了解到,要破解一个APK,必然需要重新对APK进行签名。而这个签名,一般情况无法再与APK原先的签名保持一致。(除非APK原作者的私钥泄漏,那已经是另一个层次的软件安全问题了。)

简单地说,签名机制标明了APK的发行机构。因此,站在软件安全的角度,我们就可以通过比对APK的签名情况,判断此APK是否由“官方”发行,而不是被破解篡改过重新签名打包的“盗版软件”。

Android签名机制

为了说明APK签名比对对软件安全的有效性,我们有必要了解一下Android APK的签名机制。为了更易于大家理解,我们从Auto-Sign工具的一条批处理命令说起。

《APK Crack》一文中,我们了解到,要签名一个没有签名过的APK,可以使用一个叫作Auto-sign的工具。Auto-sign工具实际运行的是一个叫做Sign.bat的批处理命令。用文本编辑器打开这个批处理文件,我们可以发现,实现签名功能的命令主要是这一行命令:

 

    java -jar signapk.jar testkey.x509.pem testkey.pk8 update.apk update_signed.apk

这条命令的意义是:通过signapk.jar这个可执行jar包,以“testkey.x509.pem”这个公钥文件和“testkey.pk8”这个私钥文件对“update.apk”进行签名,签名后的文件保存为“update_signed.apk”。    对于此处所使用的私钥和公钥的生成方式,这里就不做进一步介绍了。这方面的资料大家可以找到很多。我们这里要讲的是signapk.jar到底做了什么。

signapk.jar是Android源码包中的一个签名工具。由于Android是个开源项目,所以,很高兴地,我们可以直接找到signapk.jar的源码!路径为/build/tools/signapk/SignApk.java。

对比一个没有签名的APK和一个签名好的APK,我们会发现,签名好的APK包中多了一个叫做META-INF的文件夹。里面有三个文件,分别名为MANIFEST.MF、CERT.SF和CERT.RSA。signapk.jar就是生成了这几个文件(其他文件没有任何改变。因此我们可以很容易去掉原有签名信息)。

通过阅读signapk源码,我们可以理清签名APK包的整个过程。
1、 生成MANIFEST.MF文件:

程序遍历update.apk包中的所有文件(entry),对非文件夹非签名文件的文件,逐个生成SHA1的数字签名信息,再用Base64进行编码。具体代码见这个方法:

 

    private static Manifest addDigestsToManifest(JarFile jar)

关键代码如下:

 1     for (JarEntry entry: byName.values()) {
2         String name = entry.getName();
3         if (!entry.isDirectory() && !name.equals(JarFile.MANIFEST_NAME) &&
4             !name.equals(CERT_SF_NAME) && !name.equals(CERT_RSA_NAME) &&
5                (stripPattern == null ||!stripPattern.matcher(name).matches())) {
6                 InputStream data = jar.getInputStream(entry);
7                 while ((num = data.read(buffer)) > 0) {
8                     md.update(buffer, 0, num);
9                 }
10                 Attributes attr = null;
11                 if (input != null) attr = input.getAttributes(name);
12                 attr = attr != null ? new Attributes(attr) : new Attributes();
13                 attr.putValue(“SHA1-Digest”, base64.encode(md.digest()));
14                 output.getEntries().put(name, attr);
15           }
16     }

之后将生成的签名写入MANIFEST.MF文件。关键代码如下:

 

1     Manifest manifest = addDigestsToManifest(inputJar);
2     je = new JarEntry(JarFile.MANIFEST_NAME);
3     je.setTime(timestamp);
4     outputJar.putNextEntry(je);
5     manifest.write(outputJar);

这里简单介绍下SHA1数字签名。简单地说,它就是一种安全哈希算法,类似于MD5算法。它把任意长度的输入,通过散列算法变成固定长度的输出(这里我们称作“摘要信息”)。你不能仅通过这个摘要信息复原原来的信息。另外,它保证不同信息的摘要信息彼此不同。因此,如果你改变了apk包中的文件,那么在apk安装校验时,改变后的文件摘要信息与MANIFEST.MF的检验信息不同,于是程序就不能成功安装。
2、 生成CERT.SF文件:

对前一步生成的Manifest,使用SHA1-RSA算法,用私钥进行签名。关键代码如下:

1     Signature signature = Signature.getInstance(“SHA1withRSA”);
2     signature.initSign(privateKey);
3     je = new JarEntry(CERT_SF_NAME);
4     je.setTime(timestamp);
5     outputJar.putNextEntry(je);
6     writeSignatureFile(manifest,
7     new SignatureOutputStream(outputJar, signature));

RSA是一种非对称加密算法。用私钥通过RSA算法对摘要信息进行加密。在安装时只能使用公钥才能解密它。解密之后,将它与未加密的摘要信息进行对比,如果相符,则表明内容没有被异常修改。
3、 生成CERT.RSA文件:

生成MANIFEST.MF没有使用密钥信息,生成CERT.SF文件使用了私钥文件。那么我们可以很容易猜测到,CERT.RSA文件的生成肯定和公钥相关。

CERT.RSA文件中保存了公钥、所采用的加密算法等信息。核心代码如下:

 

1     je = new JarEntry(CERT_RSA_NAME);
2     je.setTime(timestamp);
3     outputJar.putNextEntry(je);
4     writeSignatureBlock(signature, publicKey, outputJar);

其中writeSignatureBlock的代码如下:

 

 1     private static void writeSignatureBlock(
2         Signature signature, X509Certificate publicKey, OutputStream out)
3             throws IOException, GeneralSecurityException {
4                 SignerInfo signerInfo = new SignerInfo(
5                 new X500Name(publicKey.getIssuerX500Principal().getName()),
6                 publicKey.getSerialNumber(),
7                 AlgorithmId.get(“SHA1”),
8                 AlgorithmId.get(“RSA”),
9                 signature.sign());
10
11         PKCS7 pkcs7 = new PKCS7(
12             new AlgorithmId[] { AlgorithmId.get(“SHA1”) },
13             new ContentInfo(ContentInfo.DATA_OID, null),
14             new X509Certificate[] { publicKey },
15             new SignerInfo[] { signerInfo });
16
17         pkcs7.encodeSignedData(out);
18     }

好了,分析完APK包的签名流程,我们可以清楚地意识到:

1、 Android签名机制其实是对APK包完整性和发布机构唯一性的一种校验机制。

2、 Android签名机制不能阻止APK包被修改,但修改后的再签名无法与原先的签名保持一致。(拥有私钥的情况除外)。

3、 APK包加密的公钥就打包在APK包内,且不同的私钥对应不同的公钥。换句话言之,不同的私钥签名的APK公钥也必不相同。所以我们可以根据公钥的对比,来判断私钥是否一致。

APK签名比对的实现方式

好了,通过Android签名机制的分析,我们从理论上证明了通过APK公钥的比对能判断一个APK的发布机构。并且这个发布机构是很难伪装的,我们暂时可以认为是不可伪装的。

有了理论基础后,我们就可以开始实践了。那么如何获取到APK文件的公钥信息呢?因为Android系统安装程序肯定会获取APK信息进行比对,所以我们可以通过Android源码获得一些思路和帮助。

源码中有一个隐藏的类用于APK包的解析。这个类叫PackageParser,路径为frameworks\base\core\java\android\content\pm\PackageParser.java。当我们需要获取APK包的相关信息时,可以直接使用这个类,下面代码就是一个例子函数:

 

 1     private PackageInfo parsePackage(String archiveFilePath, int flags){
2
3         PackageParser packageParser = new PackageParser(archiveFilePath);
4         DisplayMetrics metrics = new DisplayMetrics();
5         metrics.setToDefaults();
6         final File sourceFile = new File(archiveFilePath);
7         PackageParser.Package pkg = packageParser.parsePackage(
8                 sourceFile, archiveFilePath, metrics, 0);
9         if (pkg == null) {
10             return null;
11         }
12
13         packageParser.collectCertificates(pkg, 0);
14
15         return PackageParser.generatePackageInfo(pkg, null, flags, 0, 0);
16     }

其中参数archiveFilePath指定APK文件路径;flags需设置PackageManager.GET_SIGNATURES位,以保证返回证书签名信息。

具体如何通过PackageParser获取签名信息在此处不做详述,具体代码请参考PackageParser中的public boolean collectCertificates(Package pkg, int flags)和private Certificate[] loadCertificates(JarFile jarFile, JarEntry je, byte[] readBuffer)方法。至于如何在Android应用开发中使用隐藏的类及方法,可以参看我的这篇文章:《Android应用开发中如何使用隐藏API》

紧接着,我们就可以通过packageInfo.signatures来访问到APK的签名信息。还需要说明的是 Android中Signature和Java中Certificate的对应关系。它们的关系如下面代码所示:

 

1     pkg.mSignatures = new Signature[certs.length];
2     for (int i=0; i<N; i++) {
3         pkg.mSignatures[i] = new Signature(
4         certs[i].getEncoded());
5     }

也就是说signature = new Signature(certificate.getEncoded()); certificate证书中包含了公钥和证书的其他基本信息。公钥不同,证书肯定互不相同。我们可以通过certificate的getPublicKey方法获取公钥信息。所以比对签名证书本质上就是比对公钥信息。

OK,获取到APK签名证书之后,就剩下比对了。这个简单,功能函数如下所示:

 1     private boolean IsSignaturesSame(Signature[] s1, Signature[] s2) {
2             if (s1 == null) {
3                 return false;
4             }
5             if (s2 == null) {
6                 return false;
7             }
8             HashSet<Signature> set1 = new HashSet<Signature>();
9             for (Signature sig : s1) {
10                 set1.add(sig);
11             }
12             HashSet<Signature> set2 = new HashSet<Signature>();
13             for (Signature sig : s2) {
14                 set2.add(sig);
15             }
16             // Make sure s2 contains all signatures in s1.
17             if (set1.equals(set2)) {
18                 return true;
19             }
20             return false;
21         }

APK签名比对的应用场景

经过以上的论述,想必大家已经明白签名比对的原理和我的实现方式了。那么什么时候什么情况适合使用签名对比来保障Android APK的软件安全呢?

个人认为主要有以下三种场景:

1、 程序自检测。在程序运行时,自我进行签名比对。比对样本可以存放在APK包内,也可存放于云端。缺点是程序被破解时,自检测功能同样可能遭到破坏,使其失效。

2、 可信赖的第三方检测。由可信赖的第三方程序负责APK的软件安全问题。对比样本由第三方收集,放在云端。这种方式适用于杀毒安全软件或者APP Market之类的软件下载市场。缺点是需要联网检测,在无网络情况下无法实现功能。(不可能把大量的签名数据放在移动设备本地)。

3、 系统限定安装。这就涉及到改Android系统了。限定仅能安装某些证书的APK。软件发布商需要向系统发布上申请证书。如果发现问题,能追踪到是哪个软件发布商的责任。适用于系统提供商或者终端产品生产商。缺点是过于封闭,不利于系统的开放性。

以上三种场景,虽然各有缺点,但缺点并不是不能克服的。例如,我们可以考虑程序自检测的功能用native method的方法实现等等。软件安全是一个复杂的课题,往往需要多种技术联合使用,才能更好的保障软件不被恶意破坏。

 

参考资料

Android源码

《Android中的签名机制》

 

 
转载请注明出处:http://www.blogjava.net/zh-weir/archive/2011/07/19/354663.html

openssl建立多级CA签发证书

平时我们自己签发CA证书再签发服务器证书的场景其实都非常简单。浏览器把自签CA导入后,就可以信任由这个CA直接签发的服务器证书。

但是实际上网站使用的证书肯定都不是由根CA直接签发的,比如

淘宝登陆服务器使用的证书。

我之前是自己写了脚本由自签CA直接签发服务器证书,为了真清楚的理解一下证书链的作用就直接使用openssl先签发2层的子CA,再由子CA去签发服务器证书。
手动签发证书的脚本如下:
生成自签CA

点击(此处)折叠或打开

  1. # cat makerootca.sh
  2. #!/bin/bash
  3. DIR=/root/ssl.test2
  4. mkdir -p $DIR/demoCA/{private,newcerts}
  5. touch $DIR/demoCA/index.txt
  6. echo 01 > $DIR/demoCA/serial
  7. openssl genrsa -des3 -out $DIR/demoCA/private/cakey.pem 2048
  8. openssl req -new -x509 -days 3650 -key $DIR/demoCA/private/cakey.pem -out $DIR/demoCA/careq.pem

签发二级CA的脚本

点击(此处)折叠或打开

  1. # cat no2domain.sh
  2. #!/bin/bash
  3. NAME=$1
  4. DIR=$(pwd)/autoget
  5. openssl genrsa -des3 -out $DIR/$NAME.key 2048
  6. openssl rsa -in $DIR/$NAME.key -out $DIR/$NAME.key
  7. openssl req -new -days 3650 -key $DIR/$NAME.key -out $DIR/$NAME.csr
  8. openssl ca -extensions v3_ca -in $DIR/$NAME.csr -config ./openssl.cnf -days 3000 -out $DIR/$NAME.crt -cert $DIR/../demoCA/careq.pem -keyfile $DIR/../demoCA/private/cakey.pem

 

sh no2domain.sh  no2

签发三级CA的脚本

点击(此处)折叠或打开

  1. # cat no3domain.sh
  2. #!/bin/bash
  3. [ $# -ne 1 ] && echo “$0 NAME” && exit
  4. NAME=$1
  5. DIR=$(pwd)/autoget
  6. openssl genrsa -des3 -out $DIR/$NAME.key 2048
  7. openssl rsa -in $DIR/$NAME.key -out $DIR/$NAME.key
  8. openssl req -new -days 3650 -key $DIR/$NAME.key -out $DIR/$NAME.csr
  9. openssl ca -in $DIR/$NAME.csr -extensions v3_ca -config ./openssl.cnf -days 3000 -out $DIR/$NAME.crt -cert $DIR/no2.crt -keyfile $DIR/no2.key

   sh no3domain.sh  no3

由三级CA签发服务器证书的脚本

点击(此处)折叠或打开

  1. # cat no4domain.sh
  2. #!/bin/bash
  3. [ $# -ne 1 ] && echo “$0 NAME” && exit
  4. NAME=$1
  5. DIR=$(pwd)/autoget
  6. openssl genrsa -des3 -out $DIR/$NAME.key 2048
  7. openssl rsa -in $DIR/$NAME.key -out $DIR/$NAME.key
  8. openssl req -new -days 3650 -key $DIR/$NAME.key -out $DIR/$NAME.csr
  9. openssl ca -in $DIR/$NAME.csr -config ./openssl.cnf -days 3000 -out $DIR/$NAME.crt -cert $DIR/no3.crt -keyfile $DIR/no3.key

 sh no4domain.sh my.domain.net

当我们把使用三级CA签发的服务器证书配置在nginx 上时,在已经导入根CA的浏览器上肯定是会遇到证书报警的,然后依次把三级CA(no3.crt  )和二级CA(no2.crt)追加到服务器证书后面,浏览器ssl链接成功,点击证书查看如下图:

Java与数字签名

本文中介绍了Java

 

数字签名的基本知识, 发布与验证过程, 数字证书的构成,各个部分的含义.

使用keytool工具生成,导入,导出数字证书的命令, 制作keystore的过程等.

使用jarsigner对jar文件进行签名的命令,过程.

使用信任签名的证书签名后的applet可以访问读写本地文件.

 

原文链接: http://www.blogjava.net/sylilzy/articles/javaadndigtalsign.html

 

sylilzy@163.com
版权所有,转载请注明出处

关键字:Java 数字签名 PKI Keystore 数字证书 keytool jarsigner

摘要:本文介绍了数字签名的相关基础知识,并介绍了如何用java实现数字签名。

字签名作为一种电子身份的认证的手段,被普遍用于网上银行,安全网络通信等领域.数字签名是电子签名的一种特定形式.本文不对数字签名的原理作介绍,只对相关概念作一些简单的介绍,详细讲解了在java中如何对jar文件进行数字签名.

数字签名的相关概念

实际上数字签名又称作基于PKI的电子签名, PKI的核心机构是电子认证服务提供者,即通称的认证机构CA,PKI签名的核心元素是由CA签发的数字证书,数字证书就如同日常生活中的身份证一样,用来标识网上实体的身份,CA就是对网上实体进行认证的第三方机构.数字证书就是CA机构对网上实体进行认证而产生的电子证书,它是数据签名的基础技术保障.CA机构对电子证书的有效性,有效期等提供查询服务.数字证书所包含公钥用来对使用对应的私钥加密的数据信息进行验证.

数字签名实现的具体原理是:
1、 将报文按双方约定的HASH算法计算得到一个固定位数的报文摘要。在数学上保证,只要改动报文中任何一位,重新计算出的报文摘要值就会与原先的值不相符。这样就保证了报文的不可更改性。(详见参考资料的”公钥密码技术原理”章节)
2、 将该报文摘要值用发送者的私人密钥加密,然后连同原报文和数字证书(包含公钥)一起发送给接收者而产生的报文即称数字签名。
3、接收方收到数字签名后,用同样的HASH算法对报文计算摘要值,然后与用发送者的公开密钥进行解密解开的报文摘要值相比较,如相等则说明报文确实来自所称的发送者。
4、同时通过证书颁发机构CA确认证书的有效性即可确认发送的真实身份。

数字证书的技术实现:
数字证书是公钥的载体,是PKI的核心元素.数字证书符合X.509标准,现行的PIK机制一般为又证书,即一个实体一般有两个证书,两个密码对,一个用于电子签名,一个用于加密通信.按照X.509标准,一个标准和数字证书的格式为:

CA《A》=CA{V,SN,AI,CA,UCA,A,UA,Ap,Ta}

它将包含证书颁发机构和标识及用户的标识,证书ID,有效期等信息(详见参考资料),另外还包含CA对此证书内容的进行了数字签名,以验证此证书的有效性.在验证一个数字证书的过程中,对数字证书的数字签名的验证将递归进行,只到找到双方共同可信任的CA根证书为止.

如何获取数字证书

数字证书可向专门的CA机构申请,有免费的数字证书和付费的数字证书.比如:中国数字认证网(http://www.ca365.com)、广东省电子商务认证中心(http://www.cnca.net/)就可申请到有效期为一年的免费数字证书.注意申请的证书是以该CA的证书作为申请的个人证书的根证书,所以如果想要申请的证书有效,需要下载并安装相应CA的根证书.另外,其它一些工具也可生成个人使用的数字证书,如微软的makecert(下载地址http://www.microsoft.com/downloads/details.aspx?familyid=2b742795-d0f0-4a66-b27f-22a95fcd3425&displaylang=en)),JDK中包含的keytool工具(以下会详细介绍如何使用)都可生成没有经过认证的数字证书.

Java如何实现数字签名

JDK有部分工具和API提供了对数字签名的支持:keytool,jarsigner,policytool等.

KeyTool工具可生成,导入,导出数字证书,支持的证书的格式为当前流行的

生成证书:keytool -genkey -alias mykey -keystore mystore

导入证书:keytool -import -alias abc -file ABCCA.cer -keystore mystore

导出证书: keytool -export -alias mykey -file MJ.cer -keystore mystore

对jar文件进行签名使用的工具是jarsigner:

格式如下:jarsigner -keystore keystoreFile jarfile alias

例如:jarsigner -keystore sylilzyKeystore.dat test.jar sylilzy

验证一个jar文件如下:

jarsigner -verify jarfile

以下步骤演示了一个完整的由获取数字证书到签名jar文件,然后访问该jar文件时显示签名信息的全过程:

上面提到,数字证书可由以下方式生成,第一,去http://www.ca365.com申请一个免费的数字证书,下载后为test.der

也可用keytool -genkey -alias mykey -keystore mystore生成,运行此命令后,提示相关信息,并填写完毕,如下:

E:\temp>keytool -genkey -alias mykey -keystore mystore
输入keystore密码: 111111
您的名字与姓氏是什么?
[Unknown]: shi
您的组织单位名称是什么?
[Unknown]: eshore
您的组织名称是什么?
[Unknown]: de
您所在的城市或区域名称是什么?
[Unknown]: gz
您所在的州或省份名称是什么?
[Unknown]: gd
该单位的两字母国家代码是什么
[Unknown]: cn
CN=shi, OU=eshore, O=de, L=gz, ST=gd, C=cn 正确吗?
[否]: y
输入<mykey>的主密码
(如果和 keystore 密码相同,按回车):

到此,我们则生成了一个名为mystore的keystore文件,该文件中保存有别名为mykey的数字证书.输入以下命令即可查看此数字证书:

E:\temp>keytool -list -alias mykey -keystore mystore
输入keystore密码: 111111
mykey, 2006-7-5, keyEntry,
认证指纹 (MD5): A1:A9:A7:C6:D8:E5:E5:20:EA:80:59:AF:C2:65:B4:17

或者带上-v参数显示详细信息

E:\temp>keytool -list -alias mykey -keystore mystore -v
输入keystore密码: 111111
别名名称: mykey
创建日期: 2006-7-5
输入类型:KeyEntry
认证链长度: 1
认证 [1]:
Owner: CN=shi, OU=eshore, O=de, L=gz, ST=gd, C=cn
发照者: CN=shi, OU=eshore, O=de, L=gz, ST=gd, C=cn
序号: 44ab3fb8
有效期间: Wed Jul 05 12:27:36 CST 2006 至: Tue Oct 03 12:27:36 CST 2006
认证指纹:
MD5: A1:A9:A7:C6:D8:E5:E5:20:EA:80:59:AF:C2:65:B4:17
SHA1: AC:8D:AA:9D:A7:62:48:70:ED:F4:28:4C:DC:DE:56:CE:41:FE:52:C9

以上为创建的一个证书,我们可以将它从keystore文件中导出:

E:\temp>keytool -export -keystore mystore -alias mykey -file my.cer
输入keystore密码: 111111
保存在文件中的认证 <my.cer>

我们也可将前面从网上申请的电子证书导入keystore文件:

E:\temp>keytool -import -alias sily -file test.der -keystore mystore
输入keystore密码: 111111
Owner: CN=施祖阳, OU=develop, O=eshore, L=广州, ST=广东, C=CN
发照者: CN=CA365 Free Root Certificate, O=CA365, L=Beijing, ST=Beijing, C=CN
序号: 653e1a63bb003fb3
有效期间: Tue Jul 04 12:02:25 CST 2006 至: Wed Jul 04 12:02:25 CST 2007
认证指纹:
MD5: 4A:AA:63:2A:8A:E2:8D:76:4B:2B:73:E9:F3:03:CD:6F
SHA1: 02:B3:9E:D0:7E:BB:9E:C4:B3:B0:79:19:FA:89:B6:93:DB:0F:4A:88
信任这个认证? [否]: y
认证已添加至keystore中

现在查看mystore中已经存了两个证书:

E:\temp>keytool -list -keystore mystore
输入keystore密码: 111111
Keystore 类型: jks
Keystore 提供者: SUN
您的 keystore 包含 2 输入
sily, 2006-7-5, trustedCertEntry,
认证指纹 (MD5): 4A:AA:63:2A:8A:E2:8D:76:4B:2B:73:E9:F3:03:CD:6F
mykey, 2006-7-5, keyEntry,
认证指纹 (MD5): A1:A9:A7:C6:D8:E5:E5:20:EA:80:59:AF:C2:65:B4:17

现在,我们开始利用前面生成的数字证书给jar文件签名.由于applet在浏览器中运行时的权限是受限的,不能对本地文件进行读写,但是如果applet所在的jar文件如果是经过数字签名,并且用户信任该签名,那此applet则可对本地文件进行读写,下面给出一个写本地文件的applet:

 

 * Created on 2004-7-16
package   com.applet;

import   java.applet.Applet;

public   class   TestSecurity   extends   Applet   {
/**
*
*/
private   static   final   long   serialVersionUID   =   1L;

public   TestSecurity()   {
System. out .println( “this is good! ” );
}

public   void   init()   {
JButton   button   =   new   JButton( “Create a file” );
button.addActionListener( new   ActionListener()   {
public   void   actionPerformed(ActionEvent   evt)   {
File   file   =   new   File( “c:\\a.txt” );
try   {
file.createNewFile();
JOptionPane. showMessageDialog ( null ,   ” 成功创建文件c:\\a.txt” ,   “消息” ,
JOptionPane. INFORMATION_MESSAGE );
}   catch   (Exception   ex)   {
JOptionPane. showMessageDialog ( null ,  ex.getMessage(),   “错误” ,   JOptionPane. ERROR_MESSAGE );
}
}
});
add(button);
}
}

 

将此文件编译后生成在com\applet生成两个class文件,用jar打包:

E:\sylilzy\documents\project\tjava\classes>jar -cvf test.jar com
标明清单(manifest)
增加:com/(读入= 0) (写出= 0)(存储了 0%)

会发现在当前目录下会生成一个”test.jar”文件,将此文件copy到与mystore同一个目录,准备对该文件进行电子签名.

E:\temp>jarsigner -keystore mystore test.jar mykey
输入密钥库的口令短语: 111111
警告: 签名者证书将在六个月内过期。

则test.jar已经被签名,编码一个简单的html文件对其进行访问,html如下:

						
Created with Colorer-take5 Library. Type 'html'

<html><head><metahttp-equiv="Content-Type"content="text/html; charset=GB2312"><title>
			HTML Test Page
		</title></head><body>
		test.Applet1 will appear below in a Java enabled browser.<br><appletcodebase="."code="com.applet.TestSecurity"name="TestApplet"width="400"height="300"hspace="0"vspace="0"align="middle"archive="test.jar"></applet></body></html>

 

将以上html文件与test.jar文件放在同一目录,用IE打开,则可看到IE弹出安全警告: The application’s digital signature is invalid.Do you want to run the application?

用户可查看test.jar的签名信息,如果选择取消息,然后点击create a file 按钮,则提示:access denied(java.io.FilePermission c:\a.txt write)

如果在IE弹出安全警告选择”始终信任此发行者的内容”,然后点击运行,再点击create a file 按钮,则提示:成功创建文件c:\a.txt

上面给test.jar签名的数字证书是未经验证的,现在我们使用从网上申请的经过验证的数字证书给test.jar签名,看会出现什么结果:

E:\temp>jarsigner -keystore mystore test.jar sily
输入密钥库的口令短语: 111111
jarsigner: 找不到 sily 的证书链。sily 必须引用包含专用密钥和相应的公共密钥证书链的有效密钥库密钥条目。

这是因为sily的证书链不存在导致的,我们需要导入sily的证书链才可形成完整的sily的证书链,可以通过keytool -certreq生成证书链的PKCS#10格式的请求,然后再导入请求的PKCS#7格式的回复即可,由于名为sily的key是从cer文件导入的,它在keystore中是以trusted certificate entries类型存储的,没有私钥,所以不能生成证书链的请求.我们可以将前面名为mykey的key导出证书请求,或者导出mykey的证书,然后将此证书安装至”受信任的根证书颁发机构”,然后访问用此证书签名过的文件,则IE将不再弹出安全警告窗口.


 

公告

参考资料:
http://www.qqread.com/net-saft/z532114081.html 电子签名的技术实现
http://www.qqread.com/java/w292768600.html JAVA对数字证书的常用操作
http://java.sun.com/j2se/1.5.0/docs/index.html JDK 5.0 Documentation

 

 

作者简介

施祖阳,网名sylilzy,1979年生。
2002年起从事软件开发工作,主要研究JAVA、Linux及相关技术。
你可通过sylilzy@163.com与作者联系。

JAVA对数字证书的常用操作

原文链接:http://www.qqread.com/java/w292768600.html
本文中介绍了使用Java对数字证书的各种操作.
包括读取证书的各项详细,对新的证书签名,验证证书是否过期,签名是否正确等信息.

一需要包含的包

import java.security.*;

import java.io.*;

import java.util.*;

import java.security.*;

import java.security.cert.*;

import sun.security.x509.*

import java.security.cert.Certificate;

import java.security.cert.CertificateFactory;

二 从文件中读取证书

用keytool将.keystore中的证书写入文件中,然后从该文件中读取证书信息

CertificateFactory cf=CertificateFactory.getInstance(“X.509”);

FileInputStream in=new FileInputStream(“out.csr”);

Certificate c=cf.generateCertificate(in); String s=c.toString();

三 从密钥库中直接读取证书

String pass=”123456″;

FileInputStream in=new FileInputStream(“.keystore”);

KeyStore ks=KeyStore.getInstance(“JKS”);

ks.load(in,pass.toCharArray());

java.security.cert.Certificate c=ks.getCertificate(alias);//alias为条目的别名

四 JAVA程序中显示证书指定信息

System.out.println(“输出证书信息:\n”+c.toString());

System.out.println(“版本号:”+t.getVersion());

System.out.println(“序列号:”+t.getSerialNumber().toString(16));

System.out.println(“主体名:”+t.getSubjectDN());

System.out.println(“签发者:”+t.getIssuerDN());

System.out.println(“有效期:”+t.getNotBefore());

System.out.println(“签名算法:”+t.getSigAlgName());

byte [] sig=t.getSignature();//签名值

PublicKey pk=t.getPublicKey();

byte [] pkenc=pk.getEncoded();

System.out.println(“公钥”);

for(int i=0;i<pkenc.length;i++)System.out.print(pkenc[i]+”,”);

五 JAVA程序列出密钥库所有条目

String pass=”123456″;

FileInputStream in=new FileInputStream(“.keystore”);

KeyStore ks=KeyStore.getInstance(“JKS”);

ks.load(in,pass.toCharArray());

Enumeration e=ks.aliases();

while(e.hasMoreElements())

java.security.cert.Certificate c=ks.getCertificate((String)e.nextElement());

六 JAVA程序修改密钥库口令

String oldpass=”123456″;

String newpass=”654321″;

FileInputStream in=new FileInputStream(“.keystore”);

KeyStore ks=KeyStore.getInstance(“JKS”);

ks.load(in,oldpass.toCharArray());

in.close();

FileOutputStream output=new FileOutputStream(“.keystore”);

ks.store(output,newpass.toCharArray());

output.close();

七 JAVA程序修改密钥库条目的口令及添加条目

FileInputStream in=new FileInputStream(“.keystore”);

KeyStore ks=KeyStore.getInstance(“JKS”);

ks.load(in,storepass.toCharArray());

Certificate [] cchain=ks.getCertificate(alias);获取别名对应条目的证书链

PrivateKey pk=(PrivateKey)ks.getKey(alias,oldkeypass.toCharArray());获取别名对应条目的私钥

ks.setKeyEntry(alias,pk,newkeypass.toCharArray(),cchain);向密钥库中添加条目

第一个参数指定所添加条目的别名,假如使用已存在别名将覆盖已存在条目,使用新别名将增加一个新条目,第二个参数为条目的私钥,第三个为设置的新口令,第四个为该私钥的公钥的证书链

FileOutputStream output=new FileOutputStream(“another”);

ks.store(output,storepass.toCharArray())将keystore对象内容写入新文件

八 JAVA程序检验别名和删除条目

FileInputStream in=new FileInputStream(“.keystore”);

KeyStore ks=KeyStore.getInstance(“JKS”);

ks.load(in,storepass.toCharArray());

ks.containsAlias(“sage”);检验条目是否在密钥库中,存在返回true

ks.deleteEntry(“sage”);删除别名对应的条目

FileOutputStream output=new FileOutputStream(“.keystore”);

ks.store(output,storepass.toCharArray())将keystore对象内容写入文件,条目删除成功

九 JAVA程序签发数字证书

(1)从密钥库中读取CA的证书

FileInputStream in=new FileInputStream(“.keystore”);

KeyStore ks=KeyStore.getInstance(“JKS”);

ks.load(in,storepass.toCharArray());

java.security.cert.Certificate c1=ks.getCertificate(“caroot”);

(2)从密钥库中读取CA的私钥

PrivateKey caprk=(PrivateKey)ks.getKey(alias,cakeypass.toCharArray());

(3)从CA的证书中提取签发者的信息

byte[] encod1=c1.getEncoded(); 提取CA证书的编码

X509CertImpl cimp1=new X509CertImpl(encod1); 用该编码创建X509CertImpl类型对象

X509CertInfo cinfo1=(X509CertInfo)cimp1.get(X509CertImpl.NAME+”.”+X509CertImpl.INFO); 获取X509CertInfo对象

X500Name issuer=(X500Name)cinfo1.get(X509CertInfo.SUBJECT+”.”+CertificateIssuerName.DN_NAME); 获取X509Name类型的签发者信息

(4)获取待签发的证书

CertificateFactory cf=CertificateFactory.getInstance(“X.509”);

FileInputStream in2=new FileInputStream(“user.csr”);

java.security.cert.Certificate c2=cf.generateCertificate(in);

(5)从待签发的证书中提取证书信息

byte [] encod2=c2.getEncoded();

X509CertImpl cimp2=new X509CertImpl(encod2); 用该编码创建X509CertImpl类型对象

X509CertInfo cinfo2=(X509CertInfo)cimp2.get(X509CertImpl.NAME+”.”+X509CertImpl.INFO); 获取X509CertInfo对象

(6)设置新证书有效期

Date begindate=new Date(); 获取当前时间

Date enddate=new Date(begindate.getTime()+3000*24*60*60*1000L); 有效期为3000天

CertificateValidity cv=new CertificateValidity(begindate,enddate); 创建对象

cinfo2.set(X509CertInfo.VALIDITY,cv); 设置有效期

(7)设置新证书序列号

int sn=(int)(begindate.getTime()/1000); 以当前时间为序列号

CertificateSerialNumber csn=new CertificateSerialNumber(sn);

cinfo2.set(X509CertInfo.SERIAL_NUMBER,csn);

(8)设置新证书签发者

cinfo2.set(X509CertInfo.ISSUER+”.”+CertificateIssuerName.DN_NAME,issuer);应用第三步的结果

(9)设置新证书签名算法信息

AlgorithmId algorithm=new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid);

cinfo2.set(CertificateAlgorithmId.NAME+”.”+CertificateAlgorithmId.ALGORITHM,algorithm);

(10)创建证书并使用CA的私钥对其签名

X509CertImpl newcert=new X509CertImpl(cinfo2);

newcert.sign(caprk,”MD5WithRSA”); 使用CA私钥对其签名

(11)将新证书写入密钥库

ks.setCertificateEntry(“lf_signed”,newcert);

FileOutputStream out=new FileOutputStream(“newstore”);

ks.store(out,”newpass”.toCharArray()); 这里是写入了新的密钥库,也可以使用第七条来增加条目

十 数字证书的检验

(1)验证证书的有效期

(a)获取X509Certificate类型对象

CertificateFactory cf=CertificateFactory.getInstance(“X.509”);

FileInputStream in1=new FileInputStream(“aa.crt”);

java.security.cert.Certificate c1=cf.generateCertificate(in1);

X509Certificate t=(X509Certificate)c1;

in2.close();

(b)获取日期

Date TimeNow=new Date();

(c)检验有效性

try{

t.checkValidity(TimeNow);

System.out.println(“OK”);

}catch(CertificateExpiredException e){ //过期

System.out.println(“Expired”);

System.out.println(e.getMessage());

}catch((CertificateNotYetValidException e){ //尚未生效

System.out.println(“Too early”);

System.out.println(e.getMessage());}

(2)验证证书签名的有效性

(a)获取CA证书

CertificateFactory cf=CertificateFactory.getInstance(“X.509”);

FileInputStream in2=new FileInputStream(“caroot.crt”);

java.security.cert.Certificate cac=cf.generateCertificate(in2);

in2.close();

(c)获取CA的公钥

PublicKey pbk=cac.getPublicKey();

(b)获取待检验的证书(上步已经获取了,就是C1)

(c)检验证书

boolean pass=false;

try{

c1.verify(pbk);

pass=true;

}catch(Exception e){

pass=false;

System.out.println(e);

}

查看apk文件的签名信息 | 证书信息 的命令

1. keytool

 

keytool -printcert -file CERT.RSA

 

keytool -printcert -file CERT.RSA Owner: EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
Issuer: EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
Serial number: 936eacbe07f201df
Valid from: Fri Feb 29 09:33:46 CST 2008 until: Tue Jul 17 09:33:46 CST 2035
Certificate fingerprints:
MD5: E8:9B:15:8E:4B:CF:98:8E:BD:09:EB:83:F5:37:8E:87
SHA1: 61:ED:37:7E:85:D3:86:A8:DF:EE:6B:86:4B:D8:5B:0B:FA:A5:AF:81
Signature algorithm name: SHA1withRSA
Version: 3

Extensions:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 48 59 00 56 3D 27 2C 46 AE 11 86 05 A4 74 19 AC HY.V=’,F…..t..
0010: 09 CA 8C 11 ….
]
]

#2: ObjectId: 2.5.29.19 Criticality=false
BasicConstraints:[
CA:true
PathLen:2147483647
]

#3: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: 48 59 00 56 3D 27 2C 46 AE 11 86 05 A4 74 19 AC HY.V=’,F…..t..
0010: 09 CA 8C 11 ….
]

[EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US]
SerialNumber: [ 936eacbe 07f201df]
]

2. jarsigner:

jarsigner -verbose -certs -verify apk文件名

jarsigner -verbose -certs -verify 9bfe0565c65dbaafe8cc6bd487b05d02812931e8

2575 Mon Jan 06 18:20:14 CST 2014 META-INF/MANIFEST.MF
2628 Mon Jan 06 18:20:14 CST 2014 META-INF/CERT.SF
1714 Mon Jan 06 18:20:14 CST 2014 META-INF/CERT.RSA
sm 884 Mon Jan 06 18:20:14 CST 2014 res/layout/term_of_use_limited.xml

X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
[certificate is valid from 2/29/08 9:33 AM to 7/17/35 9:33 AM]

sm 1162 Thu Apr 25 07:56:44 CST 2013 res/drawable-hdpi/btn_reload2.png

X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
[certificate is valid from 2/29/08 9:33 AM to 7/17/35 9:33 AM]

sm 1616 Mon Jan 06 18:20:14 CST 2014 res/layout/file_list_view_dir.xml

X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
[certificate is valid from 2/29/08 9:33 AM to 7/17/35 9:33 AM]

sm 868 Mon Jan 06 18:20:14 CST 2014 res/layout/filelist.xml

X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
[certificate is valid from 2/29/08 9:33 AM to 7/17/35 9:33 AM]

sm 1393 Thu Apr 25 07:56:44 CST 2013 res/drawable-hdpi/btn_square_overlay_normal.png

X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
[certificate is valid from 2/29/08 9:33 AM to 7/17/35 9:33 AM]

sm 18616 Mon Jan 06 18:20:14 CST 2014 resources.arsc

X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
[certificate is valid from 2/29/08 9:33 AM to 7/17/35 9:33 AM]

sm 1877 Thu Apr 25 07:56:44 CST 2013 res/drawable-hdpi/btn_star_big_off_selected.png

X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
[certificate is valid from 2/29/08 9:33 AM to 7/17/35 9:33 AM]

sm 1744 Mon Jan 06 18:20:14 CST 2014 res/layout/listitem.xml

X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
[certificate is valid from 2/29/08 9:33 AM to 7/17/35 9:33 AM]

sm 776 Mon Jan 06 18:20:14 CST 2014 res/xml/setting.xml

X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
[certificate is valid from 2/29/08 9:33 AM to 7/17/35 9:33 AM]

sm 9648 Mon Jan 06 18:20:14 CST 2014 AndroidManifest.xml

X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
[certificate is valid from 2/29/08 9:33 AM to 7/17/35 9:33 AM]

sm 2378 Thu Apr 25 07:56:44 CST 2013 res/drawable-ldpi/icon.png

X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
[certificate is valid from 2/29/08 9:33 AM to 7/17/35 9:33 AM]

sm 4421 Thu Apr 25 07:56:44 CST 2013 res/drawable-mdpi/icon.png

X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
[certificate is valid from 2/29/08 9:33 AM to 7/17/35 9:33 AM]

sm 868 Mon Jan 06 18:20:14 CST 2014 res/layout/bookmark.xml

X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
[certificate is valid from 2/29/08 9:33 AM to 7/17/35 9:33 AM]

sm 928 Mon Jan 06 18:20:14 CST 2014 res/layout/file_list_view.xml

X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
[certificate is valid from 2/29/08 9:33 AM to 7/17/35 9:33 AM]

sm 1226 Thu Apr 25 07:56:44 CST 2013 res/drawable-hdpi/btn_reload1.png

X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
[certificate is valid from 2/29/08 9:33 AM to 7/17/35 9:33 AM]

sm 1308 Mon Jan 06 18:20:14 CST 2014 res/layout/make_save_dir.xml

X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
[certificate is valid from 2/29/08 9:33 AM to 7/17/35 9:33 AM]

sm 1749 Thu Apr 25 07:56:44 CST 2013 res/drawable-hdpi/ic_menu_forward.png

X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
[certificate is valid from 2/29/08 9:33 AM to 7/17/35 9:33 AM]

sm 480 Mon Jan 06 18:20:14 CST 2014 res/xml/policies.xml

X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
[certificate is valid from 2/29/08 9:33 AM to 7/17/35 9:33 AM]

sm 126 Thu Apr 25 07:56:44 CST 2013 res/drawable-hdpi/btn_close_normal.png

X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
[certificate is valid from 2/29/08 9:33 AM to 7/17/35 9:33 AM]

sm 2925 Thu Apr 25 07:56:44 CST 2013 res/drawable-hdpi/ic_menu_refresh.png

X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
[certificate is valid from 2/29/08 9:33 AM to 7/17/35 9:33 AM]

sm 1378 Thu Apr 25 07:56:44 CST 2013 res/drawable-hdpi/btn_star1.png

X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
[certificate is valid from 2/29/08 9:33 AM to 7/17/35 9:33 AM]

sm 188988 Mon Jan 06 18:20:14 CST 2014 classes.dex

X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
[certificate is valid from 2/29/08 9:33 AM to 7/17/35 9:33 AM]

sm 580 Mon Jan 06 18:20:14 CST 2014 res/layout/download.xml

X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
[certificate is valid from 2/29/08 9:33 AM to 7/17/35 9:33 AM]

sm 2828 Mon Jan 06 18:20:14 CST 2014 res/layout/main.xml

X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
[certificate is valid from 2/29/08 9:33 AM to 7/17/35 9:33 AM]

sm 1232 Mon Jan 06 18:20:14 CST 2014 res/layout/filelistitem.xml

X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
[certificate is valid from 2/29/08 9:33 AM to 7/17/35 9:33 AM]

sm 1415 Thu Apr 25 07:56:44 CST 2013 res/drawable-hdpi/ic_menu_archive.png

X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
[certificate is valid from 2/29/08 9:33 AM to 7/17/35 9:33 AM]

sm 1273 Thu Apr 25 07:56:44 CST 2013 res/drawable-hdpi/btn_star2.png

X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
[certificate is valid from 2/29/08 9:33 AM to 7/17/35 9:33 AM]

sm 116 Mon Jan 06 18:20:14 CST 2014 res/raw/settings.json

X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
[certificate is valid from 2/29/08 9:33 AM to 7/17/35 9:33 AM]

sm 884 Mon Jan 06 18:20:14 CST 2014 res/layout/term_of_use.xml

X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
[certificate is valid from 2/29/08 9:33 AM to 7/17/35 9:33 AM]

sm 1232 Mon Jan 06 18:20:14 CST 2014 res/layout/bookmarklistitem.xml

X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
[certificate is valid from 2/29/08 9:33 AM to 7/17/35 9:33 AM]

sm 8327 Thu Apr 25 07:56:44 CST 2013 res/drawable-hdpi/icon.png

X.509, EMAILADDRESS=android@android.com, CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
[certificate is valid from 2/29/08 9:33 AM to 7/17/35 9:33 AM]
s = signature was verified
m = entry is listed in manifest
k = at least one certificate was found in keystore
i = at least one certificate was found in identity scope

jar verified.

keytool命令详解

 

转自http://hi.baidu.com/qianshuifanchuan/blog/item/6291b8510009ad3c42a75b8e.html

Keytool是一个Java数据证书的管理工具 ,Keytool将密钥(key)和证书(certificates)存在一个称为keystore的文件中在keystore里,包含两种数据:

密钥实体(Key entity)——密钥(secret key)又或者是私钥和配对公钥(采用非对称加密)

可信任的证书实体(trusted certificate entries)——只包含公钥

ailas(别名)每个keystore都关联这一个独一无二的alias,这个alias通常不区分大小写

 

JDK中keytool常用命令:

-genkey      在用户主目录中创建一个默认文件”.keystore”,还会产生一个mykey的别名,mykey中包含用户的公钥、私钥和证书

(在没有指定生成位置的情况下,keystore会存在用户系统默认目录,如:对于window xp系统,会生成在系统的C:\Documents and Settings\UserName\文件名为“.keystore”)

-alias       产生别名

-keystore    指定密钥库的名称(产生的各类信息将不在.keystore文件中)

-keyalg      指定密钥的算法 (如 RSA  DSA(如果不指定默认采用DSA))

-validity    指定创建的证书有效期多少天

-keysize     指定密钥长度

-storepass   指定密钥库的密码(获取keystore信息所需的密码)

-keypass     指定别名条目的密码(私钥的密码)

-dname       指定证书拥有者信息 例如:  “CN=名字与姓氏,OU=组织单位名称,O=组织名称,L=城市或区域名称,ST=州或省份名称,C=单位的两字母国家代码”

-list        显示密钥库中的证书信息      keytool -list -v -keystore 指定keystore -storepass 密码

-v           显示密钥库中的证书详细信息

-export      将别名指定的证书导出到文件  keytool -export -alias 需要导出的别名 -keystore 指定keystore -file 指定导出的证书位置及证书名称 -storepass 密码

-file        参数指定导出到文件的文件名

-delete      删除密钥库中某条目          keytool -delete -alias 指定需删除的别  -keystore 指定keystore  -storepass 密码

-printcert   查看导出的证书信息          keytool -printcert -file yushan.crt

-keypasswd   修改密钥库中指定条目口令    keytool -keypasswd -alias 需修改的别名 -keypass 旧密码 -new  新密码  -storepass keystore密码  -keystore sage

-storepasswd 修改keystore口令      keytool -storepasswd -keystore e:\yushan.keystore(需修改口令的keystore) -storepass 123456(原始密码) -new yushan(新密码)

-import      将已签名数字证书导入密钥库  keytool -import -alias 指定导入条目的别名 -keystore 指定keystore -file 需导入的证书

 

下面是各选项的缺省值。

-alias “mykey”

-keyalg “DSA”

-keysize 1024

-validity 90

-keystore 用户宿主目录中名为 .keystore 的文件

-file 读时为标准输入,写时为标准输出

1、keystore的生成:

分阶段生成:

keytool -genkey -alias yushan(别名) -keypass yushan(别名密码) -keyalg RSA(算法) -keysize 1024(密钥长度) -validity 365(有效期,天单位) -keystore

e:\yushan.keystore(指定生成证书的位置和证书名称) -storepass 123456(获取keystore信息的密码);回车输入相关信息即可;

一次性生成:

keytool -genkey -alias yushan -keypass yushan -keyalg RSA -keysize 1024 -validity 365 -keystore  e:\yushan.keystore -storepass 123456 -dname “CN=(名字与

姓氏), OU=(组织单位名称), O=(组织名称), L=(城市或区域名称), ST=(州或省份名称), C=(单位的两字母国家代码)”;(中英文即可)

2、keystore信息的查看:

keytool -list  -v -keystore e:\keytool\yushan.keystore -storepass 123456

显示内容:

———————————————————————

Keystore 类型: JKS

Keystore 提供者: SUN

您的 keystore 包含 1 输入

别名名称: yushan

创建日期: 2009-7-29

项类型: PrivateKeyEntry

认证链长度: 1

认证 [1]:

所有者:CN=yushan, OU=xx公司, O=xx协会, L=湘潭, ST=湖南, C=中国

签发人:CN=yushan, OU=xx公司, O=xx协会, L=湘潭, ST=湖南, C=中国

序列号:4a6f29ed

有效期: Wed Jul 29 00:40:13 CST 2009 至Thu Jul 29 00:40:13 CST 2010

证书指纹:

MD5:A3:D7:D9:74:C3:50:7D:10:C9:C2:47:B0:33:90:45:C3

SHA1:2B:FC:9E:3A:DF:C6:C4:FB:87:B8:A0:C6:99:43:E9:4C:4A:E1:18:E8

签名算法名称:SHA1withRSA

版本: 3

——————————————————————–

 

缺省情况下,-list 命令打印证书的 MD5 指纹。而如果指定了 -v 选项,将以可读格式打印证书,如果指定了 -rfc 选项,将以可打印的编码格式输出证书。

 

keytool -list  -rfc -keystore e:\yushan.keystore -storepass 123456

显示:

——————————————————————————————————-

Keystore 类型: JKS

Keystore 提供者: SUN

您的 keystore 包含 1 输入

别名名称: yushan

创建日期: 2009-7-29

项类型: PrivateKeyEntry

认证链长度: 1

认证 [1]:

—–BEGIN CERTIFICATE—–

MIICSzCCAbSgAwIBAgIESm8p7TANBgkqhkiG9w0BAQUFADBqMQ8wDQYDVQQGDAbkuK3lm70xDzAN

BgNVBAgMBua5luWNlzEPMA0GA1UEBwwG5rmY5r2tMREwDwYDVQQKDAh4eOWNj+S8mjERMA8GA1UE

CwwIeHjlhazlj7gxDzANBgNVBAMTBnl1c2hhbjAeFw0wOTA3MjgxNjQwMTNaFw0xMDA3MjgxNjQw

MTNaMGoxDzANBgNVBAYMBuS4reWbvTEPMA0GA1UECAwG5rmW5Y2XMQ8wDQYDVQQHDAbmuZjmva0x

ETAPBgNVBAoMCHh45Y2P5LyaMREwDwYDVQQLDAh4eOWFrOWPuDEPMA0GA1UEAxMGeXVzaGFuMIGf

MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCJoru1RQczRzTnBWxefVNspQBykS220rS8Y/oX3mZa

hjL4wLfOURzUuxxuVQR2jx7QI+XKME+DHQj9r6aAcLBCi/T1jwF8mVYxtpRuTzE/6KEZdhowEe70

liWLVE+hytLBHZ03Zhwcd6q5HUMu27du3MPQvqiwzTY7MrwIvQQ8iQIDAQABMA0GCSqGSIb3DQEB

BQUAA4GBAGoQQ1/FnTfkpQh+Ni6h3fZdn3sR8ZzDMbOAIYVLAhBb85XDJ8QZTarHbZMJcIdHxAl1

i08ct3E8U87V9t8GZFWVC4BFg/+zeFEv76SFpVE56iX7P1jpsu78z0m69hHlds77VJTdyfMSvtXv

sYHP3fxfzx9WyhipBwd8VPK/NgEP

—–END CERTIFICATE—–

——————————————————————————————————-

3、证书的导出:

keytool -export -alias yushan -keystore e:\yushan.keystore -file e:\yushan.crt(指定导出的证书位置及证书名称) -storepass 123456

4、查看导出的证书信息

keytool -printcert -file yushan.crt

显示:(在windows下可以双击yushan.crt查看)

———————————————————————–

所有者:CN=yushan, OU=xx公司, O=xx协会, L=湘潭, ST=湖南, C=中国

签发人:CN=yushan, OU=xx公司, O=xx协会, L=湘潭, ST=湖南, C=中国

序列号:4a6f29ed

有效期: Wed Jul 29 00:40:13 CST 2009 至Thu Jul 29 00:40:13 CST 2010

证书指纹:

MD5:A3:D7:D9:74:C3:50:7D:10:C9:C2:47:B0:33:90:45:C3

SHA1:2B:FC:9E:3A:DF:C6:C4:FB:87:B8:A0:C6:99:43:E9:4C:4A:E1:18:E8

签名算法名称:SHA1withRSA

版本: 3

———————————————————————–

5、证书的导入:

准备一个导入的证书:

keytool -genkey -alias shuany -keypass shuany -keyalg RSA -keysize 1024 -validity 365 -keystore  e:\shuany.keystore -storepass 123456 -dname “CN=shuany,

OU=xx, O=xx, L=xx, ST=xx, C=xx”;

keytool -export -alias shuany -keystore e:\shuany.keystore -file e:\shuany.crt -storepass 123456

 

现在将shuany.crt 加入到yushan.keystore中:

keytool -import -alias shuany(指定导入证书的别名,如果不指定默认为mykey,别名唯一,否则导入出错) -file e:\shuany.crt -keystore e:\yushan.keystore -storepass

123456

keytool -list  -v -keystore e:\keytool\yushan.keystore -storepass 123456

显示:

——————————————————————————

Keystore 类型: JKS

Keystore 提供者: SUN

您的 keystore 包含 2 输入

别名名称: yushan

创建日期: 2009-7-29

项类型: PrivateKeyEntry

认证链长度: 1

认证 [1]:

所有者:CN=yushan, OU=xx公司, O=xx协会, L=湘潭, ST=湖南, C=中国

签发人:CN=yushan, OU=xx公司, O=xx协会, L=湘潭, ST=湖南, C=中国

序列号:4a6f29ed

有效期: Wed Jul 29 00:40:13 CST 2009 至Thu Jul 29 00:40:13 CST 2010

证书指纹:

MD5:A3:D7:D9:74:C3:50:7D:10:C9:C2:47:B0:33:90:45:C3

SHA1:2B:FC:9E:3A:DF:C6:C4:FB:87:B8:A0:C6:99:43:E9:4C:4A:E1:18:E8

签名算法名称:SHA1withRSA

版本: 3

*******************************************

*******************************************

别名名称: shuany

创建日期: 2009-7-29

输入类型: trustedCertEntry

所有者:CN=shuany, OU=xx, O=xx, L=xx, ST=xx, C=xx

签发人:CN=shuany, OU=xx, O=xx, L=xx, ST=xx, C=xx

序列号:4a6f2cd9

有效期: Wed Jul 29 00:52:41 CST 2009 至Thu Jul 29 00:52:41 CST 2010

证书指纹:

MD5:15:03:57:9B:14:BD:C5:50:21:15:47:1E:29:87:A4:E6

SHA1:C1:4F:8B:CD:5E:C2:94:77:B7:42:29:35:5C:BB:BB:2E:9E:F0:89:F5

签名算法名称:SHA1withRSA

版本: 3

*******************************************

*******************************************

——————————————————————————

6、证书条目的删除:

keytool -delete -alias shuany(指定需删除的别名) -keystore yushan.keystore -storepass 123456

 

7、证书条目口令的修改:

keytool -keypasswd -alias yushan(需要修改密码的别名) -keypass yushan(原始密码) -new 123456(别名的新密码)  -keystore e:\yushan.keystore -storepass 123456

8、keystore口令的修改:

keytool -storepasswd -keystore e:\yushan.keystore(需修改口令的keystore) -storepass 123456(原始密码) -new yushan(新密码)

 

9、修改keystore中别名为yushan的信息

 

keytool -selfcert -alias yushan -keypass yushan -keystore e:\yushan.keystore -storepass 123456 -dname “cn=yushan,ou=yushan,o=yushan,c=us”