Java 使用 RSA算法 进行前后端加密解密

使用RSA対前后端的消息进行加密和解密

前端

1. 安装依赖:pip install
2. ts文件中导入依赖:import forge from 'node-forge'
3. 选择加密方式
 例如指定:RSA/ECB/OAEPWithSHA-256AndMGF1Padding

 - **RSA**: 这表示使用 RSA 加密算法。
 - **ECB**: 这表示使用电子密码本 (Electronic Codebook) 模式进行加密。ECB 模式是一种基本的块加密模式,将明文分成固定大小的块,然后分别用密钥加密。
 - **OAEPWithSHA-256AndMGF1Padding**: 这表示使用 OAEP (Optimal Asymmetric Encryption Padding) 填充方案进行填充,并指定了哈希算法 SHA-256 和 MGF1 (Mask Generation Function 1) 作为填充方案的一部分。OAEP 是一种针对 RSA 加密算法设计的填充方案,旨在提供更好的安全性和随机性,以及防止对明文的长度或结构进行分析。

 综合起来,"RSA/ECB/OAEPWithSHA-256AndMGF1Padding" 表示使用 RSA 加密算法,采用 ECB 模式进行加密,并使用 OAEP 填充方案,其中哈希算法为 SHA-256,MGF1 作为填充方案的一部分。
4. 查看帮助文档:Forge的Github链接

在这里插入图片描述

 注释还贴心指定了Java参数是什么样子,你可一观察一下不同位置设置的对应关系推到一下你的参数设置;
5. 前端生成公钥和私钥测试一下
 ```ts
 export const $encryptMessage = (plaintext: any, publicKeyString: any) => {
     console.log("@5")
     // 生成一个 2048 位的 RSA 密钥对
     var keypair = forge.pki.rsa.generateKeyPair({ bits: 2048, e: 0x10001 });
 
     // 获取生成的公钥和私钥
     const publicKey = keypair.publicKey;
     const privateKey = keypair.privateKey;
   
     // 将待加密的字符串转换为字节数组
     var dataBytes = forge.util.encodeUtf8(plaintext);
 
     // 加密数据
     var encryptedBytes = publicKey.encrypt(dataBytes, 'RSA-OAEP', {
         md: forge.md.sha256.create(),
         mgf1: {
             md: forge.md.sha1.create()
         }
     });
 
     // 将加密后的字节数组转换为 Base64 编码的字符串
     var encryptedBase64 = forge.util.encode64(encryptedBytes);
     console.log("加密后数据", encryptedBase64);
 
     // 使用私钥解密数据
     var receivedEncryptedBytes = forge.util.decode64(encryptedBase64);
     var decryptedBytes = privateKey.decrypt(receivedEncryptedBytes, 'RSA-OAEP', {
         md: forge.md.sha256.create()
     });
 
     // 将解密后的字节数组转换为字符串
     var decryptedPlaintext = forge.util.decodeUtf8(decryptedBytes);
 
     console.log("Original plaintext:", plaintext);
     console.log("Decrypted plaintext:", decryptedPlaintext);
 ```
6. 实际生产环境中,肯定公钥是从后端获取的,私钥拿不到
 ------

 注意一下钥匙的格式为PEM格式:PEM 格式的数据通常以 `-----BEGIN` 开头,以 `-----END` 结尾,之间是经过 Base64 编码的数据。这种格式常用于存储和传输各种类型的密钥、证书等信息。

 ```vbnet
 公钥:
 -----BEGIN PUBLIC KEY-----
 MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjgRrqVP+D+CZCHr++8Bs
 e+mQ/Wjt0lW9zkp6bghQAfg3wR5XmYYOFWs/0lqWYgCYiwSX+iFQap6+dtkuE7jP
 HjU6d9I0hXXSoUIMaxo2WA3IfXI45n2tRHPInCTgCoPNpHtycfMaaboBQ99altqd
 TvOylEiEgdZZ4v8Elksi9F7suvx7cCy2yJFF5rK0PtVEUMYe31EFWuKDlMyUvXcn
 8aU/81v2Z+cxyIph9WL4kVFo8qV3R+eFilbm/gPFSl5YXra16aUxwWEFvZVsNoK9
 zHNA0K4XjzF1eGk99M28B65gM5FIdKQ6SF3CdKk9C1mYCAVX6WeOC1i+5XNGJRry
 nwIDAQAB
 -----END PUBLIC KEY-----
 私钥:
 -----BEGIN RSA PRIVATE KEY-----
 MIIEpAIBAAKCAQEA3F0fXoAC5elYAYU27JQ61iD/GKc+Km3LHV4J+7JNNfX7JzoY
 2fYgbVc+JJESmISs8O2z6LsjSQQ6VG2ukYcEZwIiq++HebZOHimIBLLaKry7NmQ3
 BJpJ8Y70jY2xqOQ29S+Z1Z+1HKnmUl44xJ5UG1C3ZoCYvh/PzPqC3Mfk2mT/rV2m
 UCj9g83eazw/e0ONi5DqcXyKq0EQW0rE4rZVHLuw4pNgRXwWLO5qSgN+4YhOfNpH
 ...此处省略私钥长一点....
 -----END RSA PRIVATE KEY-----
 ```

 --------

 如果你的公钥和私钥只有中间部分,就需要转换

 ```ts
 function convertToPublicPem(publicKeyBase64: string): string {
     const lines = [];
     lines.push('-----BEGIN PUBLIC KEY-----');
     for (let i = 0; i < publicKeyBase64.length; i += 64) {
         lines.push(publicKeyBase64.slice(i, i + 64));
     }
     lines.push('-----END PUBLIC KEY-----');
     return lines.join('\n');
 }
 function convertToPrivatePem(privateKeyBase64: string): string {
     const lines = [];
     lines.push('-----BEGIN PRIVATE KEY-----');
     for (let i = 0; i < privateKeyBase64.length; i += 64) {
         lines.push(privateKeyBase64.slice(i, i + 64));
     }
     lines.push('-----END PRIVATE KEY-----');
     return lines.join('\n');
 }
 ```
7. 那么我们通过测试一下前端加密和解密操作
 (通常加密在前端,解密在后端,为了你好定位问题,提供加密和解密,代码写错了是无法解密的)

 ```ts
 console.log("@5")
     // 生成一个 2048 位的 RSA 密钥对
     // var keypair = forge.pki.rsa.generateKeyPair({ bits: 2048, e: 0x10001 });
 
     // 获取生成的公钥和私钥
     // const publicKey = keypair.publicKey;
     // const privateKey = keypair.privateKey;
     // 从 PEM 格式的字符串加载公钥和私钥
     console.log("@4")
     var publicKeyString1 = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjgRrqVP+D+CZCHr++8Bse+mQ/Wjt0lW9zkp6bghQAfg3wR5XmYYOFWs/0lqWYgCYiwSX+iFQap6+dtkuE7jPHjU6d9I0hXXSoUIMaxo2WA3IfXI45n2tRHPInCTgCoPNpHtycfMaaboBQ99altqdTvOylEiEgdZZ4v8Elksi9F7suvx7cCy2yJFF5rK0PtVEUMYe31EFWuKDlMyUvXcn8aU/81v2Z+cxyIph9WL4kVFo8qV3R+eFilbm/gPFSl5YXra16aUxwWEFvZVsNoK9zHNA0K4XjzF1eGk99M28B65gM5FIdKQ6SF3CdKk9C1mYCAVX6WeOC1i+5XNGJRrynwIDAQAB";
     var privateKeyString ="MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCOBGupU/4P4JkIev77wGx76ZD9aO3SVb3OSnpuCFAB+DfBHleZhg4Vaz/SWpZiAJiLBJf6IVBqnr522S4TuM8eNTp30jSFddKhQgxrGjZYDch9cjjmfa1Ec8icJOAKg82ke3Jx8xppugFD31qW2p1O87KUSISB1lni/wSWSyL0Xuy6/HtwLLbIkUXmsrQ+1URQxh7fUQVa4oOUzJS9dyfxpT/zW/Zn5zHIimH1YviRUWjypXdH54WKVub+A8VKXlhetrXppTHBYQW9lWw2gr3Mc0DQrhePMXV4aT30zbwHrmAzkUh0pDpIXcJ0qT0LWZgIBVfpZ44LWL7lc0YlGvKfAgMBAAECggEADZIZkZwvlmfRZ9CNBhSMqUiX7Mc2lpdP5GMUkOglcRK9jSwvlcGMHfraJek3HpVM/lfJiALf8thJfgTh1MufqxTOCf4hu7EXGAa+NgvSrpZelrIwAsJ2qKhhvp39dLPEllefh4kB+KFoForE1s58IrvB0E6fruKDQ2A4GX6DkBNPlAykT7a8KrO1dqBJe8jtjf4CiOCR6Y6j0hq4tz12dZXO1FY5/gFcq7Oj5j4k1iXAPGkVLS7cZYUQhfsXfiP75q/y/hyUbYsVDW6xBWidfyc8cCNRo8fDnC8MDLa0H5TRAe+mWkYKX6M1ZSpo3E2LDTizVr7GaMBwgZ9yxmvA1QKBgQC2F1ymUQexGXecYBsHlesH0ulOlU90XptH0fMDXxR+Z7ae5gK4QAZePRZNofatOyyQGQ1+u21d9mOLv7Wm/HcTofVYODQTEBheFlbzpYZ5ciLUfuYXNmRgQlnZFkP/x3xA+lVhuCEyE87liQ+iH3FCFHh9X2mAoAim7hN8J5SpBQKBgQDHqRKVW4UXSN5sQYn0j8yGPUB5Q5BCrZCn38T+NWXNPnXBcTY80VhOZtWR41+9zdowDp7AzOZV6xWMn1hrt9xaMP+tcbB1iIcc6XTxcHDVzppt8HXIqqnpXxM041Sz1rEGW/lcNADZabJIWn2AE4XDiP2iX+IV3AU27dS5tKhuUwKBgCgX0MCWCtmFv/5gctMiwVNBrzksSwhWZF5V7eoKH1sNvvoRrvuerUhGrwh85vGRm+hGe+AxqI0N2TFGDtsrr5RVDs5T4bNo0dS1moOfKJLI/L5JCqSFx2gic+IGswY4iDVOaUpQ3o5GKkIEAbsyrR9dnoIMZhB6LC2FMikeFe95AoGBAMa5o8OBOjD42FmLyhHfZsReBuQruVSEiKxubxZOc6sbdf05/6/89hXjCMOSOmMilv6qLpzb1I7D08kJeOqOMAadKn6p3+a8Iy9Ftp3xOn20i8TNR46ZP1EGzokfk9kD4WLg/IsnP4kmSMr3Nl7aD5OVsE2DffYf7hjEE61bASH9AoGAFGDQg/ym2KwNqpt1xOVdpXpVTrkwKCqMiugcMEnFo3YaiODGH8wPqGjbkrbF+xlHZZK2tmcPpSzo2AidgSUAsgna6mYpSlLb9mfQTzMufMk7H27dUwjXKfhZdZkOnHaUy07ElokbjItGv8zedJBrzzz8hQdfy6id+vLJda0OFFI=";
     console.log("@3")
     const publicKey = forge.pki.publicKeyFromPem(convertToPublicPem(publicKeyString1));
     console.log("@2")
     const privateKey = forge.pki.privateKeyFromPem(convertToPrivatePem(privateKeyString));
     console.log("@1")
     // 将待加密的字符串转换为字节数组
     var dataBytes = forge.util.encodeUtf8(plaintext);
 
     // 加密数据
     var encryptedBytes = publicKey.encrypt(dataBytes, 'RSA-OAEP', {
         md: forge.md.sha256.create(),
         mgf1: {
             md: forge.md.sha1.create()
         }
     });
 
     // 将加密后的字节数组转换为 Base64 编码的字符串
     var encryptedBase64 = forge.util.encode64(encryptedBytes);
     console.log("加密后数据", encryptedBase64);
 
     // 使用私钥解密数据
     var receivedEncryptedBytes = forge.util.decode64(encryptedBase64);
     var decryptedBytes = privateKey.decrypt(receivedEncryptedBytes, 'RSA-OAEP', {
         md: forge.md.sha256.create()
     });
 
     // 将解密后的字节数组转换为字符串
     var decryptedPlaintext = forge.util.decodeUtf8(decryptedBytes);
 
     console.log("Original plaintext:", plaintext);
     console.log("Decrypted plaintext:", decryptedPlaintext);
 ```
8. 最后一步骤,删除不需要的代码:解密操作,公钥从后端获取
 ```
 //获取公钥
 export const $getPublicKey = async ()=>{
     const {data} = await $post(UserApi.getPublicKey,"");
     return data
 }
 function convertToPublicPem(publicKeyBase64: string): string {
     const lines = [];
     lines.push('-----BEGIN PUBLIC KEY-----');
     for (let i = 0; i < publicKeyBase64.length; i += 64) {
         lines.push(publicKeyBase64.slice(i, i + 64));
     }
     lines.push('-----END PUBLIC KEY-----');
     return lines.join('\n');
 }
 // 加密消息
 export const $encryptMessage = (plaintext: any, publicKeyString: any) => {
     const publicKey = forge.pki.publicKeyFromPem(convertToPublicPem(publicKeyString));
     // 将待加密的字符串转换为字节数组
     var dataBytes = forge.util.encodeUtf8(plaintext);
     // 加密数据
     var encryptedBytes = publicKey.encrypt(dataBytes, 'RSA-OAEP', {
         md: forge.md.sha256.create(),
         mgf1: {
             md: forge.md.sha1.create()
         }
     });
     // 将加密后的字节数组转换为 Base64 编码的字符串
     var encryptedBase64 = forge.util.encode64(encryptedBytes);
     console.log("加密后数据", encryptedBase64);
     return encryptedBase64;
 }
 
 
 export const $login = async (params:any)=>{
     try{
         const publicKey = await $getPublicKey()
         params.password = $encryptMessage(params.password, publicKey)
         xxxx发送请求xxxx
 	}catch (error) {
         console.error('登录时发生错误:', error);
         throw error; // 将错误继续向外抛出
     }
 }
 ```

后端

1. 生成公钥和私钥
if (publicKey == null && privateKey == null) {
            try {
                KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
                keyGen.initialize(2048);
                KeyPair pair = keyGen.generateKeyPair();
                // 保存公钥和私钥
                publicKey = pair.getPublic();
                privateKey = pair.getPrivate();
                // 输出公钥和私钥的Base64编码值
                log.info("RSA密钥生成成功: 公钥={}, 私钥={}", 		
                         Base64.getEncoder().encodeToString(publicKey.getEncoded()), 
                         Base64.getEncoder().encodeToString(privateKey.getEncoded()));
            } catch (Exception e) {
                log.error("初始化RSA密钥失败:", e.getMessage());
            }
 }
2. 利用公钥加密(虽然这是在前端做的)
 	 /**
     * 利用公钥进行加密
     */
    public String crypto(String encodeString) throws Exception {
        // 将传入的待加密字符串转换为字节数组
        byte[] data = encodeString.getBytes();
        // 使用公钥加密
        byte[] encryptedBytes = encrypt(data, this.publicKey);
        // 返回加密后的Base64编码字符串
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }

    /**
     * 加密操作
     */
    private byte[] encrypt(byte[] data, PublicKey publicKey) throws Exception {
        // 获取RSA算法的Cipher实例
        Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
        // 用公钥初始化Cipher实例,设置为加密模式
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        // 执行加密操作,返回加密后的字节数组
        return cipher.doFinal(data);
    }
3. 利用私钥进行解密
   /**
     * 利用私钥进行解密
     */
    public String declass(String decodeString) throws Exception {
        // 将传入的Base64编码字符串解码为字节数组
        byte[] encryptedBytes = Base64.getDecoder().decode(decodeString);
        // 使用私钥解密
        byte[] decryptedBytes = decrypt(encryptedBytes, this.privateKey);
        // 返回解密后的字符串
        return new String(decryptedBytes);
    }


    /**
     * 解密操作
     */
    private byte[] decrypt (byte[] data, PrivateKey privateKey) throws Exception {
        // 获取RSA算法的Cipher实例
        Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
        // 用私钥初始化Cipher实例,设置为解密模式
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        // 执行解密操作,返回解密后的字节数组
        return cipher.doFinal(data);
    }
4. 下面过程是完整的过程:SpringBoot项目中
  • 定义接口

    package com.happy_retail_management.modules.security;
    public interface RSAUserSecurity {
        /**
         * 解密
         */
        public String declass(String decodeString) throws Exception;
        /**
         * 加密
         */
        public String crypto(String encodeString) throws Exception;
        public String getPrivateKeyString();
        public String getPublicKeyString();
        public void initRSASecurity();
    }
    
  • 实现类

    构造方法支持你指定特定的私钥和公钥,项目运行一般通过无参构造方法+init方法

    package com.happy_retail_management.modules.security;
    
    import lombok.extern.slf4j.Slf4j;
    
    import javax.crypto.Cipher;
    import java.security.*;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    import java.util.Base64;
    
    @Slf4j
    public class RSAUserSecurityImpl implements RSAUserSecurity {
        private PrivateKey privateKey = null;
        private PublicKey publicKey = null;
    
        public RSAUserSecurityImpl() {
            // 在构造函数中初始化密钥对
    //        initRSASecurity();
        }
        public RSAUserSecurityImpl(PrivateKey privateKey,PublicKey publicKey){
            this.privateKey=privateKey;
            this.publicKey=publicKey;
        }
        public RSAUserSecurityImpl(String privateKeyString, String publicKeyString) {
            byte[] privateKeyBytes = Base64.getDecoder().decode(privateKeyString);
            byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyString);
    
            try {
                KeyFactory keyFactory = KeyFactory.getInstance("RSA");
                PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
                // 使用 PKCS8EncodedKeySpec
                X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKeyBytes);
                privateKey = keyFactory.generatePrivate(privateKeySpec);
                publicKey = keyFactory.generatePublic(publicKeySpec);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    
        /**
         * 初始化密钥
         */
        public void initRSASecurity() {
            // 只有在公钥和私钥都为空时才重新生成密钥对
            if (publicKey == null && privateKey == null) {
                try {
                    KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
                    keyGen.initialize(2048);
                    KeyPair pair = keyGen.generateKeyPair();
                    // 保存公钥和私钥
                    publicKey = pair.getPublic();
                    privateKey = pair.getPrivate();
                    // 输出公钥和私钥的Base64编码值
                    log.info("RSA密钥生成成功: 公钥={}, 私钥={}", 
                             Base64.getEncoder().encodeToString(publicKey.getEncoded()), 
                             Base64.getEncoder().encodeToString(privateKey.getEncoded()));
                } catch (Exception e) {
                    log.error("初始化RSA密钥失败:", e.getMessage());
                }
            }
        }
        public void showPSAUSerSecutiryImpl(){
            log.info("RSA密钥获取成功: 公钥={}, 私钥={}", 
                     Base64.getEncoder().encodeToString(publicKey.getEncoded()), 
                     Base64.getEncoder().encodeToString(privateKey.getEncoded()));
        }
        /**
         * 获取公钥,返回前端,进行加密的数据
         */
        public String getPublicKeyString() {
            return Base64.getEncoder().encodeToString(this.publicKey.getEncoded());
        }
        /**
         * 获取私钥,进行解密的数据
         */
        public String getPrivateKeyString() {
            return Base64.getEncoder().encodeToString(this.publicKey.getEncoded());
        }
        /**
         * 利用私钥进行解密
         */
        public String declass(String decodeString) throws Exception {
            // 将传入的Base64编码字符串解码为字节数组
            byte[] encryptedBytes = Base64.getDecoder().decode(decodeString);
            // 使用私钥解密
            byte[] decryptedBytes = decrypt(encryptedBytes, this.privateKey);
            // 返回解密后的字符串
            return new String(decryptedBytes);
        }
        /**
         * 利用公钥进行加密
         */
        public String crypto(String encodeString) throws Exception {
            // 将传入的待加密字符串转换为字节数组
            byte[] data = encodeString.getBytes();
            // 使用公钥加密
            byte[] encryptedBytes = encrypt(data, this.publicKey);
            // 返回加密后的Base64编码字符串
            return Base64.getEncoder().encodeToString(encryptedBytes);
        }
    
        /**
         * 加密操作
         */
        private byte[] encrypt(byte[] data, PublicKey publicKey) throws Exception {
            // 获取RSA算法的Cipher实例
            Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
            // 用公钥初始化Cipher实例,设置为加密模式
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            // 执行加密操作,返回加密后的字节数组
            return cipher.doFinal(data);
        }
    
    
        /**
         * 解密操作
         */
        private byte[] decrypt (byte[] data, PrivateKey privateKey) throws Exception {
            // 获取RSA算法的Cipher实例
            Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
            // 用私钥初始化Cipher实例,设置为解密模式
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            // 执行解密操作,返回解密后的字节数组
            return cipher.doFinal(data);
        }
    }
    
    
  • 测试类

    可以测试init方法的加密和解密功能,也可以设定与前端一致的钥匙対,如果能跑通,你就成功了

    package com.happy_retail_management;
    
    import com.happy_retail_management.modules.security.RSAUserSecurity;
    import com.happy_retail_management.modules.security.RSAUserSecurityImpl;
    import org.junit.jupiter.api.Test;
    import org.springframework.boot.test.context.SpringBootTest;
    
    @SpringBootTest
    class RSAUserSecurityImplTest {
        @Test
        public void testRSAUserSecurityImTest() throws Exception {
            RSAUserSecurity rsaUserSecurity = new RSAUserSecurityImpl();
            rsaUserSecurity.initRSASecurity();
            //加密
            String crypto = rsaUserSecurity.crypto("123456");
            //解密
            String declass = rsaUserSecurity.declass(crypto);
            System.out.println("crypto:"+crypto+" declass:"+declass);
    
        }
        @Test
        public void testRSAUserSecurityImplTest() throws Exception {
            String publicKeyString = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjgRrqVP+D+CZCHr++8Bse+mQ/Wjt0lW9zkp6bghQAfg3wR5XmYYOFWs/0lqWYgCYiwSX+iFQap6+dtkuE7jPHjU6d9I0hXXSoUIMaxo2WA3IfXI45n2tRHPInCTgCoPNpHtycfMaaboBQ99altqdTvOylEiEgdZZ4v8Elksi9F7suvx7cCy2yJFF5rK0PtVEUMYe31EFWuKDlMyUvXcn8aU/81v2Z+cxyIph9WL4kVFo8qV3R+eFilbm/gPFSl5YXra16aUxwWEFvZVsNoK9zHNA0K4XjzF1eGk99M28B65gM5FIdKQ6SF3CdKk9C1mYCAVX6WeOC1i+5XNGJRrynwIDAQAB";
            String privateKeyString ="MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCOBGupU/4P4JkIev77wGx76ZD9aO3SVb3OSnpuCFAB+DfBHleZhg4Vaz/SWpZiAJiLBJf6IVBqnr522S4TuM8eNTp30jSFddKhQgxrGjZYDch9cjjmfa1Ec8icJOAKg82ke3Jx8xppugFD31qW2p1O87KUSISB1lni/wSWSyL0Xuy6/HtwLLbIkUXmsrQ+1URQxh7fUQVa4oOUzJS9dyfxpT/zW/Zn5zHIimH1YviRUWjypXdH54WKVub+A8VKXlhetrXppTHBYQW9lWw2gr3Mc0DQrhePMXV4aT30zbwHrmAzkUh0pDpIXcJ0qT0LWZgIBVfpZ44LWL7lc0YlGvKfAgMBAAECggEADZIZkZwvlmfRZ9CNBhSMqUiX7Mc2lpdP5GMUkOglcRK9jSwvlcGMHfraJek3HpVM/lfJiALf8thJfgTh1MufqxTOCf4hu7EXGAa+NgvSrpZelrIwAsJ2qKhhvp39dLPEllefh4kB+KFoForE1s58IrvB0E6fruKDQ2A4GX6DkBNPlAykT7a8KrO1dqBJe8jtjf4CiOCR6Y6j0hq4tz12dZXO1FY5/gFcq7Oj5j4k1iXAPGkVLS7cZYUQhfsXfiP75q/y/hyUbYsVDW6xBWidfyc8cCNRo8fDnC8MDLa0H5TRAe+mWkYKX6M1ZSpo3E2LDTizVr7GaMBwgZ9yxmvA1QKBgQC2F1ymUQexGXecYBsHlesH0ulOlU90XptH0fMDXxR+Z7ae5gK4QAZePRZNofatOyyQGQ1+u21d9mOLv7Wm/HcTofVYODQTEBheFlbzpYZ5ciLUfuYXNmRgQlnZFkP/x3xA+lVhuCEyE87liQ+iH3FCFHh9X2mAoAim7hN8J5SpBQKBgQDHqRKVW4UXSN5sQYn0j8yGPUB5Q5BCrZCn38T+NWXNPnXBcTY80VhOZtWR41+9zdowDp7AzOZV6xWMn1hrt9xaMP+tcbB1iIcc6XTxcHDVzppt8HXIqqnpXxM041Sz1rEGW/lcNADZabJIWn2AE4XDiP2iX+IV3AU27dS5tKhuUwKBgCgX0MCWCtmFv/5gctMiwVNBrzksSwhWZF5V7eoKH1sNvvoRrvuerUhGrwh85vGRm+hGe+AxqI0N2TFGDtsrr5RVDs5T4bNo0dS1moOfKJLI/L5JCqSFx2gic+IGswY4iDVOaUpQ3o5GKkIEAbsyrR9dnoIMZhB6LC2FMikeFe95AoGBAMa5o8OBOjD42FmLyhHfZsReBuQruVSEiKxubxZOc6sbdf05/6/89hXjCMOSOmMilv6qLpzb1I7D08kJeOqOMAadKn6p3+a8Iy9Ftp3xOn20i8TNR46ZP1EGzokfk9kD4WLg/IsnP4kmSMr3Nl7aD5OVsE2DffYf7hjEE61bASH9AoGAFGDQg/ym2KwNqpt1xOVdpXpVTrkwKCqMiugcMEnFo3YaiODGH8wPqGjbkrbF+xlHZZK2tmcPpSzo2AidgSUAsgna6mYpSlLb9mfQTzMufMk7H27dUwjXKfhZdZkOnHaUy07ElokbjItGv8zedJBrzzz8hQdfy6id+vLJda0OFFI=";
            String encodeString="123456";
            //显示密钥
            RSAUserSecurityImpl rsaUserSecurity = new RSAUserSecurityImpl(privateKeyString,publicKeyString);
            rsaUserSecurity.showPSAUSerSecutiryImpl();
            //加密
            String crypto = rsaUserSecurity.crypto(encodeString);
            //解密
            String declass = rsaUserSecurity.declass(crypto);
            System.out.println("crypto:"+crypto+"\n declass:"+declass);
    
        }
        @Test
        public void testRSAUserSecurityDeclass() throws Exception {
            String publicKeyString = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjgRrqVP+D+CZCHr++8Bse+mQ/Wjt0lW9zkp6bghQAfg3wR5XmYYOFWs/0lqWYgCYiwSX+iFQap6+dtkuE7jPHjU6d9I0hXXSoUIMaxo2WA3IfXI45n2tRHPInCTgCoPNpHtycfMaaboBQ99altqdTvOylEiEgdZZ4v8Elksi9F7suvx7cCy2yJFF5rK0PtVEUMYe31EFWuKDlMyUvXcn8aU/81v2Z+cxyIph9WL4kVFo8qV3R+eFilbm/gPFSl5YXra16aUxwWEFvZVsNoK9zHNA0K4XjzF1eGk99M28B65gM5FIdKQ6SF3CdKk9C1mYCAVX6WeOC1i+5XNGJRrynwIDAQAB";
            String privateKeyString ="MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCOBGupU/4P4JkIev77wGx76ZD9aO3SVb3OSnpuCFAB+DfBHleZhg4Vaz/SWpZiAJiLBJf6IVBqnr522S4TuM8eNTp30jSFddKhQgxrGjZYDch9cjjmfa1Ec8icJOAKg82ke3Jx8xppugFD31qW2p1O87KUSISB1lni/wSWSyL0Xuy6/HtwLLbIkUXmsrQ+1URQxh7fUQVa4oOUzJS9dyfxpT/zW/Zn5zHIimH1YviRUWjypXdH54WKVub+A8VKXlhetrXppTHBYQW9lWw2gr3Mc0DQrhePMXV4aT30zbwHrmAzkUh0pDpIXcJ0qT0LWZgIBVfpZ44LWL7lc0YlGvKfAgMBAAECggEADZIZkZwvlmfRZ9CNBhSMqUiX7Mc2lpdP5GMUkOglcRK9jSwvlcGMHfraJek3HpVM/lfJiALf8thJfgTh1MufqxTOCf4hu7EXGAa+NgvSrpZelrIwAsJ2qKhhvp39dLPEllefh4kB+KFoForE1s58IrvB0E6fruKDQ2A4GX6DkBNPlAykT7a8KrO1dqBJe8jtjf4CiOCR6Y6j0hq4tz12dZXO1FY5/gFcq7Oj5j4k1iXAPGkVLS7cZYUQhfsXfiP75q/y/hyUbYsVDW6xBWidfyc8cCNRo8fDnC8MDLa0H5TRAe+mWkYKX6M1ZSpo3E2LDTizVr7GaMBwgZ9yxmvA1QKBgQC2F1ymUQexGXecYBsHlesH0ulOlU90XptH0fMDXxR+Z7ae5gK4QAZePRZNofatOyyQGQ1+u21d9mOLv7Wm/HcTofVYODQTEBheFlbzpYZ5ciLUfuYXNmRgQlnZFkP/x3xA+lVhuCEyE87liQ+iH3FCFHh9X2mAoAim7hN8J5SpBQKBgQDHqRKVW4UXSN5sQYn0j8yGPUB5Q5BCrZCn38T+NWXNPnXBcTY80VhOZtWR41+9zdowDp7AzOZV6xWMn1hrt9xaMP+tcbB1iIcc6XTxcHDVzppt8HXIqqnpXxM041Sz1rEGW/lcNADZabJIWn2AE4XDiP2iX+IV3AU27dS5tKhuUwKBgCgX0MCWCtmFv/5gctMiwVNBrzksSwhWZF5V7eoKH1sNvvoRrvuerUhGrwh85vGRm+hGe+AxqI0N2TFGDtsrr5RVDs5T4bNo0dS1moOfKJLI/L5JCqSFx2gic+IGswY4iDVOaUpQ3o5GKkIEAbsyrR9dnoIMZhB6LC2FMikeFe95AoGBAMa5o8OBOjD42FmLyhHfZsReBuQruVSEiKxubxZOc6sbdf05/6/89hXjCMOSOmMilv6qLpzb1I7D08kJeOqOMAadKn6p3+a8Iy9Ftp3xOn20i8TNR46ZP1EGzokfk9kD4WLg/IsnP4kmSMr3Nl7aD5OVsE2DffYf7hjEE61bASH9AoGAFGDQg/ym2KwNqpt1xOVdpXpVTrkwKCqMiugcMEnFo3YaiODGH8wPqGjbkrbF+xlHZZK2tmcPpSzo2AidgSUAsgna6mYpSlLb9mfQTzMufMk7H27dUwjXKfhZdZkOnHaUy07ElokbjItGv8zedJBrzzz8hQdfy6id+vLJda0OFFI=";
            String encodeString="123456";
            RSAUserSecurityImpl rsaUserSecurity = new RSAUserSecurityImpl(privateKeyString,publicKeyString);
            rsaUserSecurity.showPSAUSerSecutiryImpl();
            //加密
    //        String crypto = rsaUserSecurity.crypto(encodeString);
            String crypto = "EQfPH+726simzkd+WN5ao5/TtdrifYU1R3jfLvJoFLamcFmu6JLj3kZX2W73bnPWRVRzRZUhC6F4fXjSmNjTTxbvsRwnVzzDxcTX8gWyS1TeLjkeG/IQ+ya+HKp8XwzDFcT7IAsJbD4CWd1r7Dtj9qqpQclGqksEtHS5nsATZHhEWCmNwHix4ZWxecEVjTpupLWAdZyFiQnoqhGuXZ7nW09W99sl6840pDOK/HtIKFJcfoD6rXHGgO+imNdNFkwxDtxOqSbrb0/BrpGxZBM/JhEPEUaECR15kwpp3ewnWRkcEctjsCHHEoZe2Faj8onv0rruO0qoKa36gV1q8ZMbdQ==";
            //解密
            String declass = rsaUserSecurity.declass(crypto);
            System.out.println("crypto:"+crypto+"\n declass:"+declass);
    
        }
    
    }
    
  • 通过Spring配置类,在项目启动时候注册该类(你可以不用这种方法去使用上面的实体类)

    package com.happy_retail_management.config.security;
    
    import com.happy_retail_management.modules.security.RSAUserSecurity;
    import com.happy_retail_management.modules.security.RSAUserSecurityImpl;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class SecurityConfig {
        @Bean
        public RSAUserSecurity initRSAUserSecurity(){
            RSAUserSecurity rsaUserSecurity = new RSAUserSecurityImpl();
            rsaUserSecurity.initRSASecurity();
            return rsaUserSecurity;
        }
    }
    

    有了上面这个controller层就可以注入这个类

    @RestController
    @RequestMapping("/user")
    public class UserController {
        @Autowired
        RSAUserSecurity rsaUserSecurity;
        @Autowired
        UserService userService;
         @RequestMapping("/getPublicKey")
        public Result<String> getPublicKey(){
            return Result.success(rsaUserSecurity.getPublicKeyString());
        }
        @RequestMapping("/register")
        public Result<String> regist(@RequestBody User  user){
            //校验非空值。Useraccount和password不能为空
            if(user.getAccount()==null){
                return Result.error("用户名不能为空");
            }
            if(user.getPassword()==null){
                return Result.error("用户密码不能为空");
            }
            //解密密码
            try{
                String decode = rsaUserSecurity.declass(user.getPassword());
                user.setPassword(decode);
            }catch (Exception e){
                return Result.error("解密密码错误");
            }
            //***省略业务逻辑******
        }
    }
    

感谢:
froge的创作者

大神的启发

  • 17
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
RSA算法是一种非常常用的公钥加密算法,可以用来对文件进行加密和解密。在Java中,可以使用BigInteger库来实现RSA算法,以下是一个简单的示例代码: ```java import java.math.BigInteger; import java.security.SecureRandom; public class RSA { private final static BigInteger one = new BigInteger("1"); private final static SecureRandom random = new SecureRandom(); private BigInteger privateKey; private BigInteger publicKey; private BigInteger modulus; // 生成公钥和私钥 public RSA(int bitLength) { BigInteger p = BigInteger.probablePrime(bitLength / 2, random); BigInteger q = BigInteger.probablePrime(bitLength / 2, random); BigInteger phi = (p.subtract(one)).multiply(q.subtract(one)); modulus = p.multiply(q); publicKey = new BigInteger("65537"); // 公钥指数一般为65537 privateKey = publicKey.modInverse(phi); } // 加密 public byte[] encrypt(byte[] message) { return (new BigInteger(message)).modPow(publicKey, modulus).toByteArray(); } // 解密 public byte[] decrypt(byte[] message) { return (new BigInteger(message)).modPow(privateKey, modulus).toByteArray(); } } ``` 在上面的代码中,我们首先定义了一个RSA类,并在构造函数中生成了公钥和私钥。在加密和解密方法中,我们使用了BigInteger的modPow方法来进行加密和解密操作。 示例代码中的加密和解密方法都接收一个byte数组作为参数,这意味着我们可以使用这些方法来对文件进行加密和解密。在实际使用中,我们可以通过读取文件的方式将文件内容转换为byte数组,然后使用RSA类的加密方法进行加密,再将加密后的结果写入到文件中。解密时,我们可以反过来读取加密后的文件,将内容转换为byte数组,然后使用RSA类的解密方法进行解密,最后将解密后的结果写入到文件中。 需要注意的是,在实际使用中,我们还需要考虑到文件大小可能会超过BigInteger类型的最大值,因此需要对文件进行分块处理,每次只处理固定大小的块。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值