基于密钥库和数字证书的加密解密和签名验证操作

Posted yuwei1

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于密钥库和数字证书的加密解密和签名验证操作相关的知识,希望对你有一定的参考价值。


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("加密前:
" + inputStr);
        System.err.println("解密后:
" + 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("加密前:
" + inputStr);
        System.err.println("解密后:
" + 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("签名:
" + Hex.encodeHexString(sign));
        // 验证签名
        boolean status = CertificateCoder.verify(data, sign, certficatePath);
        System.err.println("状态:
" + status);
        // 校验
        // assertTure(status);
        
    }
    
    

}

 


以上是关于基于密钥库和数字证书的加密解密和签名验证操作的主要内容,如果未能解决你的问题,请参考以下文章

09.openssl信息摘要和数字签名指令

数字签名的实现方案

Tomcat 服务器和 HTTP 客户端接受过期的自签名证书

如何利用java程序实现加密所需的公钥密钥数字证书

Windows密钥容器和证书的关系

[转]RSA数字签名与数字信封