当前位置:   article > 正文

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

java 生成签名 加密解密

前言

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

一、非对称加密算法简介

非对称加密算法又称现代加密算法,是计算机通信安全的基石,保证了加密数据不会被破解。与对称加密算法不同,非对称加密算法需要两个密钥:公开密钥(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();
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

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);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

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));
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

三、RSA 签名验签代码实例

1.生成 RSA 密钥

代码如下:

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

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));
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

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);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/601128
推荐阅读
相关标签
  

闽ICP备14008679号