非对称加密的介绍请查看这篇文章
直接进入正题:
1、生成密钥库
keytool -genkeypair -keysize 2048 -keyalg RSA -alias test -dname "cn=test,ou=test,o=test,l=wlmq,st=xj,c=tk" -keypass 123123 -storepass 123123 -keystore test.keystore
以上命令生成一个test.keystore的密钥库文件算法是RSA 密钥长度是2048,密钥库密码:123123,私钥的密钥:123123
查看刚生成的密钥库信息:
keytool -list -storepass 123123 -keystore test.keystore
输出:
这里能看到我们刚生成的密钥库中包含1个别名为test的证书
2、导出证书
keytool -export cert -alias test -storepass 123123 -keystore test.keystore -file test.cer -v
在当前目录下就生成了一个test.cer的证书
该证书中只包含公钥信息,一般用来解密和验签。
查看证书:
keytool -printcert -file test.cer
输出:
接下来我们通过java代码来实现 非对称加密算法
cer证书中只包含公钥信息,私钥信息保存在我们的密钥库中。
我们通过公钥加密私钥解密和私钥加密公钥解密来进行验证:
3、通过证书获取公钥,密钥库获取私钥进行加解密
package com.pack.security;
import java.io.File;
import java.io. FileInputStream ;
import java.io.InputStream;
import java.security.Key;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import javax.crypto.Cipher;
public class X509CertDemo {
/**
* <p>解析证书</p>
* @param path
* @return 证书对象
* @throws Exception
*/public static Certificate parseCert(String path) throws Exception {
InputStream inStream = new FileInputStream(path);
CertificateFactory cf = CertificateFactory. getInstance ("X.509");
Certificate cert = cf.generateCertificate(inStream);
return cert ;
}
public static PublicKey getPublicKey(Certificate cert) {
return cert.getPublicKey() ;
}
/**
* <p>通过密钥库文件获取私钥信息</p>
* @param storePath
* @return 私钥
* @throws Exception
*/public static PrivateKey getPrivateKey(String storePath) throws Exception {
KeyStore keyStore = KeyStore.getInstance("JKS") ;
keyStore.load(new FileInputStream(new File(storePath)), "123123".toCharArray());
Key key = keyStore.getKey("test", "123123".toCharArray()) ;
return (PrivateKey) key ;
}
/**
* <p>加密</p>
* @author pack
* @param publicKey 公钥
* @param input 数据源
* @throws Exception
* @return byte[]
*/public static byte[] encrypt(Key key, String input) throws Exception {
Cipher cipher = Cipher.getInstance("RSA") ;
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] result = cipher.doFinal(input.getBytes()) ;
return result ;
}
/**
* <p>解密</p>
* @param key
* @param input
* @throws Exception
*/public static void decrypt(Key key, byte[] input) throws Exception {
Cipher cipher = Cipher.getInstance("RSA") ;
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] result = cipher.doFinal(input) ;
System.out.println(new String(result)) ;
}
public static void main(String[] args) throws Exception {
String path = "f:secrettest.cer" ;
String storePath = "f:secrettest.keystore" ;
String input = "java@pack" ;
PublicKey publicKey = getPublicKey(parseCert(path)) ;
byte[] secret = encrypt(publicKey, input) ;
PrivateKey privateKey = getPrivateKey(storePath) ;
decrypt(privateKey, secret) ;
System.out.println("-----------------以上公钥加密私钥解密-----------------") ;
System.out.println("-----------------以下私钥加密公钥解密-----------------") ;
secret = encrypt(privateKey, input) ;
decrypt(publicKey, secret) ;
}
}
输出结果:
由于非对称加密算法性能相比对称加密算法速度要慢的多,并且非对称加密算法对加密的内容长度要求很苛刻,比如rsa 1024密钥长度和2048密钥长度加密的内容长度是不一样的。2048长度的密码要求加密的内容不能大有245个字节。所以一般非对称加密算法用来加密对称加密算法的密钥,比如我们的https。
完毕!!!