数字签名的一些总结
来源:互联网 发布:淘宝海外 全球站入驻 编辑:程序博客网 时间:2024/05/02 08:38
数字签名和数字证书是什么
下面通过一些图片通俗易懂的解释一下什么是数字签名(digital signature)和数字证书(digital certificate)。
1.
鲍勃有两把钥匙,一把是公钥,另一把是私钥。
2.
鲍勃把公钥送给他的朋友们----帕蒂、道格、苏珊----每人一把。
3.
苏珊要给鲍勃写一封保密的信。她写完后用鲍勃的公钥加密,就可以达到保密的效果。
4.
鲍勃收信后,用私钥解密,就看到了信件内容。这里要强调的是,只要鲍勃的私钥不泄露,这封信就是安全的,即使落在别人手里,也无法解密。
5.
鲍勃给苏珊回信,决定采用"数字签名"。他写完后先用Hash函数,生成信件的摘要(digest)。
6.
然后,鲍勃使用私钥,对这个摘要加密,生成"数字签名"(signature)。
7.
鲍勃将这个签名,附在信件下面,一起发给苏珊。
8.
苏珊收信后,取下数字签名,用鲍勃的公钥解密,得到信件的摘要。由此证明,这封信确实是鲍勃发出的(因为鲍勃的公钥可以解密)。
9.
苏珊再对信件本身使用Hash函数,将得到的结果,与上一步得到的摘要进行对比。如果两者一致,就证明这封信未被修改过。
10.
复杂的情况出现了。道格想欺骗苏珊,他偷偷使用了苏珊的电脑,用自己的公钥换走了鲍勃的公钥。此时,苏珊实际拥有的是道格的公钥,但是还以为这是鲍勃的公钥。因此,道格就可以冒充鲍勃,用自己的私钥做成"数字签名",写信给苏珊,让苏珊用假的鲍勃公钥进行解密。
11.
后来,苏珊感觉不对劲,发现自己无法确定公钥是否真的属于鲍勃。她想到了一个办法,要求鲍勃去找"证书中心"(certificate authority,简称CA),为公钥做认证。证书中心用自己的私钥,对鲍勃的公钥和一些相关信息一起加密,生成"数字证书"(Digital Certificate)。
12.
鲍勃拿到数字证书以后,就可以放心了。以后再给苏珊写信,只要在签名的同时,再附上数字证书就行了。
13.
苏珊收信后,用CA的公钥解开数字证书,就可以拿到鲍勃真实的公钥了,然后就能证明"数字签名"是否真的是鲍勃签的。
需要注意的是:
- 发送方和接收方使用Hash算法需要双方实现约定好。
- 数字证书是公钥的载体,同时包含证书颁发机构和标识及用户的标识,证书ID,有效期等信息(详见参考资料),另外还包含CA对此证书内容的进行了数字签名,以验证此证书的有效性.在验证一个数字证书的过程中,对数字证书的数字签名的验证将递归进行,只到找到双方共同可信任的CA根证书为止。
14.
下面,我们看一个应用"数字证书"的实例:https协议。这个协议主要用于网页加密。
15.
首先,客户端向服务器发出加密请求。
16.
服务器用自己的私钥加密网页以后,连同本身的数字证书,一起发送给客户端。
17.
客户端(浏览器)的"证书管理器",有"受信任的根证书颁发机构"列表。客户端会根据这张列表,查看解开数字证书的公钥是否在列表之内。
18.
如果数字证书记载的网址,与你正在浏览的网址不一致,就说明这张证书可能被冒用,浏览器会发出警告。
19.
如果这张数字证书不是由受信任的机构颁发的,浏览器会发出另一种警告。
20.
如果数字证书是可靠的,客户端就可以使用证书中的服务器公钥,对信息进行加密,然后与服务器交换加密信息。如何获取数字证书
1向CA机构申请
数字证书可向专门的CA机构申请,有免费的数字证书和付费的数字证书.比如:中国数字认证网(http://www.ca365.com)、广东省电子商务认证中心(http://www.cnca.net/)就可申请到有效期为一年的免费数字证书.注意申请的证书是以该CA的证书作为申请的个人证书的根证书,所以如果想要申请的证书有效,需要下载并安装相应CA的根证书.
2.使用工具制作
通过一些工具也可生成个人使用的数字证书,如微软的makecert(下载地址http://www.microsoft.com/downloads/details.aspx?familyid=2b742795-d0f0-4a66-b27f-22a95fcd3425&displaylang=en)),JDK中包含的keytool工具(以下会详细介绍如何使用)都可生成没有经过认证的数字证书.
如何实现签名
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
1.制作证书
使用keytool -genkey -alias mykey -keystore mystore生成密钥库mystore,提示相关信息,并填写完毕,如下:
E:\downloads\qm>keytool -genkey -alias mykey -keystore mystore输入密钥库口令:再次输入新口令:您的名字与姓氏是什么? [Unknown]: david您的组织单位名称是什么? [Unknown]: zte您的组织名称是什么? [Unknown]: zte您所在的城市或区域名称是什么? [Unknown]: chengdu您所在的省/市/自治区名称是什么? [Unknown]: chengdu该单位的双字母国家/地区代码是什么? [Unknown]: cnCN=david, OU=zte, O=zte, L=chengdu, ST=chengdu, C=cn是否正确? [否]: y输入 <mykey> 的密钥口令 (如果和密钥库口令相同, 按回车):执行命令后,生成了一个名为mystore的keystore文件(即密钥库),该文件中保存有别名为mykey的数字证书.输入以下命令即可查看此数字证书:
E:\downloads\qm>keytool -list -alias mykey -keystore mystore输入密钥库口令:mykey, 2014-12-30, PrivateKeyEntry,证书指纹 (SHA1): 31:48:02:41:F8:23:6D:C5:C5:12:F3:AF:5C:56:EA:10:FF:5E:88:3A
或者带上-v参数显示详细信息
E:\downloads\qm>keytool -list -alias mykey -keystore mystore -v输入密钥库口令:别名: mykey创建日期: 2014-12-30条目类型: PrivateKeyEntry证书链长度: 1证书[1]:所有者: CN=david, OU=zte, O=zte, L=chengdu, ST=chengdu, C=cn发布者: CN=david, OU=zte, O=zte, L=chengdu, ST=chengdu, C=cn序列号: 6a66cb4f有效期开始日期: Tue Dec 30 21:27:34 CST 2014, 截止日期: Mon Mar 30 21:27:34 CST 2015证书指纹: MD5: 96:B7:72:70:BC:37:25:AF:F6:28:D9:F0:C3:54:7B:4C SHA1: 31:48:02:41:F8:23:6D:C5:C5:12:F3:AF:5C:56:EA:10:FF:5E:88:3A SHA256: 43:1A:76:13:EA:10:22:C3:3E:E8:6A:8A:CF:4F:8E:D1:6D:30:F7:70:83:0C:04:F2:3D:30:E7:2E:95:B4:A6:57 签名算法名称: SHA1withDSA 版本: 3扩展:#1: ObjectId: 2.5.29.14 Criticality=falseSubjectKeyIdentifier [KeyIdentifier [0000: 37 E5 48 80 6F 92 9C FC 33 54 17 F6 B3 15 8C A6 7.H.o...3T......0010: A9 EE 51 38 ..Q8]]
从mysore文件中导出数字证书mykey
E:\downloads\qm>keytool -export -keystore mystore -alias mykey -file my.cer输入密钥库口令:存储在文件 <my.cer> 中的证书导出的数字证书保存在my.cer文件中,如下图所示:
2. 为jar包签名
创建一个java工程testPro, 并新建一个com.test.Demo.java类,文件内容如下:
package com.test;public class Demo {public static void main(String[] args) {System.out.println("Hello World...");}}
将java工程打成jar包,testPro.jar,查看testPro.jar目录:
执行jarsigner -keystore mystore test.jar mykey对jar包进行签名
E:\downloads\qm>jarsigner -keystore mystore testPro.jar mykey输入密钥库的密码短语:警告:签名者证书将在六个月内过期。
命令中,mystore是密钥库名称,mykey是证书的别名。因为没有指定密钥库的路径,所以只需要将密钥库和jar放在同一个目录下即可。
再次查看签名后的testPro.jar的\META-INF\目录,发现多出了两个文件,如下所示:
打开MYKEY.SF文件,内容如下:
Signature-Version: 1.0SHA-256-Digest-Manifest-Main-Attributes: VmrRqAIgAm0FCZViZFzpaP8OfDbN4 iY0MyYFuzTMPv8=SHA-256-Digest-Manifest: +zYfr3FMJyM4p20Z0bcD6cxLfVnJ5XX3WdhzdMS504M=Created-By: 1.7.0_17 (Oracle Corporation)Name: com/test/Demo.classSHA-256-Digest: MjNJ1FhRBN7804+sO9ot/hn90NTUou87EoHmbi0Wcxk=Name: .classpathSHA-256-Digest: WYUpd+cq82OtrX/UYH3DGBM8E7v1AMR8LyKzH+H65do=Name: .projectSHA-256-Digest: We2148LlKL7eojW3PKQNfCOkEcy3fA3dKVWd5MJdDWI=
从MYKEY.SF文件的内容可以看出,签名时分别为testPro.jar中Demo.class、.classpath和.project三个文件生成摘要
执行Demo类,运行结果如下:
E:\downloads\qm>java -classpath testPro.jar com.test.DemoHello World...
如果我们修改MYKEY.SF文件中的任何摘要信息,如把
Name: .projectSHA-256-Digest: We2148LlKL7eojW3PKQNfCOkEcy3fA3dKVWd5MJdDWI=改成
Name: .projectSHA-256-Digest: We2148LlKL7eojW3PKQNfCOkEcy3fA3dKVWd5MJdDWI再次执行Demo类结果如下:
E:\downloads\qm>java -classpath testPro.jar com.test.DemoException in thread "main" java.lang.SecurityException: cannot verify signature block file META-INF/MYKEY at sun.security.util.SignatureFileVerifier.processImpl(SignatureFileVerifier.java:220) at sun.security.util.SignatureFileVerifier.process(SignatureFileVerifier.java:193) at java.util.jar.JarVerifier.processEntry(JarVerifier.java:262) at java.util.jar.JarVerifier.update(JarVerifier.java:216) at java.util.jar.JarFile.initializeVerifier(JarFile.java:345) at java.util.jar.JarFile.getInputStream(JarFile.java:412) at sun.misc.URLClassPath$JarLoader$2.getInputStream(URLClassPath.java:752) at sun.misc.Resource.cachedInputStream(Resource.java:77) at sun.misc.Resource.getByteBuffer(Resource.java:160) at java.net.URLClassLoader.defineClass(URLClassLoader.java:436) at java.net.URLClassLoader.access$100(URLClassLoader.java:71) at java.net.URLClassLoader$1.run(URLClassLoader.java:361) at java.net.URLClassLoader$1.run(URLClassLoader.java:355) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:354) at java.lang.ClassLoader.loadClass(ClassLoader.java:423) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:356) at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:482)或者将testPro中的Demo文件的内容修改成如下:
package com.test;public class Demo {public static void main(String[] args) {System.out.println("Hello World...");}}即第6行增加了一个空行,重新生成class文件放入testPro.jar,替换原有的Demo.class文件,重新执行Demo,将报如下错误信息:
E:\downloads\qm>java -classpath testPro.jar com.test.DemoException in thread "main" java.lang.SecurityException: SHA-256 digest error for com/test/Demo.class at sun.security.util.ManifestEntryVerifier.verify(ManifestEntryVerifier.java:220) at java.util.jar.JarVerifier.processEntry(JarVerifier.java:229) at java.util.jar.JarVerifier.update(JarVerifier.java:216) at java.util.jar.JarVerifier$VerifierStream.read(JarVerifier.java:471) at sun.misc.Resource.getBytes(Resource.java:124) at java.net.URLClassLoader.defineClass(URLClassLoader.java:444) at java.net.URLClassLoader.access$100(URLClassLoader.java:71) at java.net.URLClassLoader$1.run(URLClassLoader.java:361) at java.net.URLClassLoader$1.run(URLClassLoader.java:355) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:354) at java.lang.ClassLoader.loadClass(ClassLoader.java:423) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:356) at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:482)通过签名对jar文件签名,这样就防止被人恶意修改jar文件破坏运行程序,因为一旦jar文件被修改,我们在调用jar中程序时就会抛出安全异常,就知道jar被人修改了。
下面keytool的命令详解附在这里:
Keytool是一个Java数据证书的管理工具,Keytool将密钥(key)和证书(certificates)存在一个称为keystore的文件中在keystore里,包含两种数据:
密钥实体(Key entity)——密钥(secret key)又或者是私钥和配对公钥(采用非对称加密)
可信任的证书实体(trusted certificate entries)——只包含公钥
ailas(别名)每个keystore都关联这一个独一无二的alias,这个alias通常不区分大小写
JDK中keytool常用命令:
-genkey 在用户主目录中创建一个默认文件".keystore",还会产生一个mykey的别名,mykey中包含用户的公钥、私钥和证书
-alias 产生别名
-keystore 指定密钥库的名称(产生的各类信息将不在.keystore文件中
-keyalg 指定密钥的算法
-validity 指定创建的证书有效期多少天
-keysize 指定密钥长度
-storepass 指定密钥库的密码
-keypass 指定别名条目的密码
-dname 指定证书拥有者信息 例如: "CN=sagely,OU=atr,O=szu,L=sz,ST=gd,C=cn"
-list 显示密钥库中的证书信息 keytool -list -v -keystore sage -storepass ....
-v 显示密钥库中的证书详细信息
-export 将别名指定的证书导出到文件 keytool -export -alias caroot -file caroot.crt
-file 参数指定导出到文件的文件名
-delete 删除密钥库中某条目 keytool -delete -alias sage -keystore sage
-keypasswd 修改密钥库中指定条目口令 keytool -keypasswd -alias sage -keypass .... -new .... -storepass ... -keystore sage
-import 将已签名数字证书导入密钥库 keytool -import -alias sage -keystore sagely -file sagely.crt
导入已签名数字证书用keytool -list -v 以后可以明显发现多了认证链长度,并且把整个CA链全部打印出来。
------------------------------------------------------------------------------------------------
keytool JAVA是个密钥和证书管理工具。它使用户能够管理自己的公钥/私钥对及相关证书,用于(通过数字签名)自我认证(用户向别的用户/服务认证自己)或数据完整性以及认证服务。它还允许用户储存他们的通信对等者的公钥(以证书形式)。通过keytool –help查看其用法,详细信息可以参考http: //java.sun.com/j2se/1.5.0/docs/tooldocs/solaris/keytool.html
创建证书Java 中的 keytool.exe (位于 JDK/Bin 目录下)可以用来创建数字证书,所有的数字证书是以一条一条(采用别名区别)的形式存入证书库的中,证书库中的一条证书包含该条证书的私钥,公钥和对应的数字证书的信息。证书库中的一条证书可以导出数字证书文件,数字证书文件只包括主体信息和对应的公钥。
每一个证书库是一个文件组成,它有访问密码,在首次创建时,它会自动生成证书库,并要求指定访问证书库的密码。
在创建证书的的时候,需要填写证书的一些信息和证书对应的私钥密码。这些信息包括 CN=xx,OU=xx,O=xx,L=xx,ST=xx,C=xx,它们的意思是:
? CN(Common Name - 名字与姓氏):其实这个“名字与姓氏”应该是域名,比如说localhost或是blog.devep.net之类的。输成了姓名,和真正运行的时候域名不符,会出问题。浏览器访问时,弹出一个对话框,提示“安全证书上的名称无效,或者与站点名称不匹配”,用户选择继续还是可以浏览网页。但是用http client写程序访问的时候,会抛出类似于“javax.servlet.ServletException: HTTPS hostname wrong: should be ”的异常。
? OU(Organization Unit - 组织单位名称)
? O(Organization - 组织名称)
? L(Locality - 城市或区域名称)
? ST(State - 州或省份名称)
? C(Country - 国家名称)
可以采用交互式让工具提示输入以上信息,也可以采用参数,如:-dname “CN=xx,OU=xx,O=xx,L=xx,ST=xx,C=xx”来自动创建。
创建一个证书
指定证书库(又称密钥库)为 D:/keystore/test,创建别名为 Tomcat 的一条证书,它指定用 RSA 算法生成,且指定密钥长度为 1024,证书有效期为 1 年:
keytool -genkey -alias Tomcat -keyalg RSA -keysize 1024 -keystore C:/keystore/test -validity 365
显示证书库中的证书使用如下命令: keytool -list -keystore C:/keystore/test 将显示 C:/keystore/test 证书库的的所有证书列表
导出到证书文件
使用命令:keytool -export -alias Tomcat -file C:/keystore/TC.cer -keystore C:/keystore/test 将把证书库C:/keystore/test 中的别名为 Tomcat 的证书导出到 TC.cer 证书文件中,它包含证书主体的信息及证书的公钥,不包括私钥,可以公开。
导出的证书文件是以二进制编码文件,无法用文本编辑器正确显示,可以加上 -rfc参数以一种可打印的编者编码输出。 如:
keytool -export -alias Tomcat -file C:/keystore/TC.cer -keystore C:/keystore/test –rfc
查看证书的信息
通过命令: keytool -printcert -file D:/keystore/TC.cer 可以查看证书文件的信息。 也可以在 Windows 资源管理器中双击产生的证书文件直接查看。
删除密钥库中的条目
keytool -delete -alias Tomcat -keystore C:/keystore/test
这条命令将 C:/keystore/test 库中的 Tomcat 这一条证书删除了。
修改证书条目口令
keytool -keypasswd -alias Tomcat -keystore C:/keystore/test,可以以交互的方式修改 C:/keystore/test 证书库中的条目为 Tomcat 的证书。
Keytool -keypasswd -alias Tomcat -keypass oldpasswd -new newpasswd -storepass storepasswd -keystore C:/keystore/test 这一行命令以非交互式的方式修改库中别名为 Tomcat 的证书的密码为新密码 newpasswd,行中的 oldpasswd 是指该条证书的原密码, storepasswd 是指证书库的密码。
- 数字签名的一些总结
- 苹果数字签名的一些问题
- 关于数字证书和数字签名的一些认识
- 数字签名和数字证书的学习总结
- FastReport的一些总结
- 事务的一些总结
- BOM 的一些总结
- FastReport的一些总结
- jxl的一些总结
- 项目的一些总结
- 一些问题的总结
- 多线程的一些总结
- cookie的一些总结
- HasCode的一些总结
- dom4j的一些总结
- 一些细致的总结
- QTableWidget的一些总结
- const的一些总结
- Andrej Karpathy的CVPR 2013 reading list
- :与::
- mysql select
- [Python]利用soaplib访问webservice的实例代码
- 数据分析开发
- 数字签名的一些总结
- [Python]网络爬虫(三):异常的处理和HTTP状态码的分类
- 设计模式培训之五:代理模式
- 成都地图
- jre运行成功
- 如何创意优质的广告语
- 正则表达式30分钟入门教程
- SQL update select结合语句详解及应用
- apache Kafka下线broker的操作