PKI公钥基础设施JAVA工具类

1 篇文章 0 订阅

1、公钥加密,私钥解密 
2、私钥加密,公钥解密 
3、私钥签名,公钥验证签名

http://www.oschina.net/code/snippet_121944_15275

package com.apdplat.platform.util;

import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * 
 * @author ysc
 */
public class PKIUtils {
    private static final Logger log = LoggerFactory.getLogger(PKIUtils.class);
       
    private PKIUtils(){}
    /**
     * 
     * 用证书的私钥签名
     * @param in 证书库
     * @param storePassword 证书库密码
     * @param keyPassword 证书密码
     * @param key 钥别名
     * @param data 待签名数据
     * @return 签名
     */
    public static byte[] signature(InputStream in, String storePassword, String keyPassword, String key, byte[] data) {
        try {
            // 获取证书私钥
            PrivateKey privateKey = getPrivateKey(in, storePassword, keyPassword, key);
            Signature signet = Signature.getInstance("MD5withRSA");
            signet.initSign(privateKey);
            signet.update(data);
            byte[] signed = signet.sign(); // 对信息的数字签名
            return signed;
        } catch (Exception ex) {
            log.error("签名失败",ex);
        }
        return null;
    }
    /**
     * 用证书的公钥验证签名
     * @param in 证书
     * @param data 原始数据
     * @param signatureData 对原始数据的签名
     * @return 
     */
    public static boolean verifySignature(InputStream in, byte[] data, byte[] signatureData){
        try {
            // 获取证书公钥
            PublicKey key = getPublicKey(in);
            Signature signet = Signature.getInstance("MD5withRSA");
            signet.initVerify(key);
            signet.update(data);
            boolean result=signet.verify(signatureData);
            return result;
        } catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException ex) {
            log.error("验证签名失败",ex);
        }
        return false;
    }

    /**
     * 获取证书公钥
     * @param in 证书
     * @return 公钥
     */
    private static PublicKey getPublicKey(InputStream in) {
        try {
            // 用证书的公钥加密
            CertificateFactory factory = CertificateFactory.getInstance("X.509");
            Certificate cert = factory.generateCertificate(in);
            // 得到证书文件携带的公钥
            PublicKey key = cert.getPublicKey();
            return key;
        } catch (CertificateException ex) {
            log.error("获取证书公钥失败",ex);
        }
        return null;
    }

    /**
     * 加密数据
     * @param key 公钥或私钥
     * @param data 待加密数据
     * @return 
     */
    public static byte[] encrypt(Key key, byte[] data) {
        try {
            // 定义算法:RSA
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.ENCRYPT_MODE, key);
            // 正式执行加密操作
            byte encryptedData[] = cipher.doFinal(data);
            return encryptedData;
        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException ex) {
            log.error("加密数据失败",ex);
        }
        return null;
    }
    /**
     * 用证书的公钥加密
     * @param in 证书
     * @param data 待加密数据
     * @return 密文
     */
    public static byte[] encryptWithPublicKey(InputStream in, byte[] data) {
        try {
            // 获取证书公钥
            PublicKey key = getPublicKey(in);
            
            byte encryptedData[] = encrypt(key,data);
            return encryptedData;
        } catch (Exception ex) {
            log.error("用证书的公钥加密失败",ex);
        }
        return null;
    }
    /**
     * 用证书的私钥加密
     * @param in 证书库
     * @param storePassword 证书库密码
     * @param keyPassword 证书密码
     * @param key 钥别名
     * @param data 待加密数据
     * @return 密文
     */
    public static byte[] encryptWithPrivateKey(InputStream in, String storePassword, String keyPassword, String key, byte[] data) {
        try {
            // 获取证书私钥
            PrivateKey privateKey = getPrivateKey(in, storePassword, keyPassword, key);
            
            byte encryptedData[] = encrypt(privateKey,data);
            return encryptedData;
        } catch (Exception ex) {
            log.error("用证书的私钥加密失败",ex);
        }
        return null;
    }

    /**
     * 获取证书私钥
     * @param in 证书库
     * @param storePassword 证书库密码
     * @param keyPassword 证书密码
     * @param key 钥别名
     * @return 私钥
     */
    private static PrivateKey getPrivateKey(InputStream in, String storePassword, String keyPassword, String key) {
        try {
            // 加载证书库
            KeyStore ks = KeyStore.getInstance("JKS");
            ks.load(in, storePassword.toCharArray());
            // 获取证书私钥
            PrivateKey privateKey = (PrivateKey) ks.getKey(key, keyPassword.toCharArray());
            return privateKey;
        } catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException | UnrecoverableKeyException ex) {
            log.error("获取证书私钥失败",ex);
        }
        return null;
    }

    /**
     * 解密数据
     * @param key 公钥或私钥
     * @param data 待解密数据
     * @return  明文
     */
    public static byte[] decrypt(Key key, byte[] data) {
        try {
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.DECRYPT_MODE, key);
            // 解密后的数据
            byte[] result = cipher.doFinal(data);
            return result;
        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException ex) {
            log.error("解密数据失败",ex);
        }
        return null;
    }
    /**
     * 
     * 用证书的私钥解密 
     * @param in 证书库
     * @param storePassword 证书库密码
     * @param keyPassword 证书密码
     * @param key 钥别名
     * @param data 待解密数据
     * @return 明文
     */
    public static byte[] decryptWithPrivateKey(InputStream in, String storePassword, String keyPassword, String key, byte[] data) {
        try {
            // 获取证书私钥
            PrivateKey privateKey = getPrivateKey(in, storePassword, keyPassword, key);
            // 解密后的数据
            byte[] result = decrypt(privateKey,data);
            return result;
        } catch (Exception ex) {
            log.error("用证书的私钥解密失败",ex);
        }
        return null;
    }
    /**
     * 
     * 用证书的公钥解密 
     * @param in 证书
     * @param data 待解密数据
     * @return 明文
     */
    public static byte[] decryptWithPublicKey(InputStream in, byte[] data) {
        try {
            // 获取证书公钥
            PublicKey key = getPublicKey(in);
            // 解密后的数据
            byte[] result = decrypt(key,data);
            return result;
        } catch (Exception ex) {
            log.error("用证书的公钥解密失败",ex);
        }
        return null;
    }
}

package com.apdplat.platform.util;

import junit.framework.Assert;
import org.junit.Test;

/**
 *
 * @author ysc
 */
public class PKIUtilsTest {

     //private String cert = "/com/apdplat/module/security/pki/apdplat_public.crt";
     private String cert = "/com/apdplat/module/security/pki/apdplat.crt";
     private String store = "/com/apdplat/module/security/pki/apdplat.keystore";
     private String plainText = "apdplat应用级开发平台(杨尚川)";
    @Test
    public void testEncryptAndDecrypt1() {
        //公钥加密
        byte[] result = PKIUtils.encryptWithPublicKey(PKIUtilsTest.class.getResourceAsStream(cert), plainText.getBytes());        
        
        //私钥解密
        result = PKIUtils.decryptWithPrivateKey(PKIUtilsTest.class.getResourceAsStream(store), "apdplat_core_module", "apdplat_core_module", "apdplat", result);
        
        Assert.assertEquals(plainText, new String(result));
    }
    @Test
    public void testEncryptAndDecrypt2() {
        //私钥加密
        byte[] result = PKIUtils.encryptWithPrivateKey(PKIUtilsTest.class.getResourceAsStream(store), "apdplat_core_module", "apdplat_core_module", "apdplat", plainText.getBytes());        
        
        //公钥解密
        result = PKIUtils.decryptWithPublicKey(PKIUtilsTest.class.getResourceAsStream(cert), result);
        
        Assert.assertEquals(plainText, new String(result));
    }
    @Test
    public void testSignatureAndVerifySignature() {
        //私钥签名
        byte[] signature = PKIUtils.signature(PKIUtilsTest.class.getResourceAsStream(store), "apdplat_core_module", "apdplat_core_module", "apdplat", plainText.getBytes());

        //公钥验证签名
        boolean correct=PKIUtils.verifySignature(PKIUtilsTest.class.getResourceAsStream(cert),plainText.getBytes(),signature);
        
        Assert.assertTrue(correct);
    }
}



  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值