https://blog.csdn.net/jianggujin/article/details/53486725
系统之间在进行交互的时候,我们经常会用到数字证书,数字证书可以帮我们验证身份等,下面我们就来看一下在java中如何使用数字证书。
我们先使用keytool工具生成密钥库并导出公钥证书。
第一步:生成keyStroe文件
执行如下命令:
keytool -genkey -validity 36000 -alias www.jianggujin.com -keyalg RSA -keystore test.keystore
该命令相关参数如下:
输入完后,我们需要按照提示完成后续信息的输入,这里面我们使用的密码为:123456
第二步:导出公钥证书
生成完密钥库后,我们就可以导出公钥文件了,执行如下命令:
keytool -export -keystore test.keystore -alias www.jianggujin.com -file test.cer -rfc
该命令相关参数如下:
package com.busy.base64pack;
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Date;
import javax.crypto.Cipher;
/**
* 数字证书
*/
public class HQCertificate {
private static HQCertificate certificate = new HQCertificate();
public static HQCertificate getInstance() {
return certificate;
}
private HQCertificate() {
}
/**
* 密钥库
*/
public static enum HQKeyStore {
JCEKS("jceks"), JKS("jks"), DKS("dks"), PKCS11("pkcs11"), PKCS12("pkcs12");
private String name;
private HQKeyStore(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}
/**
* Java密钥库(Java Key Store,JKS)KEY_STORE
*/
// public final String KEY_STORE = "JKS";
public final String X509 = "X.509";
/**
* 由KeyStore获得私钥
*
* @param keyStorePath
* @param alias
* @param password
* @return
* @throws Exception
*/
private PrivateKey getPrivateKey(String keyStorePath, String alias, char[] password, HQKeyStore keyStore)
throws Exception {
KeyStore ks = getKeyStore(keyStorePath, password, keyStore);
PrivateKey key = (PrivateKey) ks.getKey(alias, password);
return key;
}
/**
* 由Certificate获得公钥
*
* @param certificatePath
* @return
* @throws Exception
*/
private PublicKey getPublicKey(String certificatePath) throws Exception {
Certificate certificate = getCertificate(certificatePath);
PublicKey key = certificate.getPublicKey();
return key;
}
/**
* 获得Certificate
*
* @param certificatePath
* @return
* @throws Exception
*/
private Certificate getCertificate(String certificatePath) throws Exception {
CertificateFactory certificateFactory = CertificateFactory.getInstance(X509);
FileInputStream in = new FileInputStream(certificatePath);
Certificate certificate = certificateFactory.generateCertificate(in);
in.close();
return certificate;
}
/**
* 获得Certificate
*
* @param keyStorePath
* @param alias
* @param password
* @return
* @throws Exception
*/
private Certificate getCertificate(String keyStorePath, String alias, char[] password, HQKeyStore keyStore)
throws Exception {
KeyStore ks = getKeyStore(keyStorePath, password, keyStore);
return getCertificate(ks, alias);
}
private Certificate getCertificate(KeyStore keyStore, String alias) throws Exception {
Certificate certificate = keyStore.getCertificate(alias);
return certificate;
}
/**
* 获得KeyStore
*
* @param keyStorePath
* @param password
* @return
* @throws Exception
*/
public KeyStore getKeyStore(String keyStorePath, char[] password, HQKeyStore keyStore) throws Exception {
KeyStore store = null;
FileInputStream is = new FileInputStream(keyStorePath);
store = getKeyStore(is, password, keyStore);
is.close();
return store;
}
public KeyStore getKeyStore(InputStream in, char[] password, HQKeyStore keyStore) throws Exception {
KeyStore ks = KeyStore.getInstance(keyStore.getName());
ks.load(in, password);
return ks;
}
/**
* 私钥加密
*
* @param data
* @param keyStorePath
* @param alias
* @param password
* @return
* @throws Exception
*/
public byte[] encrypt(byte[] data, String keyStorePath, String alias, char[] password, HQKeyStore keyStore)
throws Exception {
// 取得私钥
PrivateKey privateKey = getPrivateKey(keyStorePath, alias, password, keyStore);
return encrypt(data, privateKey);
}
public byte[] encrypt(byte[] data, PrivateKey privateKey) throws Exception {
// 对数据加密
Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
/**
* 公钥加密
*
* @param data
* @param certificatePath
* @return
* @throws Exception
*/
public byte[] encrypt(byte[] data, String certificatePath) throws Exception {
// 取得公钥
PublicKey publicKey = getPublicKey(certificatePath);
return encrypt(data, publicKey);
}
public byte[] encrypt(byte[] data, PublicKey publicKey) throws Exception {
// 对数据加密
Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(data);
}
/**
* 私钥解密
*
* @param data
* @param keyStorePath
* @param alias
* @param password
* @return
* @throws Exception
*/
public byte[] decrypt(byte[] data, String keyStorePath, String alias, char[] password, HQKeyStore keyStore)
throws Exception {
// 取得私钥
PrivateKey privateKey = getPrivateKey(keyStorePath, alias, password, keyStore);
return decrypt(data, privateKey);
}
public byte[] decrypt(byte[] data, PrivateKey privateKey) throws Exception {
// 对数据加密
Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
/**
* 公钥解密
*
* @param data
* @param certificatePath
* @return
* @throws Exception
*/
public byte[] decrypt(byte[] data, String certificatePath) throws Exception {
// 取得公钥
PublicKey publicKey = getPublicKey(certificatePath);
// 对数据加密
Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, publicKey);
return decrypt(data, publicKey);
}
public byte[] decrypt(byte[] data, PublicKey publicKey) throws Exception {
// 对数据加密
Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, publicKey);
return cipher.doFinal(data);
}
/**
* 验证Certificate
*
* @param certificatePath
* @return
*/
public boolean verifyCertificate(String certificatePath) {
return verifyCertificate(new Date(), certificatePath);
}
/**
* 验证Certificate是否过期或无效
*
* @param date
* @param certificatePath
* @return
*/
public boolean verifyCertificate(Date date, String certificatePath) {
boolean status = true;
try {
// 取得证书
Certificate certificate = getCertificate(certificatePath);
// 验证证书是否过期或无效
status = verifyCertificate(date, certificate);
} catch (Exception e) {
status = false;
}
return status;
}
/**
* 验证证书是否过期或无效
*
* @param date
* @param certificate
* @return
*/
private boolean verifyCertificate(Date date, Certificate certificate) {
boolean status = true;
try {
X509Certificate x509Certificate = (X509Certificate) certificate;
x509Certificate.checkValidity(date);
} catch (Exception e) {
status = false;
}
return status;
}
/**
* 签名
*
* @param keyStorePath
* @param alias
* @param password
*
* @return
* @throws Exception
*/
public byte[] sign(byte[] data, String keyStorePath, String alias, char[] password, HQKeyStore keyStore)
throws Exception {
// 获得证书
Certificate certificate = getCertificate(keyStorePath, alias, password, keyStore);
// 取得私钥
PrivateKey privateKey = getPrivateKey(keyStorePath, alias, password, keyStore);
return sign(data, certificate, privateKey);
}
public byte[] sign(byte[] data, Certificate certificate, PrivateKey privateKey) throws Exception {
// 获得证书
X509Certificate x509Certificate = (X509Certificate) certificate;
// 构建签名
Signature signature = Signature.getInstance(x509Certificate.getSigAlgName());
signature.initSign(privateKey);
signature.update(data);
return signature.sign();
}
/**
* 验证签名
*
* @param data
* @param sign
* @param certificatePath
* @return
* @throws Exception
*/
public boolean verify(byte[] data, byte[] sign, String certificatePath) throws Exception {
// 获得证书
Certificate certificate = getCertificate(certificatePath);
return verify(data, sign, certificate);
}
public boolean verify(byte[] data, byte[] sign, Certificate certificate) throws Exception {
// 获得证书
X509Certificate x509Certificate = (X509Certificate) certificate;
// 获得公钥
PublicKey publicKey = x509Certificate.getPublicKey();
// 构建签名
Signature signature = Signature.getInstance(x509Certificate.getSigAlgName());
signature.initVerify(publicKey);
signature.update(data);
return signature.verify(sign);
}
/**
* 验证Certificate
*
* @param keyStorePath
* @param alias
* @param password
* @return
*/
public boolean verifyCertificate(Date date, String keyStorePath, String alias, char[] password,
HQKeyStore keyStore) {
boolean status = true;
try {
Certificate certificate = getCertificate(keyStorePath, alias, password, keyStore);
status = verifyCertificate(date, certificate);
} catch (Exception e) {
status = false;
}
return status;
}
/**
* 验证Certificate
*
* @param keyStorePath
* @param alias
* @param password
* @return
*/
public boolean verifyCertificate(String keyStorePath, String alias, char[] password, HQKeyStore keyStore) {
return verifyCertificate(new Date(), keyStorePath, alias, password, keyStore);
}
}
测试:
package com.busy.base64pack;
import com.busy.base64pack.HQCertificate.HQKeyStore;
public class MainTest {
public static void main(String[] args) throws Exception {
new MainTest().certification();
}
public void certification() throws Exception {
HQCertificate certificate = HQCertificate.getInstance();
HQBase64 base64 = HQBase64.getInstance();
char[] password = "123456".toCharArray();
String alias = "www.busy.com";
String certificatePath = "D:/Program Files/Java/jdk1.8.0_171/bin/code.cer";
String keyStorePath = "D:/Program Files/Java/jdk1.8.0_171/bin/code.keystore";
byte[] data = "houjiaqi".getBytes();
HQKeyStore keyStore = HQKeyStore.JKS;
byte[] signResult = certificate.sign(data, keyStorePath, alias, password, keyStore);
System.out.println("验证证书:" + certificate.verifyCertificate(certificatePath));
System.out.println("签名:" + base64.encodeToString(signResult));
System.out.println("验签:" + certificate.verify(data, signResult, certificatePath));
byte[] result = certificate.encrypt(data, keyStorePath, alias, password, HQKeyStore.JKS);
System.out.println("加密:" + base64.encodeToString(result));
System.out.println("解密:" + new String(certificate.decrypt(result, certificatePath)));
}
}