KeyTool 工具生成X.509证书
学习系统过程中看到与其它系统交互用到证书认证,整理网上以及自己学习的一些规则制作出两个版本的证书生成方式
主要原理是使用jdk提供的 keytool命令实现
1 命令行
1.1 生成证书
keytool -genkey -alias tomcat -keyalg RSA -keystore e:/tomcat/https/mykey -storepass 111111 -keypass 111111
1.2 导出证书
keytool -export -alias tomcat -storepass 111111 -file server.cer -keystore e:/tomcat/https/mykey
制作windows 批处理脚本如下:
01-GenRSA.cmd (生成证书)
@echo off color 3A rem 显示工具信息 call 03-initInfo.cmd rem 定义变量 set "cd=%~dp0" set "keystoreFile=%cd%\file\demo.jks" set "validity=30" set "keysize=1024" set "alias=test_cert" set "keyalg=RSA" set "storepass=storepass" rem 建议去掉此项改为手工录入 set "keypass=keypass" rem 建议去掉此项改为手工录入 rem 对称加密算法genkey 非对称加密 genkeypair rem set "gen=-genkeypair" rem set "gen=-genkey" rem dname "CN=JsHand,OU=jshand.com CLD,O=jshand.com,L=BJ,ST=BJ,C=CN" set "dname="CN=JsHand,OU=jshand.com CLD,O=jshand.com,L=BJ,ST=BJ,C=CN"" rem 显示证书信息 call 04-showJksInfo.bat echo. echo. echo. keytool -genkeypair -validity %validity% -keysize %keysize% -alias %alias% -keyalg %keyalg% -keystore %keystoreFile% -storepass %storepass% -keypass %keypass% -v -dname %dname% echo 按任意键退出程序 pause>nul
02-ExportRSA.cmd (导出证书)
@echo off call 03-initInfo.cmd rem 定义变量 set "cd=%~dp0" rem 当前目录 set "filedir=%cd%\file" set "keystoreFile=%filedir%\demo.jks" set "alias=test_cert" set "cerFile=%filedir%\demo.cer" set "storepass=storepass" rem 建议去掉此项改为手工录入 rem 对称加密算法genkey 非对称加密 genkeypair rem set "gen=-genkeypair" rem set "gen=-genkey" rem dname "CN=JsHand,OU=Sinosig CLD,O=Sinosig,L=BJ,ST=BJ,C=CN" set "dname="CN=JsHand,OU=Sinosig CLD,O=Sinosig,L=BJ,ST=BJ,C=CN"" echo ******************************************** echo 证书信息 echo ******************************************** echo keystoreFile 文件存储名为:%keystoreFile% echo alias 别名为:%alias% echo storepass 别名密码为:********* echo 按任意键生成证书 pause>nul cls echo. keytool -export -keystore %keystoreFile% -alias %alias% -file %cerFile% -storepass %storepass% echo 按任意键退出程序 pause>nul
03-initInfo.cmd (显示工具信息,无关紧要)
pause @echo off rem 设置颜色 纯属为了美观,非必须 color 3A echo ********************************************* echo 关于本工具 echo ********************************************* echo 欢迎使用 keytool 证书生成工具 echo http://www.jshand.com echo 本程序利用java keytool 命令 echo 需要配置java环境变量,且jdk1.4+ echo 按任意键开始生成... rem 暂停一下,不要显示不想要的 “请按任意键继续. . .” pause>nul cls
04-showJksInfo.cmd (生成证书前显示证书信息 非必须)
echo ******************************************** echo 证书信息 echo ******************************************** echo keystoreFile 文件存储名为:%keystoreFile% echo validity 有效期为:%validity% echo keysize 密钥为:%keysize% echo alias 别名为:%alias% echo keyalg 加密算法为:%keyalg% echo storepass 别名密码为:********* echo keypass 密钥库密码为:******* echo dname 对象为:%dname% echo 按任意键继续生成 pause>nul cls
提供精简版 all.cmd
@echo off rem 生成证书 keytool -genkeypair -validity 30 -keysize 1024 -alias myalias -keyalg RSA -keystore demo.jks -storepass 123456 -keypass 654321 -v -dname "CN=JsHand,OU=jshand.com CLD,O=jshand,L=BJ,ST=BJ,C=CN" echo. rem 导出证书 部分参数 需要与上述参数一致 keytool -export -keystore demo.jks -alias myalias -file demo.cer -storepass 123456 echo. echo 任意键退出 pause>nul
2 使用java代码生成证书
2.1调用sun.security.tools.KeyTool类的main方法
public static void main(String[] args) throws Exception { // 所有变量都是写死的, 可以自己修改 // 生成证书 String doscmd = "-genkeypair -validity 30 -keysize 1024 " + " -alias myalias -keyalg RSA -keystore d:\\demo.jks -storepass 123456 " + " -keypass 654321 -v -dname CN=JsHand,OU=jshand.com,O=jshand,L=BJ,ST=BJ,C=CN"; String[] paramArrayOfString = doscmd.split("\\s+"); sun.security.tools.KeyTool.main(paramArrayOfString); // 暂停1.5秒 否则没有生成证书 后会导致导出证书也失败 Thread.sleep(1500); // 导出证书 doscmd = "-export -keystore d:\\demo.jks -alias myalias -file d:\\demo.cer -storepass 123456 "; paramArrayOfString = doscmd.split("\\s+"); sun.security.tools.KeyTool.main(paramArrayOfString); }
2.2调用keytool.exe
此处采用网上的实现,即java调用cmd命令后执行keytool,其中有个线程休眠操作,防止生成证书命令未执行完 随即执行导出证书命令,所有参数均写死,可以优化成变量传参的形式。代码如下
import java.io.InputStream; /** * TODO(用一句话描述该文件的作用) * * @title: CreateAndExportPKI.java * @author zhangjinshan-ghq * @date 2014-6-5 下午12:12:37 */ /** * TODO(这里用一句话描述这个类的作用) * * @className CreateAndExportPKI * @author zhangjinshan-ghq * @version V1.0 2014-6-5 下午12:12:37 TODO(如果是修改版本,描述修改内容) */ public class CreateAndExportPKI { public static void execDos(String doscmd) throws InterruptedException { String[] cmd = new String[3]; cmd[0] = "cmd.exe"; cmd[1] = "/C"; cmd[2] = doscmd; String executeComd = "cmd.exe " + " /C " + doscmd; try { System.out.println("cmd 命令如下-->" + cmd[2]); Runtime runtime = Runtime.getRuntime(); Process processa = runtime.exec(executeComd); InputStream in = processa.getInputStream(); Thread.sleep(1500); // 将cmd显示的内容输出到命令行 while (in.available() > 0) { byte[] b = new byte[in.available()]; in.read(b); System.out.println(new String(b, "iso8859-1")); } in.close(); } catch (java.io.IOException e) { System.err.println("IOException " + e.getMessage()); } } public static void main(String[] args) throws InterruptedException { // 所有变量都是写死的, 可以自己修改 // 生成证书 String doscmd = " keytool -genkeypair -validity 30 -keysize 1024 " + " -alias myalias -keyalg RSA -keystore d:\\demo.jks -storepass 123456 " + " -keypass 654321 -v -dname \"CN=JsHand,OU=jshand.com CLD,O=jshand,L=BJ,ST=BJ,C=CN\""; execDos(doscmd); // 暂停1.5秒 否则没有生成证书 后会导致导出证书也失败 Thread.sleep(1500); // 导出证书 doscmd = "keytool -export -keystore d:\\demo.jks -alias myalias -file d:\\demo.cer -storepass 123456 "; execDos(doscmd); } }
3 参考
3.1 keytool 具体参数如下(摘自网络,可以百度或者Google)
-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链全部打印出来。
3.2 命令行中keytool的所有参数
keytool 用法: -certreq [-v] [-protected] [-alias <别名>] [-sigalg <sigalg>] [-file <csr_file>] [-keypass <密钥库口令>] [-keystore <密钥库>] [-storepass <存储库口令>] [-storetype <存储类型>] [-providername <名称>] [-providerclass <提供方类名称> [-providerarg <参数>]] ... [-providerpath <路径列表>] -changealias [-v] [-protected] -alias <别名> -destalias <目标别名> [-keypass <密钥库口令>] [-keystore <密钥库>] [-storepass <存储库口令>] [-storetype <存储类型>] [-providername <名称>] [-providerclass <提供方类名称> [-providerarg <参数>]] ... [-providerpath <路径列表>] -delete [-v] [-protected] -alias <别名> [-keystore <密钥库>] [-storepass <存储库口令>] [-storetype <存储类型>] [-providername <名称>] [-providerclass <提供方类名称> [-providerarg <参数>]] ... [-providerpath <路径列表>] -exportcert [-v] [-rfc] [-protected] [-alias <别名>] [-file <认证文件>] [-keystore <密钥库>] [-storepass <存储库口令>] [-storetype <存储类型>] [-providername <名称>] [-providerclass <提供方类名称> [-providerarg <参数>]] ... [-providerpath <路径列表>] -genkeypair [-v] [-protected] [-alias <别名>] [-keyalg <keyalg>] [-keysize <密钥大小>] [-sigalg <sigalg>] [-dname <dname>] [-validity <valDays>] [-keypass <密钥库口令>] [-keystore <密钥库>] [-storepass <存储库口令>] [-storetype <存储类型>] [-providername <名称>] [-providerclass <提供方类名称> [-providerarg <参数>]] ... [-providerpath <路径列表>] -genseckey [-v] [-protected] [-alias <别名>] [-keypass <密钥库口令>] [-keyalg <keyalg>] [-keysize <密钥大小>] [-keystore <密钥库>] [-storepass <存储库口令>] [-storetype <存储类型>] [-providername <名称>] [-providerclass <提供方类名称> [-providerarg <参数>]] ... [-providerpath <路径列表>] -help -importcert [-v] [-noprompt] [-trustcacerts] [-protected] [-alias <别名>] [-file <认证文件>] [-keypass <密钥库口令>] [-keystore <密钥库>] [-storepass <存储库口令>] [-storetype <存储类型>] [-providername <名称>] [-providerclass <提供方类名称> [-providerarg <参数>]] ... [-providerpath <路径列表>] -importkeystore [-v] [-srckeystore <源密钥库>] [-destkeystore <目标密钥库>] [-srcstoretype <源存储类型>] [-deststoretype <目标存储类型>] [-srcstorepass <源存储库口令>] [-deststorepass <目标存储库口令>] [-srcprotected] [-destprotected] [-srcprovidername <源提供方名称>] [-destprovidername <目标提供方名称>] [-srcalias <源别名> [-destalias <目标别名>] [-srckeypass <源密钥库口令>] [-destkeypass <目标密钥库口令>]] [-noprompt] [-providerclass <提供方类名称> [-providerarg <参数>]] ... [-providerpath <路径列表>] -keypasswd [-v] [-alias <别名>] [-keypass <旧密钥库口令>] [-new <新密钥库口令>] [-keystore <密钥库>] [-storepass <存储库口令>] [-storetype <存储类型>] [-providername <名称>] [-providerclass <提供方类名称> [-providerarg <参数>]] ... [-providerpath <路径列表>] -list [-v | -rfc] [-protected] [-alias <别名>] [-keystore <密钥库>] [-storepass <存储库口令>] [-storetype <存储类型>] [-providername <名称>] [-providerclass <提供方类名称> [-providerarg <参数>]] ... [-providerpath <路径列表>] -printcert [-v] [-file <认证文件>] -storepasswd [-v] [-new <新存储库口令>] [-keystore <密钥库>] [-storepass <存储库口令>] [-storetype <存储类型>] [-providername <名称>] [-providerclass <提供方类名称> [-providerarg <参数>]] ...
3.4 bat 获取当期路径
http://blog.csdn.net/guomao545/article/details/6417667
3.5 java命令keytool 中的参数
http://woainishijin456.blog.163.com/blog/static/9893862620124153220890/