Java 实现 RSA 非对称加密算法加解密和签名验签

前言

文章字数比较多,可直接查看代码:源码地址,文中描述有误的地方欢迎各位大神指导。

一、非对称加密算法简介

非对称加密算法又称现代加密算法,是计算机通信安全的基石,保证了加密数据不会被破解。与对称加密算法不同,非对称加密算法需要两个密钥:公开密钥(publickey)和私有密(privatekey),因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。公钥和私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密。常见算法:RSA、ECC。

加解密和签名验签区别:

既然是加密,那肯定是不希望别人知道我的消息,所以只有我才能解密,所以可得出公钥负责加密,私钥负责解密;同理既然是签名,那肯定是不希望有人冒充我发消息,只有我才能发布这个签名,所以可得出私钥负责签名,公钥负责验证。

注意: 公钥加密、私钥解密,私钥签名、公钥验签。

二、RSA 加解密代码实例

1.生成 RSA 密钥

代码如下:

    public static KeyPair generateKeyPair(int keySize) throws NoSuchAlgorithmException {
        // 获取指定算法的密钥对生成器(RSA)
        final KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
        // 初始化密钥对生成器(指定密钥长度, 使用默认的安全随机数源)
        generator.initialize(keySize);
        // 随机生成一对密钥(包含公钥和私钥)
        return generator.generateKeyPair();
    }

2.RSA 加解密

代码如下:

    /**
     * RSA 加密
     *
     * @param publicKeyBytes 公钥
     * @param plain 原文
     * @return 密文
     */
    public static byte[] encrypt(byte[] publicKeyBytes, byte[] plain) throws Exception {
        // RSA
        final KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        final X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(publicKeyBytes);
        final PublicKey publicKey = keyFactory.generatePublic(pubX509);
        final Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return cipher.doFinal(plain);
    }

    /**
     * RSA 解密
     *
     * @param privateKeyBytes  私钥
     * @param encrypted  密文
     * @return byte[] 原文
     */
    public static byte[] decrypt(byte[] privateKeyBytes, byte[] encrypted) throws Exception {
        // RSA
        final KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        final PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
        final PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
        final Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        return cipher.doFinal(encrypted);
    }

3.测试代码

代码如下:

    public static void main(String[] args) throws Exception {
        final String data = "test";
        final KeyPair keyPair = generateKeyPair(2048);

        final byte[] encrypt = encrypt(keyPair.getPublic().getEncoded(), data.getBytes());
        final byte[] decrypt = decrypt(keyPair.getPrivate().getEncoded(), encrypt);
        System.out.println(new String(decrypt));
    }

三、RSA 签名验签代码实例

1.生成 RSA 密钥

代码如下:

    public static KeyPair generateKeyPair(int keySize) throws NoSuchAlgorithmException {
        // 获取指定算法的密钥对生成器(RSA)
        final KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
        // 初始化密钥对生成器(指定密钥长度, 使用默认的安全随机数源)
        generator.initialize(keySize);
        // 随机生成一对密钥(包含公钥和私钥)
        return generator.generateKeyPair();
    }

2.RSA 签名验签

代码如下:

    /**
     * signature.
     *
     * @param privateKeyBytes 私钥
     * @param plain 明文
     * @return String 签名
     */
    public static String signature(byte[] privateKeyBytes, String plain) throws Exception {
        final KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        final PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
        final PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
        final Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initSign(privateKey);
        signature.update(plain.getBytes(StandardCharsets.UTF_8));
        final byte[] signed = signature.sign();
        return Base64.encodeBase64URLSafeString(signed);
    }

    /**
     * verify.
     *
     * @param publicKeyBytes 公钥
     * @param plain 原文
     * @param sign 签名
     * @return boolean
     */
    public static boolean verify(byte[] publicKeyBytes, String plain, String sign)
        throws Exception {
        final KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        final X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(publicKeyBytes);
        final PublicKey publicKey = keyFactory.generatePublic(pubX509);
        final Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initVerify(publicKey);
        signature.update(plain.getBytes(StandardCharsets.UTF_8));
        return signature.verify(Base64.decodeBase64URLSafe(sign));
    }

3.测试代码

代码如下:

    public static void main(String[] args) throws Exception {
        final String data = "test";
        final KeyPair keyPair = generateKeyPair(2048);

        final String sign = signature(keyPair.getPrivate().getEncoded(), data);
        final boolean verify = verify(keyPair.getPublic().getEncoded(), data, sign);
        System.err.println(verify);
    }
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值