基于密钥库和数字证书的加密解密和签名验证操作
package com.szzs; import java.io.FileInputStream; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import javax.crypto.Cipher; public class CertificateCoder { // 类型证书X.509 public static final String CERT_TYPE = "X.509"; // 1.根据密钥库获得私钥 private static PrivateKey getPrivateKeyByKeyStore(String keyStorePath,String alias, String password) throws Exception{ // 获得密钥库 KeyStore ks = getKeyStore(keyStorePath,password); // 根据别名和密码获取私钥 PrivateKey privateKey = (PrivateKey) ks.getKey(alias, password.toCharArray()); return privateKey; } // 2.根据证书获取公钥 private static PublicKey getPublicKeyByCertificate(String certificatePath) throws Exception { // 获得证书 Certificate certificate = getCertificate(certificatePath); // 获得证书公钥 return certificate.getPublicKey(); } // 3.加载数字证书:certificatePath为证书路径 private static Certificate getCertificate(String certificatePath) throws Exception { // 实例化证书工厂 CertificateFactory certificateFactory = CertificateFactory.getInstance(CERT_TYPE); // 取得证书文件流 FileInputStream in = new FileInputStream(certificatePath); // 生成证书 Certificate certificate = certificateFactory.generateCertificate(in); //关闭证书文件流 in.close(); return certificate; } // 4.根据别名从密钥库获得数字证书 private static Certificate getCertificate(String keyStorePath, String alias, String password ) throws Exception { // 获得密钥库 KeyStore ks = getKeyStore(keyStorePath, password); // 获得证书 return ks.getCertificate(alias); } // 5.根据密钥库路径获得KeyStore private static KeyStore getKeyStore(String keyStorepath, String password) throws Exception { // 实例化密钥库 KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); // 获得密钥库文件流 FileInputStream is = new FileInputStream(keyStorepath); // 加载密钥库 ks.load(is, password.toCharArray()); // 关闭密钥库文件流 is.close(); return ks; } // 6.私钥加密 public static byte[] encryptByPrivateKey(byte[] data, String keyStorePath, String alias, String password) throws Exception { // 取得私钥 PrivateKey privateKey = getPrivateKeyByKeyStore(keyStorePath,alias,password); // 对数据加密 Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateKey); return cipher.doFinal(data); } // 7.私钥解密 public static byte[] decryptByPrivateKey(byte[] data, String keyStorePath, String alias, String password) throws Exception { // 取得私钥 PrivateKey privateKey = getPrivateKeyByKeyStore(keyStorePath,alias,password); // 对数据加密 Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateKey); return cipher.doFinal(data); } // 8.公钥加密:返回加密后数据 public static byte[] encryptByPublicKey(byte[] data, String certificatePath) throws Exception { // 取得公钥 PublicKey publicKey = getPublicKeyByCertificate(certificatePath); // 对数据加密 Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicKey); return cipher.doFinal(data); } // 9.公钥解密 public static byte[] decryptByPublicKey(byte[] data, String certificatePath) throws Exception { // 取得私钥 PublicKey publicKey = getPublicKeyByCertificate(certificatePath); // 对数据加密 Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicKey); return cipher.doFinal(data); } // 10.获取签名 public static byte[] sign(byte[] sign, String keyStorePath, String alias, String password) throws Exception { // 根据密钥库路径,密钥库别名,密码获得证书 X509Certificate x509Certificate = (X509Certificate) getCertificate(keyStorePath, alias, password); // 构建签名,由证书指定签名算法 Signature signature = Signature.getInstance(x509Certificate.getSigAlgName()); // 获得私钥 PrivateKey privateKey = getPrivateKeyByKeyStore(keyStorePath, alias, password); // 初始化签名,由私钥构建 signature.initSign(privateKey); signature.update(sign); return signature.sign(); //返回签名 } // 11.验证签名,签名为真返回ture public static boolean verify(byte[] data, byte[] sign, String certificatePath) throws Exception { // 获得证书 X509Certificate x509Certificate = (X509Certificate) getCertificate(certificatePath); // 构建签名,由证书指定签名算法 Signature signature = Signature.getInstance(x509Certificate.getSigAlgName()); // 由证书初始化签名,实际是用了证书中的公钥 signature.initVerify(x509Certificate); signature.update(data); return signature.verify(sign); } }
测试:
package com.szzs; // 基于密钥库和数字证书的加密解密和签名验证操作 public class CertificateCoderTest { private String password = "123456"; private String alias = "www.zlex.org"; private String certficatePath = "D:/zlex.cer"; // 数字证书 private String keyStorePath = "D:/zlex.keystore"; // 密钥库 // 1.公钥加密,私钥解密 public void test1() throws Exception { System.out.println("公钥加密--私钥解密"); String inputStr = "数字证书"; byte[] data = inputStr.getBytes(); // 公钥加密 byte[] encrypt = CertificateCoder.encryptByPublicKey(data, certficatePath); // 私钥解密 byte[] decrypt = CertificateCoder.decryptByPrivateKey(data, keyStorePath, alias, password); String outputStr = new String(decrypt); System.err.println("加密前:\n" + inputStr); System.err.println("解密后:\n" + outputStr); // 验证数据一致 // assertArrayEquals(data, decrypt); } // 2.私钥加密,公钥解密 public void test2() throws Exception { System.out.println("私钥加密--公钥解密"); String inputStr = "数字签名"; byte[] data = inputStr.getBytes(); // 私钥加密 byte[] encodedData = CertificateCoder.encryptByPrivateKey(data, keyStorePath, alias, password); // 公钥解密 byte[] decodedData = CertificateCoder.decryptByPublicKey(data, certficatePath); String outputStr = new String(decodedData); System.err.println("加密前:\n" + inputStr); System.err.println("解密后:\n" + outputStr); // 验证数据一致 // assertEquals(inputStr, outputStr); } // 3.签名验证 public void testSign() throws Exception { String inputStr = "签名"; byte[] data = inputStr.getBytes(); System.out.println("私钥签名---公钥验证"); // 产生签名 byte[] sign = CertificateCoder.sign(data, keyStorePath, alias, password); // System.err.println("签名:\n" + Hex.encodeHexString(sign)); // 验证签名 boolean status = CertificateCoder.verify(data, sign, certficatePath); System.err.println("状态:\n" + status); // 校验 // assertTure(status); } }