密码签名管理
在Java程序中Sun公司提供了两个管理加密签名的工 具:keytool和jarsigner(JAR签名和验证工具)。jarsigner用于签名JAR文件,它用指定的符号连接指定的程序。 keytool和jarsigner取代了JDK1.1中的javakey。第三个工具policytool在Java2中用于管理安全策略。
Jarsigner
同JDK一起发布的jarsigner应用程序完成两个功能:签名JAR文件,并校验JAR文件中的签名。JAR代表Java文档(Java Archive)。它实际上是一种支持签名的.zip文件。用jarsigner签名,就可以用证书保证文件内容的安全。
通常签名的JAR文件用于发布签名的Applet,但也可用于发布其他可信代码。一个软件开发人员可以分发签名的JAR文件,该文件直接从该开发人员那里获得,并且不会被第三方修改。
Applet通常被签名,以便授予一定特权,比如读写本地文件系统。
给JAR文件签名
1、打包jar的命令 jar cvf HelloWorld.jar HelloWorld.class
2、为该jar进行签名
- 生成密钥对(默认保存在用户目录的.keystore密钥库中)
keytool -genkey -alias mykey
- 给jar签名
jarsigner HelloWorld.jar mykey
3、校验jar文件 jarsigner -verify -verbose HelloWorld.jar
签名的JAR文件
一个JAR文件就是许多文件的简单集合。当一个JAR文件被签名,它就不再是原先JAR文件,而是它其中的部分或全部文件。也就是说签名的JAR文件不能 保证其中所包括的所有东西是有用的。用Winzip之类工具可以在不破坏签名的情况下往签名的JAR文件中增加文件,而且修改其中的文件不会影响别的文 件。签名必须保存在JAR文件中,并含有一些额外信息,如信息摘要、签名信息。这些信息用下述形式表示:
- 清单文件 META-INF\MANIFEST.MF(包括签名文件的名字和杂凑)
- 签名文件 META-INF\SIGNER.SF(包括清单中的摘要以及清单每个实体的摘要)
- 数字签名文件 META-INF\*.DSA(*.RSA)具体是哪一个取决于签名算法,它是.SF文件中使用PKCS#7格式的数字签名,这个文件使用二进制格式,所以是不可读的。
在Java中使用消息摘要
java.security.MessageDigest
- getInstance() 创建对象
- update() 将输入的数据转换成消息摘要,本方法可以对非常大的数据进行杂凑,数据最长可达到2的64次方位,具体长度取决于底层的算法
- digest() 返回字节数组形式的杂凑结果。如果只有少量的数据需要进行杂凑处理,可以直接将数据传送给digest(),因为该方法可以选择地对一个字节数组进行杂凑处理
消息摘要流
- DigestInputStream 消息摘要输入流
- DigestOutputStream 消息摘要输出流
消息认证码(MAC)
javax.crypto.Mac
- getInstance() 创建对象
- init() 使用密钥进行初始化
- update() 将数据字节传给MAC,产生消息认证码
- doFinal() 返回MAC码
在Java中使用数字签名
java.security.Signature
- getInstance() 创建对象
- initSign()和initVerify() 初始化签名对象,具体用哪一个取决于你是要进行签名,还是要进行验证
- update() 将数据传送给它。如果要签名,就将待签名的数据传送给它;如果要验证签名,就把待验证的数据传送给它
- sign() 如果正在进行签名,该方法就会返回用方法update()传送给签名对象的数据的签名结果
- verify() 如果是要验证数据而不是签名,则要调用该方法,它会返回一个布尔值,以表明签名是否有效
在Java中使用证书
java.security.cert.Certificate
- getPublicKey() 返回证书主体的公钥
- verify() 验证证书的签名。它要求你输入证书发布者的公钥
java.security.cert.X509Certificate
java.security.cert.CertificateFactory
Keystore
java.security.KeyStore
在Java中,keystore用于收集密钥和证书。keystore通常存放在文件中,但是它可以存放在其他媒介中,如数据库或者LDAP服务器。在keystore中有两种类型的实体:
- 可信证书——指的是你相信它是由证书的宣称者所签署的证书。可信证书的一个例子就是CA。
- 密钥——指的是可以用于数字签名或者加密的私钥或者对称密钥。在keystore中存放的密钥必须与该密钥的证书相对应。这不是可信证书,只是简单的包含拥有私钥的主题。
Keytool
keytool是JDK所带的一个程序。它管理keystore,而且可以产生证书。下面逐个介绍每个选项:
- -certreq——证书产生请求,用于请求CA签署一个证书。
- -delete——从keystore中删除一个实体。
- -export——从keystore中输出一个DER编码的证书。通过添加-rfc选项,就可以添加BASE64编码。注意,无法用此选项输出私钥。
- -genkey——产生密钥对以及自签名的证书。可以用-keyalg指定使用的算法,如-keyalg RSA。
- -help——显示使用keytool时可能的选项。
- -identitydb——转换JDK1.1的身份数据库为Java2型的keystore。
- -import——向keystore中输入新的证书。这一选项对于向一已经存在的别名添加新的证书和已经签署的证书非常有用。
- -keyclone——在keystore中拷贝实体。
- -keypassword——修改保护别名的口令。
- -list——列出数据库中所有的别名
- -printcert——显示证书。
- -selfcert——产生一个自签名的证书。
- -storepassword——修改keystore的口令。
-v选项指定任何命令使用的verbose模式,-keystore选项让你可以指定想要打开的文件。
java.security.cert.X509CRL
创建自己的CA
sun.security.X509.*
- X509CertImpl 提供X.509证书的底层实现。我们可以用这个类来创建新的证书,它提供了签发证书的方法sign()。
- X509CertInfo 对存放在X.509证书中的内容进行封装。这允许我们为新证书设置一些新的属性。
- X500Name 描述X.500名字。
- AlgorithmId 描述密码算法。
- CertificateSubjectName 主体的X.500名字。
- CertificateValidity 证书的有效期。
- CertificateSerialNumber 描述证书的序列号。对于给定的CA,这个序列号应该是惟一确定的。
- CertificateIssuerName 证书发布者的X.500名字。
- CertificateAlgorithmId 用于签署证书的算法ID号。
消息摘要
消息摘要对于数据来讲是一种重要的指纹。消息摘要的目的就是防止数据被篡改。
从数据获取消息摘要的过程通常称作杂凑。利用消息摘要相对于直接与原始数据的拷贝进行比较的优点在于它的长度:不管数据的长度有多大,消息摘要的长度通常只有16或者20个字节长。消息摘要计算起来比较简单:利用消息摘要算法对数据进行处理即可得到消息摘要。
消息摘要的一个用途就是在FTP中进行文件的确认。大文件传送中有时会出现一些问题。如果服务器提供了该文件的消息摘要,你就可以在下载该文件后进行比较,以确保文件传送的正确性。
口令认证
消息摘要的一个常用的用途就是口令认证。由于消息摘要是单向转换得来的数据,因此由它不可能得到原始数据。我们可以只存储口令的杂凑值,这样就没有人能破译出存储的口令,因为没有任何方法可以直接破译消息摘要。
为了让攻击者获取了经杂凑处理的口令,也更难猜出口令,需要使用加盐的方法来存储口令,这样就可以使口令攻击者预先产生常用口令的消息摘要清单这一方法不可行。
消息认证码(MAC)
消息认证码是一种非常重要的消息摘要。它通常用于在不安全的网络,如Internet上鉴别传送的数据。通信的双方交换密钥,然后用这个密钥对数据进行验 证。因为是通过密码学的方法利用共享密钥来保护消息摘要,所以MAC解决了如何在不安全的网络环境中传送消息摘要的问题。
基于密码学上的hash函数的MAC通常被称作HMAC(杂凑消息认证码)。还有其他类型的MAC,它们是基于分组密码的,但并不常用。
在Sun的JCE中有两种HMAC函数:一种是用MD5算法,另一种使用SHA-1算法。你可以用参数HmacMD5和HmacSHA1对它们进行调用。其他的提供者,如Bouncy Castle,甚至支持更多的算法。
数字签名
数字签名有点类似于用数字方式的物理签名,但它们又不完全相同。数字签名与单独的数据,如签字的合同或者电子邮件有关。物理签名也是为了完成相同的工作, 但是物理签名却无法引用待签的文档。强迫进行物理签名比强迫进行数字签名容易得多:只需从另一个文档拷贝该签名即可。数字签名通常提供更高的安全度,因为 它们与签名的文档相关,而且如果无法读取所使用的密钥,就很难伪造签名。
数字签名是一种重要的消息摘要,它是用自己的私钥进行处理的。你可以先将要签名的数字送给消息摘要算法,然后消息摘要和私钥送给签名算法。所得到的数据就 是所要得到的数字签名,它是用私钥签名的。签名数据与原始数据一起传送,以此证明该数据是由持有私钥的人签署的。
为了验证签名,必须使用签名者的公钥,然后比较数据的消息摘要,如果相同,就可以知道该数据是用对应的私钥签名的,你也可以通过这个结果知道,数据自签名后没有被修改。
数字签名有两个主要用途:保持数据的完整性和同一性。
数字证书
数字证书是由第三方提供的一种确保该公钥是由其宣称者所拥有的一种方式。然而,证书不只可以发布给人,还可以发布给一些主体,如公司或者其他组织。
一般情况下,证书是由你的公钥和一些其他信息组成,这些信息和你的公钥是由第三方的私钥进行签名。通常,第三方称作CA(证书授权机构)。
两个最著名的CA是Verisign和Thawte(后者实际上是前者的子公司)。还有一些其他的CA公司,但它们只占据很少一部分CA市场。通过对你的公钥进行签名,CA可以保证这个公钥是由你所发布的。
证书链
证书主要是为了确保公钥正确性。还是可以对这一功能进行扩充,可以将多个证书链接起来组成一个证书链。证书链中的每个实体(除了最后一个实体之外)都是一个CA。证书链用于管理证书。通过建立子证书,就易于实现每个证书的功能。
证书撤销清单(CRL)
有时,需要在证书有效期之间取消该证书。证书撤销清单提供了这种功能。CRL中存放了由CA签署的已被撤销的证书的序列号。每个CA都有它自己的CRL可 供下载。如果你想知道某个证书是否有效,可以检查一下CRL,看看有无该证书的序列号。如果没有的话,则该证书还没有被撤销。
公钥基础设施(PKI)
公钥基础设施是管理公钥密码的一个基本系统。正如我们所知道的,在配置甚至刚刚开始建立安全系统时,就涉及到很多的算法、协议和安全概念。PKI试图将大量的算法和标准集成进一个统一的系统中以提供安全服务。
PKI至少必须提供以下服务:
- 创建证书
- 证书撤销
- 证书的验证
- 向客户端提供证书