Java实现RSA加解密(代码)

Java RSA加解密实践与代码示例
该博客详细介绍了如何在Java中使用RSA算法进行加解密操作,强调了Base64包的选择以及密钥长度的重要性。博主提供了在线生成密钥对的链接,并给出了PHP格式密钥转换为Java格式的方法,同时分享了分片加解密的封装代码。

本博客的代码经过自己慢慢调试,全部都成功运行

 特别注意的是:

  • Base64的包要这个,import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
  • key的长度是根据密钥的长度决定,private static final int KEY_SIZE = 1024;
  • 在线生成密钥对的网址:http://web.chacuo.net/netrsakeypair,可以自己生成密钥对来验证
  • php格式密钥转换为Java格式的密钥:public static String getCerToPublicKey() throws CertificateException

直接贴代码 

package wofang.common.utils;


import com.alibaba.fastjson.JSON;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import javax.crypto.Cipher;
import java.io.*;
import java.security.*;
import java.security.cert.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.*;

/**
 * @author 林高禄
 * @create 2020-05-15-15:09
 */
public class RsaUtils {

    /** *//**
     * 加密算法RSA
     */
    public static final String KEY_ALGORITHM = "RSA";

    /**
     * 填充方式
     */
    public static final String CIPHERALGORITHM = "RSA/ECB/PKCS1Padding";

    /**
     * 签名算法
     */
    public static final String SIGNATURE_ALGORITHM = "MD5withRSA";

    /**
     * 获取公钥的key
     */
    private static final String PUBLIC_KEY = "RSAPublicKey";

    /**
     * php公钥的key
     */
    public static final String PHP_PUBLIC_KEY = "-----BEGIN CERTIFICATE-----\n" +
            "MIICjTCCAfYCCQD0L/1fW/xYMjANBgkqhkiG9w0BAQsFADCBijELMAkGA1UEBhMC\n" +
            "Q04xDzANBgNVBAgMBkhhaU5hbjEPMA0GA1UEBwwGSGFpS291MQ8wDQYDVQQKDAZX\n" +
            "b0ZhbmcxDzANBgNVBAsMBldvRmFuZzEZMBcGA1UEAwwQd3hhcGkud29mYW5nLmNv\n" +
            "bTEcMBoGCSqGSIb3DQEJARYNd29mYW5nQHFxLmNvbTAeFw0xODA1MjIwNjQ2NTJa\n" +
            "Fw0yODA1MTkwNjQ2NTJaMIGKMQswCQYDVQQGEwJDTjEPMA0GA1UECAwGSGFpTmFu\n" +
            "MQ8wDQYDVQQHDAZIYWlLb3UxDzANBgNVBAoMBldvRmFuZzEPMA0GA1UECwwGV29G\n" +
            "YW5nMRkwFwYDVQQDDBB3eGFwaS53b2ZhbmcuY29tMRwwGgYJKoZIhvcNAQkBFg13\n" +
            "b2ZhbmdAcXEuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCo5zysftrH\n" +
            "mlfuZ3Fokzha1w+rmZc3MIgWL+3Z7URCasSr3TtSaaTYnl91VCfTF78rEhdZG7h6\n" +
            "8kgzovc5alMRmPBtEe9Enr9G+XPN6RCu6Y1nFRepIIscXghBpISj1Cofe6SUGgHY\n" +
            "5S9THNZsXSHxsvNLcPcOFEZtBKcSz9FXlwIDAQABMA0GCSqGSIb3DQEBCwUAA4GB\n" +
            "AHEIGEVJSQmLH3qPu4/8qHVYF3iB3sFDrnU+aYm0L0b/y0TeTjtztpAerMTK3LLA\n" +
            "RBVxjwSQzdIf9EDihYl/VrZSlxjkvoE2k1dRxNg1dBZLraZPle6cgEq+l2nh6FD9\n" +
            "Xzx8udLo2sr5wbGsldmyTZGcpjGSOOecGaGh6Xvh0CEC\n" +
            "-----END CERTIFICATE-----";

    /**
     * 获取私钥的key
     */
    private static final String PRIVATE_KEY = "RSAPrivateKey";

    /**
     * 长度
     */
    private static final int KEY_SIZE = 1024;

    /**
     * RSA最大加密明文大小
     */
    private static final int MAX_ENCRYPT_BLOCK = KEY_SIZE / 8 - 11;

    /**
     * RSA最大解密密文大小
     */
    private static final int MAX_DECRYPT_BLOCK = KEY_SIZE / 8;

    /**
     * 用于封装随机产生的公钥与私钥
     */
    private static Map<String, Key> keyMap = new HashMap<String, Key>();

    /**
     * 生成密钥对(公钥和私钥)
     * @throws          Exception       异常
     */
    public static void genKeyPair() throws Exception {
        // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
        // 初始化密钥对生成器
        keyPairGen.initialize(KEY_SIZE, new SecureRandom());
        // 生成一个密钥对,保存在keyPair中
        KeyPair keyPair = keyPairGen.generateKeyPair();
        // 得到私钥
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        // 得到公钥
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        keyMap.put(PUBLIC_KEY, publicKey);
        keyMap.put(PRIVATE_KEY, privateKey);
    }

    /**
     * 密钥转换,去除其他格式,换行符等
     * @param privateKey    私钥
     * @return              String
     */
    public static String keyTransformation(String privateKey,String begin,String end){
        return privateKey.replace(begin, "")
                 .replace(end, "")
                .replace("\r\n", "")
                .replace("\r", "")
                .replace("\n", "") ;
    }


    /**
     * 获取私钥
     * @return String
     */
    public static String getPrivateKey(){
        Key key = keyMap.get(PRIVATE_KEY);
        return Base64.encode(key.getEncoded());
    }

    /**
     * 获取公钥
     * @return  String
     */
    public static String getPublicKey(){
        Key key = keyMap.get(PUBLIC_KEY);
        return Base64.encode(key.getEncoded());
    }

    /**
     * php格式密钥转换为Java格式的密钥
     * BEGIN CERTIFICATE格式解析密钥
     * @Return: java.security.PublicKey
     */
    public static String getCerToPublicKey() throws CertificateException {
        //FileInputStream file = new FileInputStream("D://publicKey.cer");
        String phpPublicKey = keyTransformation(RsaUtils.PHP_PUBLIC_KEY,"-----BEGIN CERTIFICATE-----","-----END CERTIFICATE-----");
        byte[] phpKeyBytes = Base64.decode(phpPublicKey);
        CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
        InputStream in = new ByteArrayInputStream(phpKeyBytes);
        X509Certificate certificate = (X509Certificate)certFactory.generateCertificate(in);
        PublicKey publicKey = certificate.getPublicKey();
       /* CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
        X509Certificate certificate = (X509Certificate) certFactory.generateCertificate(file);
        PublicKey publicKey = certificate.getPublicKey();*/
        String strKey = "-----BEGIN PUBLIC KEY-----\n"
                + Base64.encode(publicKey.getEncoded())
                + "\n-----END PUBLIC KEY-----";
        return strKey;
    }

    /**
     * 用私钥对信息生成数字签名
     * @param data              已加密数据
     * @param privateKey        私钥(BASE64编码)
     * @return                  String
     * @throws Exception       异常
     */
    public static String sign(byte[] data, String privateKey) throws Exception {
        privateKey = keyTransformation(privateKey,"-----BEGIN PRIVATE KEY-----","-----END PRIVATE KEY-----");
        byte[] keyBytes = Base64.decode(privateKey);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
        signature.initSign(privateK);
        signature.update(data);
        return Base64.encode(signature.sign());
    }

    /**
     * 校验数字签名
     * @param data                  已加密数据
     * @param publicKey             公钥(BASE64编码)
     * @param sign          
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林高禄

你打不打赏,我都会一直写博客

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值