Java读取pem格式公钥/私钥实现RSA加解密

1.使用openssl生成私钥和公钥

    openssl生成私钥命令: openssl genrsa -out rsa_private_key.pem 1024
    openssl生成公钥命令: openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
此时可以看到 rsa_private_key.pem 和 rsa_public_key.pem 两个文件。这时候的私钥是不能直接使用的,需要进行 pkcs8 编码。

2.pkcs8编码

openssl的pkcs8编码命令:openssl pkcs8 -topk8 -in rsa_private_key.pem -out  pkcs8_rsa_private_key.pem -nocrypt
    此时可以看到 pkcs8_rsa_private_key.pem 文件。
    至此,可用的密钥对已经生成好了,私钥使用pkcs8_rsa_private_key.pem,公钥采用rsa_public_key.pem。

3.使用密钥对进行签名、加解密

   公钥加密数据,然后私钥解密的情况被称为加密和解密;
    私钥加密数据,公钥解密一般被称为签名和验证签名。

package com.cy;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import java.io.BufferedReader;
import java.io.FileReader;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
/*
1.使用openssl生成私钥和公钥
    openssl生成私钥命令: openssl genrsa -out rsa_private_key.pem 1024
    openssl生成公钥命令: openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
2.此时可以看到 rsa_private_key.pem 和 rsa_public_key.pem 两个文件。这时候的私钥是不能直接使用的,需要进行 pkcs8 编码
    openssl的pkcs8编码命令:openssl pkcs8 -topk8 -in rsa_private_key.pem -out pkcs8_rsa_private_key.pem -nocrypt
    此时可以看到 pkcs8_rsa_private_key.pem 文件。
    至此,可用的密钥对已经生成好了,私钥使用pkcs8_rsa_private_key.pem,公钥采用rsa_public_key.pem。
3.使用密钥对进行签名、加解密
    公钥加密数据,然后私钥解密的情况被称为加密和解密;
    私钥加密数据,公钥解密一般被称为签名和验证签名。
 */


public class RSAPemCoder {
    public static final String PRIVATE_KEY_PEM = "F:/pkcs8_rsa_private_key.pem";
    public static final String PUBLIC_KEY_PEM = "F:/rsa_public_key.pem";

    public static final String KEY_SHA = "SHA";
    public static final String KEY_MD5 = "MD5";
    public static final String KEY_ALGORITHM = "RSA";
    public static final String SIGNATURE_ALGORITHM = "MD5withRSA";


    public static void main(String[] args) throws Exception {
        PrivateKey privateKey = getPrivateKeyFromPem();
        PublicKey publicKey = getPublicKeyFromPem();
        String data = "测试123";

        /*************************************************************************************************/
        //私钥加密
        byte[] privateDataBytes = encryptByPrivateKey(data.getBytes(StandardCharsets.UTF_8), privateKey);
        String privateDataBase64 = encryptBASE64(privateDataBytes);
        System.out.println(privateDataBase64);
        //公钥解密
        privateDataBytes = decryptBASE64(privateDataBase64);
        byte[] dataBytes = decryptByPublicKey(privateDataBytes, publicKey);
        System.out.println(new String(dataBytes, StandardCharsets.UTF_8));
        /*************************************************************************************************/

        /*************************************************************************************************/
        //公钥加密
        byte[] publicDataBytes = encryptByPublicKey(data.getBytes(StandardCharsets.UTF_8), publicKey);
        String publicDataBase64 = encryptBASE64(publicDataBytes);
        System.out.println(publicDataBase64);
        //私钥解密
        publicDataBytes = decryptBASE64(publicDataBase64);
        dataBytes = decryptByPrivateKey(publicDataBytes, privateKey);
        System.out.println(new String(dataBytes, StandardCharsets.UTF_8));
        /*************************************************************************************************/

        /*************************************************************************************************/
        //签名:私钥加密
        String sign = sign(data.getBytes(StandardCharsets.UTF_8), privateKey);
        System.out.println(sign);
        //验证签名:公钥解密
        boolean verify = verify(data.getBytes(StandardCharsets.UTF_8), publicKey, sign);
        System.out.println(verify);
        /*************************************************************************************************/
    }

    /**
     * 用私钥对信息生成数字签名
     * @param data       加密数据
     * @param privateKey 私钥
     * @return
     * @throws Exception
     */
    public static String sign(byte[] data, PrivateKey privateKey) throws Exception {
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initSign(privateKey);
        signature.update(data);
        return encryptBASE64(signature.sign());
    }

    /**
     * 校验数字签名
     * @param data      加密数据
     * @param publicKey 公钥
     * @param sign      数字签名
     * @return 校验成功返回true 失败返回false
     * @throws Exception
     */
    public static boolean verify(byte[] data, PublicKey publicKey, String sign) throws Exception {
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initVerify(publicKey);
        signature.update(data);
        return signature.verify(decryptBASE64(sign));
    }

    /**
     * 私钥解密
     * @param data       密文
     * @param privateKey 私钥
     * @return
     * @throws Exception
     */
    public static byte[] decryptByPrivateKey(byte[] data, PrivateKey privateKey) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        return cipher.doFinal(data);
    }

    /**
     * 用公钥解密
     * @param data      密文
     * @param publicKey 公钥
     * @return
     * @throws Exception
     */
    public static byte[] decryptByPublicKey(byte[] data, PublicKey publicKey) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, publicKey);
        return cipher.doFinal(data);
    }

    /**
     * 用公钥加密
     * @param data      明文
     * @param publicKey 公钥
     * @return
     * @throws Exception
     */
    public static byte[] encryptByPublicKey(byte[] data, PublicKey publicKey) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return cipher.doFinal(data);
    }

    /**
     * 用私钥加密
     * @param data       明文
     * @param privateKey 私钥
     * @return
     * @throws Exception
     */
    public static byte[] encryptByPrivateKey(byte[] data, PrivateKey privateKey) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
        return cipher.doFinal(data);
    }

    // 获取私匙
    public static PrivateKey getPrivateKeyFromPem() throws Exception {
        BufferedReader br = new BufferedReader(new FileReader(PRIVATE_KEY_PEM));
        String s = br.readLine();
        String str = "";
        s = br.readLine();
        while (s.charAt(0) != '-') {
            str += s + "\r";
            s = br.readLine();
        }
        BASE64Decoder base64decoder = new BASE64Decoder();
        byte[] b = base64decoder.decodeBuffer(str);

        // 生成私匙
        KeyFactory kf = KeyFactory.getInstance("RSA");
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(b);
        PrivateKey privateKey = kf.generatePrivate(keySpec);
        return privateKey;
    }

    // 获取公钥
    public static PublicKey getPublicKeyFromPem() throws Exception {
        BufferedReader br = new BufferedReader(new FileReader(PUBLIC_KEY_PEM));
        String s = br.readLine();
        String str = "";
        s = br.readLine();
        while (s.charAt(0) != '-') {
            str += s + "\r";
            s = br.readLine();
        }
        BASE64Decoder base64decoder = new BASE64Decoder();
        byte[] b = base64decoder.decodeBuffer(str);
        KeyFactory kf = KeyFactory.getInstance("RSA");
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(b);
        PublicKey pubKey = kf.generatePublic(keySpec);
        return pubKey;
    }

    public static byte[] decryptBASE64(String key) throws Exception {
        return (new BASE64Decoder()).decodeBuffer(key);
    }

    public static String encryptBASE64(byte[] key) throws Exception {
        return (new BASE64Encoder()).encodeBuffer(key);
    }

    public static byte[] encryptMD5(byte[] data) throws Exception {
        MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);
        md5.update(data);
        return md5.digest();
    }

    public static byte[] encryptSHA(byte[] data) throws Exception {
        MessageDigest sha = MessageDigest.getInstance(KEY_SHA);
        sha.update(data);
        return sha.digest();
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值