jdk工具keytool和jarsigner帮助Part1(jdk keytool&jarsigner tool manual)
0.背景
keytool是JDK中包含的密钥和证书的管理工具。用于管理私钥及其相关的X.509证书链的keystore。X.509证书链用于认证对应的公钥,keystore类似于一个数据库。同时keytool还用于管理信任实体发布的证书。
jarsigner是JDK中包含的用于JAR文件签名和验证的工具。为Java档案文件(JAR)生成签名,以及对已签名的jar文件的进行校验。
1.工具Location
这两个工具都位于$JAVA_HOME/bin目录下,其中$JAVA_HOME是JDK的安装目录。
这两个工具都是在命令行中使用,在命令行窗口输入:
keytool和jarsigner即可获取命令的工具的使用方法。
2.keytool工具简介
keytool是密钥和证书管理工具。用户使用该工具来管理公钥/私钥对以及关联的证书,通过使用数字签名,可以应用于自签名或者数据完整性/认证服务,用户还可以使用该工具来缓存合作伙伴的公钥(以证书的形式)。
证书是由实体进行数字签名的声明,这里实体可以是个人或者企业。一旦数据被数字签名,那么可以通过检查数据完整性和可靠性来校验签名。完整性的意思是数据没有被修改/篡改过,可靠性是指数据确实是来自于宣布拥有数据的人。
keytool将密钥和证书存储在所谓的keystore中,默认的keystore实现是将keystore作为一个文件。它使用密码来保护私钥。
jarsigner工具使用keystore中的信息来生成或者校验JAR文件的数字签名。jarsigner使用附带在JAR文件中的证书来校验数字签名(证书包含在JAR文件的签名块文件中),然后检查证书的公钥是否是可信赖的,也就是说是否包含在指定的keystore中。
3.keystore实体
在keystore中包含了两种不同类型的实体:
i.密钥实体 - 包含了非常敏感的加密密钥信息,以受保护的形式进行存储,以防止未授权访问。典型的这种类型的实体保存一个secret key,或者通过证书链连接的public key对应的private key。keytool和jarsigner工具只处理后一种类型的实体,即private key和关联的证书链。
ii.信任的证书实体 - 包含了其他组织的public key certificate。之所以成为信任的证书,是因为keystore的所有者信任证书中的public key确实属于由证书的subject标识的个体。证书的签发者通过签发证书为此担保。
4.keystore别名(aliases)
通过使用唯一的别名可以访问keystore中的实体。别名是不区分大小写的。
当使用-genkey命令生成key pair(public & private key),或者使用-import命令来添加证书或者证书链到信任证书列表时来指定的。keytool命令必须使用这个别名来引用这个实体。
例如,使用duke作为别名来生成新的public/private key pair,并将public key包装到一个自签名的证书中。命令如下:
keytool -genkey -alias duke -keypass dukekeypasswd
这里使用了初始密码,可以通过下面的命令进行密码的修改:
keytool -keypasswd -alias duke -keypass dukekeypasswd -new newpass
上面的命令将密码由dukekeypasswd修改为newpass。
5.keystore存储位置
每个keytool命令都包含了一个-keystore选项,用于指定持久化keystore文件的名字和位置。默认的keystore保存在用户主目录(user.home系统属性)中,名为.keystore。假设用户名为uName,那么user.home属性的值默认为:
多用户Windows NT/2000系统:C:/Winnt/Profiles/uName
多用户Windows 95/98/XP系统:C:/WINDOWS/Profiles/uName
单用户Windows 95/98/XP系统:C:/WINDOWS
注:-keystore选项指定的input stream是作为参数传递到KeyStore.load方法中,如果NONE被指定,那么null stream被传送到KeyStore.load方法。只有当KeyStore不是基于文件的时候,比方说,位于硬件中,才会指定为NONE。
6.keystore生成
当使用-genkey,-import,-identitydb命令时,都会创建一个keystore(当keystore不存在时)。
再具体的说,当在-keystore选项中指定的keystore文件不存在时,keystore会被创建。
如果不指定-keystore选项,会使用默认的keystore文件名,即user.home/.keystore,如果该文件不存在,那么创建该文件。
7.keystore实现
java.security.KeyStore类提供了定义良好的接口用于访问和修改keystore中的信息。可能还会存在多种不同的具体实现,对应不同类型的keystore。
目前,keytool和jarsigner以及基于GUI的Policy Tool都使用keystore实现。既然KeyStore是公共的类,JDK用户可以使用它来编写更多的安全应用。
Sun公司提供了一个内置的默认的实现,将keystore作为一个文件来实现,使用的keystore类型为"JKS"。通过密码来保护private key,同时通过密码(通常和保护private key的密码不同)来保护整个keystore的完整性。
keystore的实现是基于provider的。再进一步的说,KeyStore提供的应用程序接口是以SPI(Service Provider Interface)的方式来实现的。也就是说,在java.security package中,还包含了一个对应的keystoreSpi抽象类,定义了provider必须实现的SPI。因此,要提供keystore的实现,就必须实现provider并提供KeystoreSpi子类的实现。
应用程序可以选择不同类型的keystore实现,通过使用KeyStore类的getInstance工厂方法。keystore类型定义了keystore信息的存储和数据格式,以及用于保护private key的算法。不同类型的Keystore实现是不兼容的。
keytool工具可以工作与任意基于文件的keystore实现。而jarsigner和policytool则可以从任意位置(可以通过URL指定的)来读取keystore。
对于keystore和jarsigner,可以通过-storetype命令行选项来指定keystore类型,对于Policy Tool,可以通过Change Keystore命令来制定keystore类型。
如果不显示的指定keystore的类型,那么工具会根据security属性文件中的keystore.type的值来选择keystore的实现。security属性文件叫做java.security,位于JDK security属性目录中,JAVA_HOME/lib/security,JAVA_HOME表示java运行时环境即JRE的目录。
获取keystore.type值后,检查当前安装的所有provider,直到发现该类型的keystore实现。然后使用provider提供的keystore实现。
KeyStore类定义了一个静态方法,叫做getDefaultType,应用程序以及applets可以使用该方法来获取keystore.type属性的值。下面的方法创建了一个默认keystore类型的KeyStore实例。
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
默认的keystore类型是"jks",这是Sun公司提供的默认实现。通过security属性文件指定:
keystore.type=jks
可以通过修改security属性文件的该值来修改默认的keystore实现。例如:
keystore.type=pkcs12
注:类型不区分大小写,PKCS12等价于pkcs12。
8.支持的算法及密钥大小
keytool允许用户指定任意已经注册的加密服务provider提供的key pair生成器以及签名算法。也就是说,keyalg和slgalg选项必须被provider实现所支持。默认的key pair生成器算法是DSA,签名算法是从底层的private key的算法继承来的:如果底层private key的类型是DSA,那么默认的签名算法就是SHA1withDSA,如果底层private key的类型是RSA,那么默认的签名算法就是MD5withRSA。
当成生DSA key pair时,key的大小必须在512 - 1024之间,并且必须是64的整数倍。所有算法的默认的key大小为1024。
9.证书
证书,通常也叫公钥证书,是由实体进行数字签名的声明。证书的一些术语说明如下:
公钥:与特定实体相关联的数字,并且公开给与其有交互的外部实体。公钥用于验证签名。
数字签名:如果数据被数字签名,那么它将作为实体的身份被存储,签名可以证明实体识别数据。通过使用实体的私钥来进行签名,可以确保数据不可伪造。
身份标识:用于确定实体。在某些系统中,身份就是公钥,在一些其他系统中,可以是Unix的UID,Email地址,X.509 DN。
签名:签名是使用实体的私钥来对一些数据进行计算。当signer(签名者)是一个证书时,也被叫做issuer(发行者)。
私钥:只提供给特定实体的数字,也就是说,它应该是保密的。在所有的公钥加密系统中,私钥和公钥是成对存在的。在典型的PKCS(public key crypto systems)系统中,例如DSA,一个私钥对应唯一的一个公钥,私钥用于计算签名。
实体:实体可以是个人,组织,程序,计算机,企业,银行以及在某种程度上用户信任的任何事物。
基本上说,公钥加密需要访问用户的公钥。在大规模的网络环境下,很难保证通信实体间已经建立了重要关系或者一个可信赖的存储库保存了所有用过的公钥。这种情况下,证书作为一个解决方案来解决公钥发布的问题。现在,认证中心(Certification Authority,i.e CA)可以扮演可信赖的第三方。
使用keytool可以显示,导入,到处证书。同样,也可以生成自签名的证书。
keytool目前可以处理X.509证书。
10.X.509证书
X.509标准定义了证书中可以包含哪些信息,并描述了数据的格式,所有的X.509证书都包含除签名外的以下的数据:
版本:标识证书的X.509标准的版本,用于确定哪些信息是可以被指定的。截至到目前,已经定义了三种版本。keytool可以导入和到处v1,v2和v3证书,可以生成v1证书。
序列号:创建证书的实体需要给证书分配一个序列号来标识它发行的证书。这个信息在很多地方使用,例如如果一个证书被废弃了,那么它的序列号将被添加到证书废弃列表中(CRL)。
签名算法标识:标识CA签名证书时使用的算法。
发行者名称:签名该证书的实体的X.500 DN。这通常是CA。
有效期:每个证书都有一个有效期。由起始时间和结束时间来确定。
主题名:证书标识的公钥所属的实体的名字。名称使用X.500标准。例如:
CN=Java Duke, OU=Java Software Division, O=Sun Microsystems Inc, C=US
主题公钥信息:实体的公钥,以及算法标识。
其中v1是最普遍的。v2还没有广泛使用。v3提供了对扩展的支持。
11.X.500 DN
X.500 Distinguished Names(DN)用于标识实体,例如X.509证书的subject和issuer字段的信息。keytoo支持以下的子部分:
commonName:人的名字
organizationUnit:规模较小的组织名,比如部门。
organizationName:规模较大的组织名。
localityName:区域名。
stateName:州或者省的名字。
country:两个字符的国家代码。
当提供distinguished name时,使用-dname选项,字符串的格式不许如下所示:
CN=cName, OU=orgUnit, O=org, L=city, S=state, C=countryCode
例如:
keytool -genkey -dname "CN=Mark Smith, OU=JavaSoft, O=Sun, L=Cupertino, S=California, C=US" -alias mark
必须按照指定的顺序指定各个部分的值,但是并不是所有的部分都是必须的。如果某一部分的值包含逗号,那么需要使用/进行转义。例如:
cn=peter schuster, o=Sun Microsystems/, Inc., o=sun, c=us
12.Internet RFC1421证书编码标准
证书常常以可以打印的编码格式进行保存。这个编码格式是由Internet RFC 1421标准来定义的,用来取代二进制格式。这个证书格式,即Base64编码,方便了导出证书给其他应用程序使用。
通过-import或者-printcert命令来读取时,可以使用这种格式或者二进制格式。
-export命令默认以二进制格式输出证书,但是会以可打印的编码格式,如果指定-rfc选项的话。
-list命令默认打印证书的MD5指印。如果-v选项被指定的话,证书可以以可读的格式打印,如果-rfc选项被指定的话,证书以printable编码格式输出。
可打印编码格式的证书以
-----BEGIN CERTIFICATE-----
开头,以
-----END CERTIFICATE-----
结尾。
13.证书链
keytool可以创建和管理keystore的key实体,每个key实体可以包含一个私钥和一个关联的证书链。证书链中的第一个证书包含对应私钥的公钥。
当keys被第一次生成时,证书链开始包含单一的元素,即自签名证书。自签名证书是指issuer和subject是同一个实体的证书。每当-genkey被调用时,都会生成一个新的public/private key pair,并将public key包装进自签名证书。
之后,当使用-certreq命令生成证书签名请求并将其发送给CA,CA的反应被导入(-import),自签名的证书被证书链取代,在证书链的底部的是CA认证并签发的证书,接下来的是认证CA公钥的证书。
在很多情况下,这是一个自签名证书(即CA对自己的公钥进行自签名得到的证书),并作为证书链中最后的证书。在其他情况,CA会发挥一个证书链。在这种情况下,证书链的底部还是相同的,但是第二个证书是一个被不同CA认证的证书,认证CA的公钥。以此类推,最后到一个自签名的根证书。
很多CA值返回发行的证书,而不支持链,特别是没有中间CA的时候。这种情况下,证书链必须从keystore中已经包含的受信任的证书开始建立。
另外一种反应格式(由PKCS#7标准定义)是包含证书链。keytool可以处理这两种反应格式。
14.导入证书
可以使用-import选项来从文件中导入证书。
keytool -import -alias joe -file jcertfile.cer
上面的命令导入jcertfile.cer中的证书,并将其保存在keystore中,由别名joe来进行标识。
导入证书主要有两个原因:
a.将其添加到信任的证书列表中
b.将CA返回来的证书导入
到底想导入哪种取决于-alias选项的值:
如果alias指向一个key实体,那么keytool假定在导入CA返回的证书。keytool检查证书中的public key是否与keystore中存储的实体(由alias指定的)的public key一致,如果不一致,那么退出。
如果alias没有指向任何key实体,那么keytool假定在向keystore中添加信赖的证书实体。在这种情况下,alias不应该存在于keystore中。如果alias已经存在,那么keytool输出一个错误。
在导入信赖的证书前,要检查证书。首先查看一下证书,使用-printcert证书或者不带-noprompt选项的-import命令。
15.导出证书
使用-export命令来导出证书。
keytool -export -alias jane -file janecertfile.cer
16.显示证书
使用-list命令来打印出keystore实体的内容:
keytool -list -alias joe
如果不指定-alias的话,那么将会打印整个keystore。
可以使用-printcert命令来显示文件中保存的证书的内容:
keytool -printcert -file certfile.cer
17.生成自签名证书
自签名证书是指issuer和subject相同的证书。每次使用-genkey命令的时候,都会生成新的public/private key pair,同时将public key包装进自签名证书。
有时可能需要生成新的自签名证书,例如可能希望使用相同的key pair在不同的身份下。例如可以修改部门。 此时可以:
a.拷贝(clone)原始的key entry。请参考-keyclone。
b.为cloned的实体生成新的自签名的证书,使用新的DN。
c.为cloned的实体生成CSR,并将反应的证书或者证书链导入。请参考-certreq和-import命令。
d.删除原始的实体。请参考-delete
可以使用-selfcert命令生成自签名的证书:
keytool -selfcert -alias dukeNew -keypass b92kqmp -dname "cn=Duke Smith, ou=Purchasing, o=BlueSoft, c=US"
18.命令及选项注意事项
所有的命令和选项名都以-做前缀。
每个命令的选项不区分顺序。
所有没有斜体的或者没有在大括弧或者中括弧中的项目是必须原原本本输出的。
大括弧包含的选项表示如果该选项没有被指定,那么采用默认的值。大括弧还用作-v,-rfc和-J选项,只用来表示这些选项是否出现在命令行上。即表示如果它们不出现,也没有默认值。
中括弧包含的选项表示,如果用户不指定值,那么将会在命令行提示用户输入。
斜体表示的项目代表必须提供的实际值。
选项的值必须使用双引号,如果包含空格的话
下面是一些常见的默认值:
-alias "mykey"
-keyalg "DSA"
-keysize 1024
-validity 90
-keystore $user.home/.keystore
-file stdin/stdout
下面是大多数命令都会使用的通用选项:
-v选项适用于除-help之外的所有命令,表示verbose模式,即输出详细信息。
-J选项适用于任何命令,如果出现的话,javaoption会直接传送到Java解释器(keytool实际上就是解释器的包装器)。该选项不能包含任何空格,主要用于设置执行环境以及内存使用,可用的解释器选项可以通过输入java -h或者java -X来查看。
-storetype :设置keystore的类型。
-keystore :keystore文件的存储位置
-storepass:keystore文件的密码,密码长度至少为6个字符,当访问keystore文件的内容时,必须提供该密码。如果不指定该选项,命令行会提示用户输入。
-provider :指定加密服务provider的master class文件的名字。
19.命令详解
-certreq [-v] [-alias <alias>] [-sigalg <sigalg>]
[-file <csr_file>] [-keypass <keypass>]
[-keystore <keystore>] [-storepass <storepass>]
[-storetype <storetype>] [-provider <provider_class_name>] ...
生成证书签名请求(CSR),使用PKCS#10格式。CSR是用来发送给CA,CA对证书签名请求认证,并返回证书或者证书链,用来替换keystore中既存的证书链(初始状态是自签名的证书)。
alias关联的private key和X.500 DN被用来创建PKCS#10证书请求。
-delete [-v] -alias <alias>
[-keystore <keystore>] [-storepass <storepass>]
[-storetype <storetype>] [-provider <provider_class_name>] ...
-export [-v] [-rfc] [-alias <alias>] [-file <cert_file>]
[-keystore <keystore>] [-storepass <storepass>]
[-storetype <storetype>] [-provider <provider_class_name>] ...
从keystore中导出由alias指定的证书,并保存为cert_file。默认情况下证书以二进制编码格式导出,可以通过指定rfc选项来以可打印的编码格式导出。
-genkey [-v] [-alias <alias>] [-keyalg <keyalg>]
[-keysize <keysize>] [-sigalg <sigalg>]
[-dname <dname>] [-validity <valDays>]
[-keypass <keypass>] [-keystore <keystore>]
[-storepass <storepass>] [-storetype <storetype>]
[-provider <provider_class_name>] ...
生成key pair(public key机器关联的private key),将public key包装入X.509 v1自签名证书,该证书链中只包含单一元素。这个证书链以及私钥被存储到一个新的keystore中,以alias标识。例如:
C:/j2sdk1.4.2_15/bin>keytool -genkey -alias valuptec -keyalg RSA -keysize 1024 -
sigalg SHA1withRSA -dname "CN=Example, O=Example, OU=Example, L=Example, S=Example,C=CH" -keypassp@ssword -validity
3650 -storetype jks -keystore "c:/example.keystore" -storepass p@ssword
-help
-identitydb [-v] [-file <idb_file>] [-keystore <keystore>]
[-storepass <storepass>] [-storetype <storetype>]
[-provider <provider_class_name>] ...
-import [-v] [-noprompt] [-trustcacerts] [-alias <alias>]
[-file <cert_file>] [-keypass <keypass>]
[-keystore <keystore>] [-storepass <storepass>]
[-storetype <storetype>] [-provider <provider_class_name>] ...
从cert_file中读取证书或者证书链(当以PKCS#7格式提供时),并将其存储到keystore中,以alias标识。keytool可以导入X.501 v1,v2,v3证书,以及PKCS#7格式的证书链。被导入的数据必须以二进制编码格式或者可打印编码格式提供。
当导入新的受信任的证书时,alias必须不存在于keystore中。在将证书添加到keystore之前,keytool首先尝试创建由证书到自签名证书的链,使用已经存在于keystore中的受信任的证书。如果-trustcacerts选项被指定,附加的证书被认为是信任链。即在一个名为cacerts的文件上的证书。如果keytool无法创建由导入证书到自签名证书的信任路径(从keystore或者cacerts文件),证书的信息被打印,提示用户检查信息。
当导入证书回复时,通过使用keystore中的信任证书对证书回复进行验证,同时可以选择使用cacerts文件中的证书(指定-trustcacerts选项)。决定证书回复是否被信任的方法如下:
a.如果证书回复是X.509证书,那么keytool尝试建立从证书回复到自签名证书的信任链。如果无法建立信任链,证书回复不被导入。此时keytool不打印证书的内容。
b.如果证书回复是PKCS#7格式的证书链,首先对证书链排序(用户证书在开始,自签名证书在结尾),然后keytool尝试使用cacerts keystore中的受信任的证书来匹配证书回复中的根证书。如果没有发现匹配的证书,根证书的信息被打印,提示用户确认。用户可以选择取消导入。如果-noprompt选项被指定,那么不会与用户交互。
注:cacerts证书文件
一个名为cacerts的证书文件位于security属性目录,java.home/lib/security,java.home标识java runtime environment目录。
cacerts文件表示包含了CA的系统范围的keystore。系统管理员可以配置和管理这个文件。
cacerts文件的初密码是changeit。
-keyclone [-v] [-alias <alias>] -dest <dest_alias>
[-keypass <keypass>] [-new <new_keypass>]
[-keystore <keystore>] [-storepass <storepass>]
[-storetype <storetype>] [-provider <provider_class_name>] ...
clone key。
-keypasswd [-v] [-alias <alias>]
[-keypass <old_keypass>] [-new <new_keypass>]
[-keystore <keystore>] [-storepass <storepass>]
[-storetype <storetype>] [-provider <provider_class_name>] ...
修改private key密码。
-list [-v | -rfc] [-alias <alias>]
[-keystore <keystore>] [-storepass <storepass>]
[-storetype <storetype>] [-provider <provider_class_name>] ...
列举keystore文件中包含的证书信息,例如:
C:/j2sdk1.4.2_15/jre/lib/security>c:/j2sdk1.4.2_15/bin/keytool.exe -list -alias
valuptec -keystore c:/valupshanghai.keystore -rfc
キーストアのパスワードを入力してください: pa55w@rd
別名: valuptec
作成日: 2009/03/17
エントリのタイプ: keyEntry
証明連鎖の長さ: 1
証明書[1]:
-----BEGIN CERTIFICATE-----
BASE64 ENCODING CERTIFICATE DATA
-----END CERTIFICATE-----
-printcert [-v] [-file <cert_file>]
打印证书信息。
-selfcert [-v] [-alias <alias>] [-sigalg <sigalg>]
[-dname <dname>] [-validity <valDays>]
[-keypass <keypass>] [-keystore <keystore>]
[-storepass <storepass>] [-storetype <storetype>]
[-provider <provider_class_name>] ...
生成X.509 v1自签名证书,使用包含private key和public key的keystore的信息。如果dname在命令行提供,那么用来作为证书的issuer和subject。
-storepasswd [-v] [-new <new_storepass>]
[-keystore <keystore>] [-storepass <storepass>]
[-storetype <storetype>] [-provider <provider_class_name>] ...
修改存储密码。
20总结
本文是介绍Java安全工具keytool&jarsigner文章的第一部分,主要介绍了安全相关的概念,例如实体,公钥,私钥,证书,签名等,并简要的介绍了keytool的使用方法。
关于jarsigner的介绍,请参考本文的第二部分。
转:http://blog.csdn.net/sunjavaduke/article/details/3998283