• Java实现RSA加密和验证



    RSA(Rivest–Shamir–Adleman)是一种非对称加密算法,由Ron Rivest、Adi Shamir和Leonard Adleman于1977年提出,是目前广泛应用于加密和数字签名领域的一种加密算法。RSA的工作原理基于两个密钥:公钥和私钥,分别用于加密和解密数据,以及数字签名和验证。
    以下是RSA的主要特点和一些常见的使用场景:

    1. 非对称加密: RSA是一种非对称加密算法,意味着它使用不同的密钥进行加密和解密。公钥用于加密数据,只有拥有相应私钥的用户才能解密它。这种非对称性使得RSA在安全通信中非常有用,因为公钥可以公开分享,而私钥必须保密
    2. 数字签名和验证: RSA还可以用于数字签名和验证。发送方可以使用其私钥对消息进行签名,接收方可以使用发送方的公钥来验证签名。这确保了消息的完整性和来源认证。数字签名在网络安全、电子邮件认证和电子商务中广泛使用。
    3. 密钥交换: RSA可用于安全地交换对称密钥。在两个通信方之间建立安全连接时,可以使用RSA加密传输对称密钥,然后使用该对称密钥进行快速的数据加密和解密。这提高了性能并确保了密钥的安全交换。
    4. 安全通信: RSA可用于保护通信的机密性和完整性。通信双方可以使用对方的公钥来加密数据,以确保只有持有私钥的一方能够解密它。这在保护敏感信息传输时非常重要,例如,网上银行、电子商务和VPN连接。
    5. 数字证书RSA也与数字证书一起使用,以验证网站的身份和安全性。数字证书中包含了网站的公钥,通过验证证书的签名,用户可以确保他们正在与合法的网站通信,而不是受到中间人攻击。
    6. 安全存储 RSA可以用于加密敏感数据,然后将其存储在不安全的环境中,只有持有私钥的用户才能解密和访问数据。这对于存储密码、加密钱包和数据库等敏感数据非常有用。

    总的来说,RSA是一种强大且多用途的加密算法,广泛应用于网络通信、数据安全、数字签名、身份验证和加密存储等领域。然而,需要注意的是,RSA的性能较低,特别是对于长消息,因此在某些情况下,可能需要与对称加密算法结合使用,以提高性能。

    本文主要讲述如何通过Java实现RSA加密与验证,应用场景为与其他平台对接接口时,通过RSA加密和解密验证请求的有效性,在对接时双方互换公钥

    生成公私钥

    要实现加密和验证,首先你需要生成一对RSA密钥对,包括公钥和私钥。你可以使用Java的KeyPairGenerator类来生成密钥对。实现代码如下:

    package com.zjq.dailyrecord.security;
    
    import java.security.KeyPair;
    import java.security.KeyPairGenerator;
    import java.security.PrivateKey;
    import java.security.PublicKey;
    import java.util.Base64;
    
    /**
     * RSA公私钥生成
     * @author 共饮一杯无
     */
    public class GenerateRSAKeys {
        public static void main(String[] args) throws Exception {
            // 创建一个RSA密钥对生成器
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            // 设置密钥长度,通常为2048位
            keyPairGenerator.initialize(2048);
    
            // 生成RSA密钥对
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            PublicKey publicKey = keyPair.getPublic();
            PrivateKey privateKey = keyPair.getPrivate();
    
            System.out.println("公钥: " + Base64.getEncoder().encodeToString(publicKey.getEncoded()));
            System.out.println("私钥: " + Base64.getEncoder().encodeToString(privateKey.getEncoded()));
        }
    }
    
    
    • 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

    基础的公钥加密私钥解密

    具体代码实现如下:

    package com.zjq.dailyrecord.security;
    
    import java.security.KeyFactory;
    import java.security.PrivateKey;
    import java.security.PublicKey;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    import java.util.Base64;
    import javax.crypto.Cipher;
    
    /**
     * RSA加密和解密
     * @author 共饮一杯无
     */
    public class RSAEncryptionDecryption {
        public static void main(String[] args) throws Exception {
            String originalText = "Hello, RSA encryption and decryption!";
            
            // 将公钥和私钥的Base64编码字符串转换为PublicKey和PrivateKey对象
            String publicKeyBase64 = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhRJqXuMDyyc4b3+LrsZqwh+sZtV3n2pwjkWZ+SIkfW3GlrVPEQmGDbCB2xJ3coSc/IQ5ukkdh1ArTzf69kmn3zNZT34ZJgYjLNnvi9I2dBRZkARV2ERFhPYZsUt8WecSGt29SK22NsctMkSroRmsLRMUArmZ2r3knMrhy54PLvoeXwvDdpXC19EsioK5I7Huh29G+c3Bi8IWySR4/U2kpH+8CU2iZGiChwIZ6qqJgvaVbUuSdksHFnrVbl1LjqGKlb+Vos16UnluPlW4PGJMCfRYZcPqLSm728qT+jQFIUK17yAeznIvx5nccg6ke1GgnwhqeDicPuKnj4FKFm33/wIDAQAB";
            String privateKeyBase64 = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCFEmpe4wPLJzhvf4uuxmrCH6xm1XefanCORZn5IiR9bcaWtU8RCYYNsIHbEndyhJz8hDm6SR2HUCtPN/r2SaffM1lPfhkmBiMs2e+L0jZ0FFmQBFXYREWE9hmxS3xZ5xIa3b1IrbY2xy0yRKuhGawtExQCuZnaveScyuHLng8u+h5fC8N2lcLX0SyKgrkjse6Hb0b5zcGLwhbJJHj9TaSkf7wJTaJkaIKHAhnqqomC9pVtS5J2SwcWetVuXUuOoYqVv5WizXpSeW4+Vbg8YkwJ9Fhlw+otKbvbypP6NAUhQrXvIB7Oci/HmdxyDqR7UaCfCGp4OJw+4qePgUoWbff/AgMBAAECggEAWWJOSuAn6yy0DsjYlZQ3n59Q2V4n1M/VPOtpiluxsQKsswykSGhiQA3Am9timmyTWlaixAtap0plXPfYPdipxxYhtnCYCd9zfywAaKXR59THeCJBW1w4aiA4j8uJgoXgtmUdQJVWYKMXK73Onw60hS5ccZwjyTdmOR9Z3cCUqFNmX9EIAj9jUE9/nASNgnGNH5ULspaBUSH59B0D/2kNUexMrteShtlxKL73iFdptGu68NLk05GvghLG3o0HMJtOIyF+kj6x0BtPcD5xh7YxN6PTdrxnj4tmKsAesc38NBJphFFFmvxY5B9m9gKMOBQcGVW0By6AJLbE5Pj1w5GlMQKBgQDJ7+XQc3Q8VgXQZYpO2CA8Kygkls7GTsXwblB6u0aYT7uhht4Dwk2xCtkRWoUri6rVkcOKKY/SrU4GvVyK8E5AMHfOjTc1M6GQ6UOj760NUMqUwwzR45pUFKLtYq+gOlWqHz0Vu84DCQqU7nhJGqv5cMUoZRkTrqV6zPq/oWLa6QKBgQCosroKI3NfvkaTxYboNF8Bn6j1nzCrNW3VrtZvXXbeTWTxSgH01p45IcPPEfauQqHHzFSzrVP4HL9PNz8SYpwhS61i3PX5S2ftLRKsfOheYKWG7l5clu80SZfAcpXblp4QTZmHdp67dp2XMEFi/3VGDhZU/LCpLMvIUs/8MpmapwKBgBXALD3Gocd58Ihg14PkjZxNfbZrM/xyManTCAIgN9tiAzDDyRgYjqu6ImVXHa7yDUWRvMEd9urXVect8FDaz2LklZL+7OpjFEz6gxmeUEJ16Ewbsj7NSCs0SdRN4+LbRazcToUPxIHZMHWYNgaRw+JLPkE6mnffQN24RG3toSs5AoGBAIgoEI2kRTduXIpiL9t0gYXO9lCgVmio6+g+f+ZMemc78g/pWqDhI70a6m5TolTNhMO8wFRwvcgQc7wc6/QL0NXyvZOAoaq+2LeN3HeJLQcXXCIGe/ShAZmjGC8EjL052INyDktOSxkkyFbBZNThOCb9sbqQZIl2lVcut51mvaEbAoGBALwLpxIjj7N+dxkbScZCTWCgSPZ6t9y5rO9VkLtJ31aDAFqXljh4hphHhnsUq9z2pT3fo5mNRnaYutIixmzxQSQlzmjvnzFe+ZHFXMHm2l1fgOi5ByV9a/prUmyTuLuiwCf1/Q+E+qFPNnl5Actbamqk26zlMbZVTK6lrTM5PN+/";
            
            PublicKey publicKey = KeyFactory.getInstance("RSA")
                    .generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode(publicKeyBase64)));
            PrivateKey privateKey = KeyFactory.getInstance("RSA")
                    .generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKeyBase64)));
    
            // 使用公钥加密数据
            Cipher encryptCipher = Cipher.getInstance("RSA");
            encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] encryptedBytes = encryptCipher.doFinal(originalText.getBytes());
    
            // 使用私钥解密数据
            Cipher decryptCipher = Cipher.getInstance("RSA");
            decryptCipher.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] decryptedBytes = decryptCipher.doFinal(encryptedBytes);
    
            String decryptedText = new String(decryptedBytes);
            System.out.println("加密后的数据: " + Base64.getEncoder().encodeToString(encryptedBytes));
            System.out.println("解密后的数据: " + decryptedText);
        }
    }
    
    
    • 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
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    执行结果如下:
    image.png

    自定义密钥加密及校验

    通过对接双方各自生成对应的公私钥,然后交换公钥和jwt用户key的形式实现加密和验证。
    需要引入如下坐标依赖:

        <dependency>
          <groupId>com.auth0groupId>
          <artifactId>java-jwtartifactId>
          <version>3.8.3version>
        dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    具体代码实现如下:

    加密

        /**
         * 加密
         * @param dataJson
         * @param priKey
         * @param pubKey
         * @return
         */
        public static String encodeJwtToken(String dataJson, String priKey, String pubKey) {
            try {
                RSAPublicKey publicKey = defaultRSAPublicKey(pubKey);
                RSAPrivateKey privateKey = defaultRSAPrivateKey(priKey);
                //加密
                Algorithm algorithm = Algorithm.RSA256(publicKey, privateKey);
                String token = JWT.create()
                        .withIssuer(RSAKeyUtil.USER_KEY)
                        //.withExpiresAt(expiresAt)
                        .withClaim("data", dataJson)
                        .sign(algorithm);
                return token;
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    
    
        public static RSAPublicKey defaultRSAPublicKey(String pubKey) throws Exception {
            RSAPublicKey publicKey = getRSAPublicKey(pubKey);
            return publicKey;
        }
    
        public static RSAPrivateKey defaultRSAPrivateKey(String priKey) throws Exception {
            RSAPrivateKey privateKey = getRSAPrivateKey(priKey);
            return privateKey;
        }
    
        public static RSAPublicKey getRSAPublicKey(String publicKey) throws Exception {
            byte[] publicBytes = decryptBASE64(publicKey);
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            RSAPublicKey pubKey = (RSAPublicKey) keyFactory.generatePublic(keySpec);
            return pubKey;
        }
    
        public static RSAPrivateKey getRSAPrivateKey(String privateKey) throws Exception {
            byte[] clear = decryptBASE64(privateKey);
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(clear);
            KeyFactory fact = KeyFactory.getInstance("RSA");
            RSAPrivateKey priKey = (RSAPrivateKey) fact.generatePrivate(keySpec);
            Arrays.fill(clear, (byte) 0);
            return priKey;
        }
    
        /**
         * 解码返回byte
         * @param key
         * @return
         * @throws Exception
         */
        public static byte[] decryptBASE64(String key) throws Exception {
            return (new BASE64Decoder()).decodeBuffer(key);
        }
    
    • 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
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    校验

        /**
         * 验签校验
         * @param jwtToken
         * @param priKey
         * @param pubKey
         * @return
         * @throws Exception
         */
        public static Boolean verify(String jwtToken, String priKey, String pubKey) throws Exception {
            RSAPublicKey publicKey = RSAKeyUtil.defaultRSAPublicKey(pubKey);
            RSAPrivateKey privateKey = RSAKeyUtil.defaultRSAPrivateKey(priKey);
            //加密
            Algorithm algorithm = Algorithm.RSA256(publicKey, privateKey);
            //解密
            JWTVerifier verifier = JWT.require(algorithm)
                    .withIssuer(RSAKeyUtil.USER_KEY)
                    .build();
            DecodedJWT jwt = null;
            try{
                jwt = verifier.verify(jwtToken);
            }catch (Exception e){
                e.printStackTrace();
                return false;
            }
            return !StringUtils.isEmpty(jwt);
        }
    
    • 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

    测试验证

    测试验证代码如下:

    package com.zjq.dailyrecord.security;
    
    import com.auth0.jwt.JWT;
    import com.auth0.jwt.algorithms.Algorithm;
    import com.auth0.jwt.interfaces.Claim;
    import com.auth0.jwt.interfaces.DecodedJWT;
    import com.auth0.jwt.interfaces.JWTVerifier;
    import org.springframework.util.StringUtils;
    import sun.misc.BASE64Decoder;
    import java.security.KeyFactory;
    import java.security.interfaces.RSAPrivateKey;
    import java.security.interfaces.RSAPublicKey;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    import java.util.Arrays;
    
    
    /**
     * 商户公司验签加解密工具类
     * @author 共饮一杯无
     */
    public class RSAKeyUtil {
        public final static String USER_KEY = "gongyinyibeiwu";
    
        /**
         * 验签校验
         * @param jwtToken
         * @param priKey
         * @param pubKey
         * @return
         * @throws Exception
         */
        public static Boolean verify(String jwtToken, String priKey, String pubKey) throws Exception {
            RSAPublicKey publicKey = RSAKeyUtil.defaultRSAPublicKey(pubKey);
            RSAPrivateKey privateKey = RSAKeyUtil.defaultRSAPrivateKey(priKey);
            //加密
            Algorithm algorithm = Algorithm.RSA256(publicKey, privateKey);
            //解密
            JWTVerifier verifier = JWT.require(algorithm)
                    .withIssuer(RSAKeyUtil.USER_KEY)
                    .build();
            DecodedJWT jwt = null;
            try{
                jwt = verifier.verify(jwtToken);
                Claim subjectClaim  = verifier.verify(jwtToken).getClaim("data");
                String result = subjectClaim.asString();
                System.out.println("解密结果:"+result);
            }catch (Exception e){
                e.printStackTrace();
                return false;
            }
            return !StringUtils.isEmpty(jwt);
        }
    
        /**
         * 加密
         * @param dataJson
         * @param priKey
         * @param pubKey
         * @return
         */
        public static String encodeJwtToken(String dataJson, String priKey, String pubKey) {
            try {
                RSAPublicKey publicKey = defaultRSAPublicKey(pubKey);
                RSAPrivateKey privateKey = defaultRSAPrivateKey(priKey);
                //加密
                Algorithm algorithm = Algorithm.RSA256(publicKey, privateKey);
                String token = JWT.create()
                        .withIssuer(RSAKeyUtil.USER_KEY)
                        //.withExpiresAt(expiresAt)
                        .withClaim("data", dataJson)
                        .sign(algorithm);
                return token;
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    
    
        public static RSAPublicKey defaultRSAPublicKey(String pubKey) throws Exception {
            RSAPublicKey publicKey = getRSAPublicKey(pubKey);
            return publicKey;
        }
    
        public static RSAPrivateKey defaultRSAPrivateKey(String priKey) throws Exception {
            RSAPrivateKey privateKey = getRSAPrivateKey(priKey);
            return privateKey;
        }
    
        public static RSAPublicKey getRSAPublicKey(String publicKey) throws Exception {
            byte[] publicBytes = decryptBASE64(publicKey);
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            RSAPublicKey pubKey = (RSAPublicKey) keyFactory.generatePublic(keySpec);
            return pubKey;
        }
    
        public static RSAPrivateKey getRSAPrivateKey(String privateKey) throws Exception {
            byte[] clear = decryptBASE64(privateKey);
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(clear);
            KeyFactory fact = KeyFactory.getInstance("RSA");
            RSAPrivateKey priKey = (RSAPrivateKey) fact.generatePrivate(keySpec);
            Arrays.fill(clear, (byte) 0);
            return priKey;
        }
    
        /**
         * 解码返回byte
         * @param key
         * @return
         * @throws Exception
         */
        public static byte[] decryptBASE64(String key) throws Exception {
            return (new BASE64Decoder()).decodeBuffer(key);
        }
    
        public static void main(String[] args) {
    //        当前平台的公钥
            String ownPubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgBu0tGxKBDDUzEW498JYS5ibAtCTxXcw7fEALMek3D6mfbV9JOe10+Ukf9CSRYd4FEhjaq63Vy57mVs/Bmse9RQcv2AxyCBThwKJELA8kH2B8ulYkwlthEyz5/HJ49eLKljak9+b5Ya6uHTo3d5xIhXLc20IzW1O4QsxJVkmkTYS0jruFx3YrZdiiluawCYdmAUQ34JONS4cgsMrjwF8sRNsZ6Vu0trCttY94i2NYWJU1X0XCMWcYoTKLCenMa4XMoP+cgI1Q+6Ni4zZbCLMkwxo7rr+LBD6jpzrfi9/p15PdnzGFvOr+ZCQbKwemex+GuR86Xq/+ZozHK9YIjrcvQIDAQAB";
    //        当前平台的私钥
            String ownPriKey = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCAG7S0bEoEMNTMRbj3wlhLmJsC0JPFdzDt8QAsx6TcPqZ9tX0k57XT5SR/0JJFh3gUSGNqrrdXLnuZWz8Gax71FBy/YDHIIFOHAokQsDyQfYHy6ViTCW2ETLPn8cnj14sqWNqT35vlhrq4dOjd3nEiFctzbQjNbU7hCzElWSaRNhLSOu4XHditl2KKW5rAJh2YBRDfgk41LhyCwyuPAXyxE2xnpW7S2sK21j3iLY1hYlTVfRcIxZxihMosJ6cxrhcyg/5yAjVD7o2LjNlsIsyTDGjuuv4sEPqOnOt+L3+nXk92fMYW86v5kJBsrB6Z7H4a5Hzper/5mjMcr1giOty9AgMBAAECggEANjoEEr8n0YBOAy2cLxvPvigZrWZWtqZOStnRxiK38RZ/6QRStbVzLP94pLXHxLCkLom5s2XDa57caLzL/86GKx1ZUdTJHbo5QRPcqvi+mjbWM9l8Sbka536ERLD/UXdijAlSdHeZiN2v2fZ6v7ex0cjB9tj3eeVEF1RieDm1bo+IffHsiDKidfJ3/VaG5rlOzxQvxq22R9BBh5I8C1N3OnDX+A4R4lqy85OTH5+IQcJh4Z4lDP2gMHMqDJDoa6yxOB4UdL9gmfWDx2TBD9Y0XbaILDRGHG/gdPPtUb7ybhuZ3GaRO0JfH6k0oeGo+g7dAOTkyZlkPFa++jgXf/YYrQKBgQC/Ar3E54fZAzdQv0f9uBtEhtgT4Um0OcXZin6WUqBbcYwH1XnATPxPpQG0SNpRDWlKiBVSGH2d9OcE6Rxtal3IbXR/nTtGQumWSFJ8cYIaQGS22Bynb5e5H5XXfgXZ+0qlGgMW3WeqJv7f47g/W14w8rBf4zCbQ44JALd3+CraBwKBgQCrshV+86pjEQfWzuuGGNOaVt4GEyomheGGxWd1vncDm6TwFYixiWEnt/0ZKRXjN7gmljv07u17WZHANRKeHJJ5mYTfge/ZKrrY5LUorWA3lpzTbFEdOof+ea7FUujfZ0VcFmRtEb1yyOwtxTNyUSuwJn9OzmbhsGZngUGtIbuyGwKBgBy4TsxSe8yXfTO47xwpGIB/PfIPR8O/hA4nks0Lc20Mb5+l636MlMts5gqzgY/6UkCQoZQMdqbPcgT8//c7rQo72u5tN8JiwTiFe1GWx5cm433SlMxgLRH6u88A9eRGsnyMorZHaBTfdCc52DQ+irUVaIuiX2aZC7wyzWNOfzL1AoGADEbJfrBRiI/ZLaTR9l6kEq8PZQPNyb9c5tQKl8Kso9dnLbt8cKVQCxT+xePIKtz7D9dCJjtHQ8CdyU6CLEgCuSse8xRJYA/MGGISCfyLmq3sPLnL+vkKbEmrE3TgLckmjnUTbTENiL2RFZy6Fvxy0T+PbsUXWh/Q0qnNVmHJF+0CgYBstz+ESSvKJhSCNpWccnsCNyza9gy1KrgHFQn8RbJ/ss4s21iXEBZYEex2sjwFUZmH2xUxeV45x2zOyCrxJrHqgaA+0og8CmD5mqLDpliiBOpIQr2Du7DLMUAQDZ4oJvkul/ADQ3HJcCcMqQs7xLI0PzIKHjhh/IeWtxbQDDp72g==";
    
    //        对接平台公钥
            String otherPubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4A6SXgt/nNh76Hn85pZxvh2mRv2y4VWfrwM8lFv7urzJ3xt5FocujjEoQT3Q5jeByxiZaOmPk6mfpTTCsel5vGZqLtM8mrNKoPrXiKuq0U0sWUpXdlRLaFV+SMujTsuYl76get9kLVjwXRu4qlhtZlLlWcLpNu6wEu1JwY8Kl9BDP46X0J+IoL+f9iB0i8PAw71n6NJmGk4bvYAjwnMd9zMPdY+s9hfbv2OILdGkSAcaZGoan03HK8u5JBikMZOvhXHkNkgBtRX8ATqCbYK4fTAC70RdOwqbyOhcW/qie18KnfZJsINb7cPfN406wIK6rMapCx7RJ7eu7Ey0Hm8GGQIDAQAB";
    //        对接平台私钥
            String otherPriKey = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDgDpJeC3+c2HvoefzmlnG+HaZG/bLhVZ+vAzyUW/u6vMnfG3kWhy6OMShBPdDmN4HLGJlo6Y+TqZ+lNMKx6Xm8Zmou0zyas0qg+teIq6rRTSxZSld2VEtoVX5Iy6NOy5iXvqB632QtWPBdG7iqWG1mUuVZwuk27rAS7UnBjwqX0EM/jpfQn4igv5/2IHSLw8DDvWfo0mYaThu9gCPCcx33Mw91j6z2F9u/Y4gt0aRIBxpkahqfTccry7kkGKQxk6+FceQ2SAG1FfwBOoJtgrh9MALvRF07CpvI6Fxb+qJ7Xwqd9kmwg1vtw983jTrAgrqsxqkLHtEnt67sTLQebwYZAgMBAAECggEAHh23TM7M21854HitJq1oIn7Hv9kP9zvUF+kedm6aunHvzH5b20xWVKSE3agacSda2dq3nCNwug9dtw4NcW6Jf2pgsWSRS9X3nQW6fNNeRX3TDTlx4iTYcfCz5cMBc3DoVNU5qupmA7ZlsI4uVy9FnTBdRaBuSoTww8qDVHIOoXMLenXArosyQEytxEL1uBGF8xijBWC5CGQfLjegcqYiVJ7Bl5kGXGwo0q0dzTabx/P4sH1BBRWMkTEUgfBZs4QvFiTfCIB0/X44cIHpokBnaeYGKX7aVVDIRni1ot3gzYDgBnIGM9ZY/CjLn0mrnZciVr8SemTyobGf/GlPoID+xQKBgQD4HLuAQR1SqiNwuB+lDz0hYqFL/r3VvEa4Wety7lznppz9EWeDEnN89bk9+RXxq+cSg7EwGdI+LGNeZpShpCBrb/93VYN/kohywb6vgZJ3gjT50J+8mmvxm0cE61xZ+VGkAKn1QqO6voF17mOcHD4k/h1je0SVj7d40q2QbQwKWwKBgQDnLhCF9JZE23gPP2CCccQlA4QHR89i6YwQpFWyINIJA/p42cdVPErprQqsBDBoV5sk9GX9X08GBsU2tDDvOxCsQjPShe/pVSvdCg8aFnQzi5r8lEhGpirH16N9LHRx2dsFvoN/h+zqbuF4MRdmsPmUb6UFs3CnGfvraWo/OCATmwKBgAsS1TeDMHjZCR3lydvHE1ZjHYnTw8s/TPS7ZqvJgbIBGK6e0TzjXO4t1Wezr0wK/RQxdn4MGPsXZhP3hhi0x5Gj/QXpdiYCdz6P8R/KK6xTzmN78TUsuzacVI4epw+I9iDYur0sjTwvdn259w4noIpsIQmoncYDFRA6bu6sP0ZTAoGBAIra/Em5c1jAigh+hLVVJ/8jcXX+B+7dYKfOTTrEw+NuZE+aX0QvBr/8k+BmU70YgbNcqLXbPVfdUS9eY9YNoCIXUZEtqcB4y/PkStXcjsc3H0x+tDrbK+8E8soInZiUxh1ZJRrAxei52OuccPXZbs9dj70w3oU/8jSgCJUYXQvpAoGBAIv+AsEpjKnSCukCftO4XBdRFgyf4+XXbnqOqThHzUlSd02qk2aijjs9XFMtnoBobqOM/jDhh6uYSX5vWJtrarlgX7cvKD9xDroC54RmDnDfOl0CfN5DaffofsD8+z6MSQU1FN1PYigkqfDHCKCFRL4Hp90PvGuynejhAl8x1OfC";
    
            String jsonStr = "{\n" +
                    "    \"name\":\"共饮一杯无\"\n" +
                    "}";
    
    //        1.先加密
            String jwtToken = RSAKeyUtil.encodeJwtToken(jsonStr,ownPriKey,otherPubKey);
            System.out.println(jwtToken);
    
            try {
    //            2.解密
                Boolean verify =  RSAKeyUtil.verify("eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJkYXRhIjoie1xuICAgIFwibmFtZVwiOlwi5YWx6aWu5LiA5p2v5pegXCJcbn0iLCJpc3MiOiJnb25neWlueWliZWl3dSJ9.BGat7UWtc75ZyTMoySrtBOLyED9iNBOJOvw198_yg6ZbjCuitFIvl4p7qs9v2oo3BoAPWH8gKLQsLLhsUQ6p9thcCimB0ClTJkxQlxd_2I8J-fli2Jmc09I53mIptNOtfB_zDn5UuXyVtB5-aD_mUs9xLXkEb8DJbMl4__LHDQyr1v3ixh0rq_e5LaY0ZOfSq2l06MaSAssdKQRvN_H0snO0KJkodcPktfRr4hOXI_ZvcbZHgiuv6JUpbp6x7T9BWMvixD7TTd-lqqm2OsqGOCtWJ4URSJmjYdLDswHY89jNzfVHrQ6exuUIeranWJoRf2-smE8KpLAN8kxs1o1Rpg"
                        ,otherPriKey,ownPubKey);
                System.out.println(verify);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    
    }
    
    
    • 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
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149

    如果用户key不对会报如下错误:
    在这里插入图片描述
    如果公私钥不匹配会报如下错误:
    在这里插入图片描述
    两种结果都说明解密失败。
    正常执行返回结果:
    在这里插入图片描述

    使用RSA进行数字签名和验证

    实现逻辑为使用私钥对数据进行签名,然后使用公钥进行验证。具体代码实现如下:

    import java.security.KeyFactory;
    import java.security.PrivateKey;
    import java.security.PublicKey;
    import java.security.Signature;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    import java.util.Base64;
    
    /**
     * RSA数字签名实现
     * @author 共饮一杯无
     */
    public class RSASignatureVerification {
        public static void main(String[] args) throws Exception {
            String data = "待签署及核实的资料。";
    
            // 将公钥和私钥的Base64编码字符串转换为PublicKey和PrivateKey对象
            String publicKeyBase64 = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhRJqXuMDyyc4b3+LrsZqwh+sZtV3n2pwjkWZ+SIkfW3GlrVPEQmGDbCB2xJ3coSc/IQ5ukkdh1ArTzf69kmn3zNZT34ZJgYjLNnvi9I2dBRZkARV2ERFhPYZsUt8WecSGt29SK22NsctMkSroRmsLRMUArmZ2r3knMrhy54PLvoeXwvDdpXC19EsioK5I7Huh29G+c3Bi8IWySR4/U2kpH+8CU2iZGiChwIZ6qqJgvaVbUuSdksHFnrVbl1LjqGKlb+Vos16UnluPlW4PGJMCfRYZcPqLSm728qT+jQFIUK17yAeznIvx5nccg6ke1GgnwhqeDicPuKnj4FKFm33/wIDAQAB";
            String privateKeyBase64 = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCFEmpe4wPLJzhvf4uuxmrCH6xm1XefanCORZn5IiR9bcaWtU8RCYYNsIHbEndyhJz8hDm6SR2HUCtPN/r2SaffM1lPfhkmBiMs2e+L0jZ0FFmQBFXYREWE9hmxS3xZ5xIa3b1IrbY2xy0yRKuhGawtExQCuZnaveScyuHLng8u+h5fC8N2lcLX0SyKgrkjse6Hb0b5zcGLwhbJJHj9TaSkf7wJTaJkaIKHAhnqqomC9pVtS5J2SwcWetVuXUuOoYqVv5WizXpSeW4+Vbg8YkwJ9Fhlw+otKbvbypP6NAUhQrXvIB7Oci/HmdxyDqR7UaCfCGp4OJw+4qePgUoWbff/AgMBAAECggEAWWJOSuAn6yy0DsjYlZQ3n59Q2V4n1M/VPOtpiluxsQKsswykSGhiQA3Am9timmyTWlaixAtap0plXPfYPdipxxYhtnCYCd9zfywAaKXR59THeCJBW1w4aiA4j8uJgoXgtmUdQJVWYKMXK73Onw60hS5ccZwjyTdmOR9Z3cCUqFNmX9EIAj9jUE9/nASNgnGNH5ULspaBUSH59B0D/2kNUexMrteShtlxKL73iFdptGu68NLk05GvghLG3o0HMJtOIyF+kj6x0BtPcD5xh7YxN6PTdrxnj4tmKsAesc38NBJphFFFmvxY5B9m9gKMOBQcGVW0By6AJLbE5Pj1w5GlMQKBgQDJ7+XQc3Q8VgXQZYpO2CA8Kygkls7GTsXwblB6u0aYT7uhht4Dwk2xCtkRWoUri6rVkcOKKY/SrU4GvVyK8E5AMHfOjTc1M6GQ6UOj760NUMqUwwzR45pUFKLtYq+gOlWqHz0Vu84DCQqU7nhJGqv5cMUoZRkTrqV6zPq/oWLa6QKBgQCosroKI3NfvkaTxYboNF8Bn6j1nzCrNW3VrtZvXXbeTWTxSgH01p45IcPPEfauQqHHzFSzrVP4HL9PNz8SYpwhS61i3PX5S2ftLRKsfOheYKWG7l5clu80SZfAcpXblp4QTZmHdp67dp2XMEFi/3VGDhZU/LCpLMvIUs/8MpmapwKBgBXALD3Gocd58Ihg14PkjZxNfbZrM/xyManTCAIgN9tiAzDDyRgYjqu6ImVXHa7yDUWRvMEd9urXVect8FDaz2LklZL+7OpjFEz6gxmeUEJ16Ewbsj7NSCs0SdRN4+LbRazcToUPxIHZMHWYNgaRw+JLPkE6mnffQN24RG3toSs5AoGBAIgoEI2kRTduXIpiL9t0gYXO9lCgVmio6+g+f+ZMemc78g/pWqDhI70a6m5TolTNhMO8wFRwvcgQc7wc6/QL0NXyvZOAoaq+2LeN3HeJLQcXXCIGe/ShAZmjGC8EjL052INyDktOSxkkyFbBZNThOCb9sbqQZIl2lVcut51mvaEbAoGBALwLpxIjj7N+dxkbScZCTWCgSPZ6t9y5rO9VkLtJ31aDAFqXljh4hphHhnsUq9z2pT3fo5mNRnaYutIixmzxQSQlzmjvnzFe+ZHFXMHm2l1fgOi5ByV9a/prUmyTuLuiwCf1/Q+E+qFPNnl5Actbamqk26zlMbZVTK6lrTM5PN+/";
    
            PublicKey publicKey = KeyFactory.getInstance("RSA")
                    .generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode(publicKeyBase64)));
            PrivateKey privateKey = KeyFactory.getInstance("RSA")
                    .generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKeyBase64)));
    
            // 使用私钥进行数字签名
            Signature signature = Signature.getInstance("SHA256withRSA");
            signature.initSign(privateKey);
            signature.update(data.getBytes());
            byte[] signatureBytes = signature.sign();
    
            System.out.println("数字签名: " + Base64.getEncoder().encodeToString(signatureBytes));
    
            // 使用公钥进行验证
            signature.initVerify(publicKey);
            signature.update(data.getBytes());
            boolean verified = signature.verify(signatureBytes);
    
            if (verified) {
                System.out.println("数字签名验证成功!");
            } else {
                System.out.println("数字签名验证失败!");
            }
        }
    }
    
    • 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
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    结果输出如下:
    在这里插入图片描述

    本文内容到此结束了,
    如有收获欢迎点赞👍收藏💖关注✔️,您的鼓励是我最大的动力。
    如有错误❌疑问💬欢迎各位指出。
    主页共饮一杯无的博客汇总👨‍💻

    保持热爱,奔赴下一场山海。🏃🏃🏃

  • 相关阅读:
    springboot集成minio,docker部署
    Oracle之SQL plus的一些经验心得
    Git - Tag
    时间序列预测各类算法探究上篇
    新手一定要看的嵌入式学习方法
    web项目的搭建
    ACM模式下构建二叉树来实现各个核心代码 (java含注释)
    【最小的k个数】
    智慧路灯控制系统设计方案思路及设计原则
    东莞市交投集团供应链服务平台上线啦
  • 原文地址:https://blog.csdn.net/qq_35427589/article/details/133745697