3)如果要给予applet更多的信赖,你必须知道下面两件事:
3.1) applet来自哪里?
3.2) 在传输过程中代码是否被破坏?
1)消息摘要(message digest): 是数据块的数字指纹。(干货——消息摘要定义)
2)消息摘要具有两个基本属性(properties):
p1) 如果数据的1位或者几位改变了,那么消息摘要也将改变。
p2) 拥有给定消息的伪造者不能创建与原消息具有相同摘要的假消息。
3)看个荔枝:
让我们来看看下面这位亿万富翁留下的遗嘱: "我死了之后,我的财产将由我的孩子平分,但是,我的儿子George应该拿不到一个子。" 这份遗嘱的SHA1指纹为: 2D 8B 35 F3 BF 49 CD B1 94 04 E0 66 21 2B 5E 57 70 49 E1 7E;这位有疑心病的父亲将这份遗嘱交给一位律师保存,而将指纹交给另一位律师保存。现在,假设George能够贿赂那位保存遗嘱的律师,他想修改这份遗嘱,使得Bill一无所得。当然,这需要将原指纹改为下面这样完全不同的位模式: 2A 33 0B 4B B3 FE CC 1C 9D 5C 01 A7 09 51 0B 49 AC 8F 98 92; 那么George能够找到与该指纹相匹配的其他文字吗?如果从地球形成之时,他就很自豪地拥有10亿台计算机,每台计算机每秒钟能处理一百万条信息,他依然无法找到一个能够替换的遗嘱。
4) 计算消息摘要的算法: 其中最著名的两种算法是SHA1和MD5。SHA1是由美国国家标准和技术学会开发的加密散列算法,MD5是由麻省理工学院的Ronald Rivest发明的算法。6)Java编程语言已经实现了SHA1和MD5。
6.1)MessageDigest类: 是用于创建封装了指纹算法的对象的"工厂",它的静态方法getInstance返回继承了MessageDigest类的某个类的对象。
6.2) 这意味着MessageDigest类能够承担下面的双重职责(responsibilities):
r1)作为一个工厂类。
r2)作为所有消息摘要算法的超类。
6.2)如何获取消息摘要:
step1)下面是如何获取一个能够计算SHA指纹的对象的方法:
MessageDigest alg = MessageDigest.getInstance("SHA-1");
or MessageDigest alg = MessageDigest.getInstance("MD5");
InputStream in = . . .
int ch;
while ((ch = in.read()) != -1)
alg.update((byte) ch);
step2.1)如果这些字节存放在一个数组中,那就可以一次完成整个数组的更新:
byte[] bytes = . . .;
alg.update(bytes);
byte[] hash = alg.digest();
4.1)荔枝背景:假设Alice想要给Bob发送一个消息,Bob想知道该消息是否来自Alice,而不是冒名顶替者。Alice写好了消息,并且用她的私有密钥对该消息摘要签名。Bob得到了她的公共密钥的拷贝,然后Bob用公共密钥对该签名进行校验。
4.2)如果通过了校验,则Bob可以确认以下两个事实(truth):
t1) 原始消息没有被篡改过;
t2) 该消息是由Alice签名的,她是私有密钥的持有者,该私有密钥就是与Bob用于校验的公共密钥相匹配的密钥;
4.3)你可以看到私有密钥的安全性为什么是最重要的。 如果某个人偷了Alice的私有密钥,或者政府要求她交出私有密钥,那么她就麻烦了。小偷或者政府代表就可以假扮她的身份来发送消息和资金转帐指令等等,而其他人则会相信这些消息确实来自于Alice。
3)keytool程序的功能: 负责管理密钥库、证书数据库和私有密钥。密钥库中的每一项都有一个"别名"。
3.1)看个荔枝:下面展示的是Alice如何创建一个密钥库alice.store 并且用别名生成一个密钥对的。
keytool -genkey -keystore alice.store -alias alice
jar cvf document.jar document.txt
jarsigner -verify -keystore bob.store document.jar
4.4)Bob不需要设定密钥别名。该jarsigner程序会在数字签名中找到密钥所有者的X.500名字,并在密钥库中搜寻匹配的证书。
4.5)如果JAR文件没有受到破坏而且签名匹配,那么jarsigner程序将打印: jar verified. 否则,程序将显示一个出错消息。
1)看个荔枝:假设你从一个声称代表某著名软件公司的陌生人那里获得了一个消息,他要求你运行消息附带的程序。这个陌生人甚至将他的公共密钥的拷贝发送给你,以便让你校验他是否是该消息的作者。你检查后会发现该签名是有效的,这就证明该消息是用匹配的私有密钥签名的,并且没有遭到破坏。这时候你要小心:你仍然不清楚谁写的这条消息。
2)认证问题定义:任何人都可以生成一对公共密钥和私有密钥,再用私有密钥对消息进行签名,然后把签名好的消息和公共密钥发送给你。这种确定发送者身份的问题称为"认证问题"。(干货——认证问题定义)
3)认证问题的solution: 解决这个认证问题的通常做法是比较简单的。假设陌生人和你有一个你们俩都值得信赖的共同熟人。假设陌生人亲自约见了该熟人,将包含公共密钥的磁盘交给了他。后来,你的熟人与你见面,向你担保他与该陌生人见了面,并且该陌生人确实在那家著名的软件公司工作,然后将磁盘交给你 。如此这样,你的熟人就证明了陌生人身份的真实性。
4)你不需要与熟人见面的: 取而代之的是,他可以将他的私有签名应用于陌生人的公共密钥文件之上即可。keytool -importcert -keystore cindy.certs -alias alice -file alice_signedby_acmeroot.cerstep5) 密钥库要进行校验,以确定该密钥是由密钥库中已有的受信赖的根密钥签过名的,而且Cindy不必对证书的指纹进行校验。 一旦Cindy添加了根证书和经常给她发送文档的人的证书后,她就再也不用担心密钥库了。
/usr/lib/ssl/misc/CA.pl -newca
-----BEGIN CERTIFICATE----- |
以及下面这行之后的所有内容:
-----END CERTIFICATE----- |
step3)现在可以按照通常的方式将acmeroot.pem导入到每个密钥库中了:
keytool -importcert -keystore cindy.certs -alias alice -file acmeroot.pem |
这看起来有点不可思议,keytool竟然不能自己去执行这种编辑操作。
step4)要对Alice的公共密钥签名,需要生成一个证书请求,它包含这个PEM格式的证书:
keytool -certreq -keystore alice.store -alias alice -file alice.pem |
step5)要签名这个证书,需要运行:
openssl ca -in alice.pem -out alice_signedby_acmeroot.pem |
step6)与前面一样,在alice_signedby_acmeroot.pem中切除BEGIN CERTIFICATE/END CERTIFICATE标记之外的所有内容。然后,将其导入到密钥库中:
keytool -importcert -keystore cindy.certs -alias alice -file |
你可以使用相同的步骤,使一个证书得到诸如VeriSign这样的公共证书权威机构的签名。
-------------------------------------------------------------------------------------------------------------------------------
【7】代码签名
c2) 在公众因特网上传递: 软件供应商获取由证书发放权威(如VeriSign公司)签名的证书。当最终用户访问一个包含已签名applet的Web站点时,就会弹出一个对话框,显示软件供应商的相关信息,并给最终用户两个选择,一个是给予applet全部权限,另一个是继续在沙盒中运行。
2)在本节的剩余部分: 我们将要介绍如何建立策略文件,来为已知来源的代码赋予特定的权限。创建和部署这些策略文件不是普通最终用户要做的,然而,系统管理员在准备部署企业内联网程序时需要做这些工作。 (干货——我们将要介绍如何建立策略文件,来为已知来源的代码赋予特定的权限。)D:\tmp>mkdir jar_signatureD:\tmp>cd jar_signature
D:\tmp\jar_signature>keytool -genkeypair -keystore acmesoft.certs -alias acmeroot
输入密钥库口令:
再次输入新口令:
您的名字与姓氏是什么?
[Unknown]: tang
您的组织单位名称是什么?
[Unknown]: swjtu
您的组织名称是什么?
[Unknown]: swjtu
您所在的城市或区域名称是什么?
[Unknown]: chengdu
您所在的省/市/自治区名称是什么?
[Unknown]: sichuan
该单位的双字母国家/地区代码是什么?
[Unknown]: CN
CN=tang, OU=swjtu, O=swjtu, L=chengdu, ST=sichuan, C=CN是否正确?
[否]: y
输入 的密钥口令
(如果和密钥库口令相同, 按回车):
再次输入新口令:
D:\tmp\jar_signature>dir
驱动器 D 中的卷是 软件
卷的序列号是 0006-7799
D:\tmp\jar_signature 的目录
2016/02/21 22:05 .
2016/02/21 22:05 ..
2016/02/21 22:05 1,274 acmesoft.certs
1 个文件 1,274 字节
2 个目录 21,075,292,160 可用字节
keytool -exportcert -keystore acmesoft.certs -alias acmeroot -file acmeroot.cer
keytool -importcert -keystore client.certs -alias acmeroot -file acmeroot.cer
D:\tmp\jar_signature>keytool -exportcert -keystore acmesoft.certs -alias acmeroot -file acmeroot.cer
输入密钥库口令:
存储在文件 中的证书
D:\tmp\jar_signature>keytool -importcert -keystore client.certs -alias acmeroot -file acmeroot.cer
输入密钥库口令:
再次输入新口令:
所有者: CN=tang, OU=swjtu, O=swjtu, L=chengdu, ST=sichuan, C=CN
发布者: CN=tang, OU=swjtu, O=swjtu, L=chengdu, ST=sichuan, C=CN
序列号: 717a234
有效期开始日期: Sun Feb 21 22:14:20 CST 2016, 截止日期: Sat May 21 22:14:20 CST 2016
证书指纹:
MD5: 4E:6A:EA:66:B1:67:69:44:61:5F:E1:D0:51:12:18:EF
SHA1: BF:E0:B8:76:E5:FA:A6:F6:E5:33:31:0B:B7:68:45:81:97:07:9B:FF
SHA256: 1D:26:85:E1:62:C9:43:E3:28:C5:3F:AD:E7:D3:C8:C7:6A:24:92:14:18:2F:71:EF:28:7D:16:9B
:6D:AD:1A:28
签名算法名称: SHA1withDSA
版本: 3
扩展:
#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: A8 83 5A D8 8C 45 4C 0D C2 9A 4B 1D D5 8F 8B 3E ..Z..EL...K....>
0010: 8C 3F 47 14 .?G.
]
]
是否信任此证书? [否]: y
证书已添加到密钥库中
javac HelloWorld.java
jar cvf HelloWorld.jar *.class
D:\tmp\jar_signature>javac HelloWorld.java
D:\tmp\jar_signature>jar cvf HelloWorld.jar *.class
已添加清单
正在添加: HelloWorld.class(输入 = 428) (输出 = 292)(压缩了 31%)
step4)
然后ACME中某个信任的人运行jarsigner工具,指定JAR文件和私有密钥的别名: jarsigner -keystore acmesoft.certs HelloWorld.jar acmeroot
被签名的applet现在就已经准备好在Web服务器中部署了。
D:\tmp\jar_signature>jarsigner -keystore acmesoft.certs HelloWorld.jar acmeroot
输入密钥库的密码短语:
jar 已签名。
警告:
签名者证书将在六个月内过期。
未提供 -tsa 或 -tsacert, 此 jar 没有时间戳。如果没有时间戳, 则在签名者证书的到期日期 (2016-05-21) 或
以后的任何撤销日期之后, 用户可能无法验证此 jar。
keystore "keystoreURL", "keystoreType";step5.1) 其中,URL可以是绝对的或相对的,其中相对URL 是相对于策略文件的位置而言的。如果密钥库是由keytool工具生成的,则它的类型是JKS。例如:
keystore "file:certs.store", "JKS";
""grant子句可以有signedBy "alias"后缀,例如:
grant signedBy "acmeroot"
{
. . .
};
keystore "client.certs" "JKS"
grant signedBy "acmeroot"
{
permission java.lang.RuntimePermission "usePolicy";
permission java.io.FilePermission "D:\tmp\jar_signature\", "read";
};step7) 最后,告诉applet浏览器使用该策略文件:
appletviewer -J-Djava.security.policy=HelloWorld.policy FileReadApplet.htm
-------------------------------------------------------------------------------------------------------------------------------
2)现在你有两个选择(select):
s1)用全部权限运行程序,或者
s2)将程序限制在沙盒中运行。(对话框中的Cancel按钮是一种误导。如果点击这个按钮,applet不会被取消,而是运行在沙盒中。)
3)那么什么样的因素可能会影响你的决定呢?下面是已经了解的情况:
3.1) Thawte公司将一个证书卖给了软件开发人员。
3.2) 程序确实是用该证书签名的,并且在传输过程中没有被篡改过。
3.3) 该证书确实是由Thawteit签名的,它是用本地cacerts文件中的公共密钥校验的。
4) 是否就意味着该代码可以安全运行了?
4.1)如果你只知道供应商的名字,以及Thawte公司卖给他们一个软件开发者证书这个事实,那么你会信赖该供应商吗?
4.2)如果想要担保ChemAxon Kft.不是个彻头彻尾的破解者,恐怕连Thawte公司自己也会陷入麻烦之中。
4.3)然而,没有一个证书发放者会对软件供应商的诚信度和资格能力进行广泛的审查。