RSA加密算法之JAVA实现

本文介绍了一次与大型银行系统对接过程中对RSA加密算法的研究经历。通过整合两篇优快云上的文章,实现了RSA密钥生成、公钥加密及私钥解密的功能,并提供了完整的Java代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

欢迎大家来我的博客:http://www.qnloft.com 交流学习还可以观看视频教程

切入正题,今天需要和某国有(大型)银行系统对接,对方使用RSA对敏感数据进行加密返回,不得已,我要研究一下RSA加密算法了,本着探索(懒)精神,由于Google还没回归,所以先百度瞅瞅。一搜一大片文章,使用排除法,先排除互相抄袭的,年代久远的等等…最后找到这么两篇

不得不夸一下我大优快云没少给百度送钱吧~!O(∩_∩)O哈哈~

将两篇文章代码取长补短,整合了一下,发现还是不行。不禁仰天长叹,好坑啊……….

填坑之旅

RSA算法分为生成私钥和公钥,可以选择:

  • 私匙加密,必须公钥解密。
  • 公钥加密,必须私匙解密。

生成私钥和公钥代码如下:


KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
keyPairGen.initialize(1024);
KeyPair keyPair = keyPairGen.generateKeyPair();
// 私匙
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
// 公匙
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();

现在我使用生成的公匙加密,私匙解密,代码如下:

/**
 * 公匙加密
 * @param privateKey
 * @param obj
 * @return
 */
protected byte[] encrypt(RSAPublicKey privateKey, byte[] obj) {
    if (privateKey != null) {
        try {
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, privateKey);
            return cipher.doFinal(obj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    return null;
}

/**
 * 私匙解密
 * @param privateKey
 * @param obj
 * @return
 */
protected byte[] decrypt(RSAPrivateKey privateKey, byte[] obj) {
    if (privateKey != null) {
        try {
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            return cipher.doFinal(obj);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    return null;
}

加密后的密文,需要再经过base64一下才传播。

现在贴出完整的代码:

import javax.crypto.Cipher;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;

/**
 * @author : R&M www.qnloft.com/blog
 *         2018/8/14 11:08
 *         
 */
public class RSATest {
    public static void main(String[] args) {
        try {
            RSATest encrypt = new RSATest();

            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
            keyPairGen.initialize(1024);
            KeyPair keyPair = keyPairGen.generateKeyPair();
//            RSAPrivateKey privateKey = (RSAPrivateKey) getPrivateKey(ConstantForEnterprise.PSBC_SECRET_KEY);
            // 私匙
            RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
            // 公匙
            RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();

            String str = "123456789012345678!测试";
            System.out.println("需要加密的内容是: " + str);
            byte[] e = encrypt.encrypt(publicKey, str.getBytes());
            String publicValue = encodeBase64(e);
            System.out.println("密文是:" + publicValue);

            byte[] d = encrypt.decrypt(privateKey, decodeBase64(publicValue));
            System.out.println("解密后的结果是: " + new String(d));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 公匙加密
     * @param privateKey
     * @param obj
     * @return
     */
    protected byte[] encrypt(RSAPublicKey privateKey, byte[] obj) {
        if (privateKey != null) {
            try {
                Cipher cipher = Cipher.getInstance("RSA");
                cipher.init(Cipher.ENCRYPT_MODE, privateKey);
                return cipher.doFinal(obj);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 私匙解密
     * @param privateKey
     * @param obj
     * @return
     */
    protected byte[] decrypt(RSAPrivateKey privateKey, byte[] obj) {
        if (privateKey != null) {
            try {
                Cipher cipher = Cipher.getInstance("RSA");
                cipher.init(Cipher.DECRYPT_MODE, privateKey);
                return cipher.doFinal(obj);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * String类型的密匙转私匙
     * @param privateKey
     * @return
     * @throws Exception
     */
    private static PrivateKey getPrivateKey(String privateKey) throws Exception {
        byte[] keyBytes = Base64.getDecoder().decode(privateKey.getBytes());
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePrivate(keySpec);
    }
    private static String encodeBase64(byte[] binaryData) {
        return Base64.getEncoder().encodeToString(binaryData);
    }

    private static byte[] decodeBase64(String encoded){
        return Base64.getDecoder().decode(encoded);
    }
}

到这里就结束了,PrivateKeyPublicKey代表了密匙和公匙的对象,适当的修改就可以变成密匙加密,公匙解密了。

Base64.getDecoder().decode(encoded)

这里一定要使用java8的类,要不maven打包出错,我会再写一篇文章讲这个事情。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

qnloft

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值