1、使用生成keystore,路径d:/wymtest.keystore,如果不存在,自动创建;如果存在,则在其中添加
C:\Users>keytool -genkey -alias test11 -keyalg RSA -keysize 1024 -keystore d:/wymtest.keystore -validity 4000
-validity参数可以指定所创建的证书有效期是多少天
-alias test11指定别名;当密钥库中有多个公钥/私钥对和证书时,应该使用别名,同一个密钥库中可以存放多个条目(公钥/私钥对和证书),它们在密钥库中以别名(alias)区分。
比如:这里如果再次使用test11别名执行一次的话,报错:keytool错误: java.lang.Exception: 没有创建键值对,别名 已经存在
当密钥库中只有一个密钥对别名时,可以使用jdk中的方法获取别名,然后进行加解密;
但是,如果密钥库中存在多个别名的话,由于无法区别该别名属于哪个密钥对,所以不要使用此方法
FileInputStream is = new FileInputStream(new File("d:\\wymtest.keystore"));
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(is, "123456".toCharArray());
Enumeration aliasEnum = keyStore.aliases();
String keyAlias = "" ;
while (aliasEnum.hasMoreElements()) {
keyAlias = (String) aliasEnum.nextElement();
System.out.println("别名"+keyAlias);
}
输出结果:别名test11
2、加载公私钥。测试签名验签
public static void main(String aa[]) throws Exception {
FileInputStream is = new FileInputStream(new File("d:\\wymtest.keystore"));
KeyStore keyStore = KeyStore.getInstance("JKS");
//这里填设置的keystore密码,两个可以不一致
keyStore.load(is, "123456".toCharArray());
//加载别名,这里认为只有一个别名,可以这么取;当有多个别名时,别名要用参数传进来。不然,第二次的会覆盖第一次的
Enumeration aliasEnum = keyStore.aliases();
String keyAlias = "" ;
while (aliasEnum.hasMoreElements()) {
keyAlias = (String) aliasEnum.nextElement();
System.out.println("别名"+keyAlias);
}
Certificate certificate = keyStore.getCertificate(keyAlias);
//加载公钥
PublicKey publicKey = keyStore.getCertificate(keyAlias).getPublicKey();
//加载私钥,这里填私钥密码
PrivateKey privateKey = ((KeyStore.PrivateKeyEntry) keyStore.getEntry(keyAlias,
new KeyStore.PasswordProtection("123456".toCharArray()))).getPrivateKey();
//加载私钥另一写法
//PrivateKey privateKey = (PrivateKey) keyStore.getKey(keyAlias, "123456".toCharArray());
//base64输出私钥
String strKey = Base64.encodeBase64String(privateKey.getEncoded());
System.out.println(strKey);
//测试签名
String sign = Base64.encodeBase64String(sign("测试msg".getBytes(),privateKey,"SHA1withRSA",null));
//测试验签
boolean verfi = verify("测试msg".getBytes(),Base64.decodeBase64(sign), publicKey,"SHA1withRSA",null);
System.out.println(verfi);
}
/**
* 签名
*/
public static byte[] sign(byte[] message, PrivateKey privateKey, String algorithm, String provider) throws Exception {
Signature signature;
if (null == provider || provider.length() == 0) {
signature = Signature.getInstance(algorithm);
} else {
signature = Signature.getInstance(algorithm, provider);
}
signature.initSign(privateKey);
signature.update(message);
return signature.sign();
}
/**
* 验签
*/
public static boolean verify(byte[] message, byte[] signMessage, PublicKey publicKey, String algorithm,
String provider) throws Exception {
Signature signature;
if (null == provider || provider.length() == 0) {
signature = Signature.getInstance(algorithm);
} else {
signature = Signature.getInstance(algorithm, provider);
}
signature.initVerify(publicKey);
signature.update(message);
return signature.verify(signMessage);
}
最后输出:true。表示加载和测试通过。
3、这个keystore中是单一的密钥对。下面再往里面放一个看看。
keytool -genkey -alias test22 -keyalg RSA -keysize 1024 -keystore d:/wymtest.keystore -validity 4000
再次放一个别名为test22进去。(每次别名都不能相同,否则报错:java.lang.Exception: 没有创建键值对,别名 xxx已经存在
).
此时再用上面1、中的方法测试输入如下:
别名test11
别名test22
所以,keystore中存在多个别名时,应该将别名用参数传递进来。
付:如果使用其他方式,如用openssl之类的工具产生证书和密钥时,别名不是必须的,虽然生产时没有指定,然而却有默认的别名,如1 2 3等。在获取密钥和证书时,依然需要指定别名。
其他命令:https://blog.csdn.net/u014386474/article/details/51996019