RSA非对称加密,前台vue加密,后台java解密

前言

RSA加密非对称加密,简单理解为就是有一个私钥一个公钥,我们在前台用私钥进行加密,到后台以后再使用对应的公钥进行解密。(这一对公钥和私钥可以由后台实时生成,每次生成的公钥和私钥都不一样,然后后台把私钥传给前段;也可以前后端商量好固定的公钥和私钥自己单独保存。)

公钥和私钥的获取

在本文后端这块的RSAUtils工具里可以自动生成,这里提供一对,可用的公钥和私钥例子:
也可以用在线网站直接生成

一、前端Vue加密

1、组件模式

1.1安装jsencrypt

npm install jsencrypt

1.2 在src文件夹中的utils中创建jsencrypt.js

在这里插入图片描述

1.3 JSEncrypt

/** ***
 * RSA加密解密工具类
 * **/
import { JSEncrypt } from 'jsencrypt' // 导入
// 公钥和私钥需前后端一致
// 公钥
const publicKey = '获取的公钥'
// 私钥
const privateKey = '获取的私钥'

// 加密
export function encrypt(data) {
  const encryptor = new JSEncrypt()
  encryptor.setPublicKey(publicKey) // 设置公钥
  return encryptor.encrypt(data) // 对需要加密的数据进行加密
}

// 解密
export function decrypt(data) {
  const encryptor = new JSEncrypt()
  encryptor.setPrivateKey(privateKey)
  return encryptor.decrypt(data)
}

1.4 使用方法

  import { encrypt } from '../../utils/jsencrypt'

在这里插入图片描述
函数中使用

methods: {
      rr: function () {
        var userId = sessionStorage.getItem('userId')
        console.log('加密前:' + userId)
        let tt = encrypt(userId)
        console.log('加密后:' + tt)
      },

2、 直接使用

2.1 安装好后,直接在文件里引用

import { JSEncrypt } from 'jsencrypt';

2.2 使用私钥加密

// 加密
export const encryptedData = function(data) {
    //公钥和私钥和后端沟通是固定的
    let publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDpZVuOnmdJ8BtR2MknFU4k3LFonjJnub8N1vzERm5l4nFT2dRcQLQoM6NowEgAA3MuTZNJ9ocIhgBGNmmoHCmcTTUe4CPo4SAU+E4pVyzqQEeIydfIhFxb2n7uisgdsaqlQzKzM7NuwAWCCRX+jz2BIBghaGJxgC6LgdYTO3ir8QIDAQAB";
     // 新建JSEncrypt对象
    let encryptor = new JSEncrypt();
    // 设置公钥
    encryptor.setPublicKey(publicKey);
    var jm_data = encryptor.encrypt(data);
    // 加密数据
    return jm_data;
}

二、后端解密

2.1 RSAUtils工具类



import lombok.Data;
import org.apache.commons.codec.binary.Base64;
import org.jetbrains.annotations.NotNull;

import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

@Data
public class RSAUtils {

    private static final String ALGORITHM = "RSA";
    private static final String PUBLIC_KEY = "PUBLIC_kEY";
    private static final String PRIVATE_KEY = "PRIVATE_KEY";
    // 私钥
    public static final String privateKey = "";
    // 公钥
    public static final String publicKey = "";
    /**
     * 加密算法
     */
    private static final String CIPHER_DE = "RSA";
    /**
     * 解密算法
     */
    private static final String CIPHER_EN = "RSA";
    /**
     * 密钥长度
     */
    private static final Integer KEY_LENGTH = 1024;

    /**
     * RSA最大加密明文大小
     */
    private static final int MAX_ENCRYPT_BLOCK = 117;
    /**
     * RSA最大解密密文大小
     */
    private static final int MAX_DECRYPT_BLOCK = 128;

    /**
     * 生成秘钥对,公钥和私钥
     *
     * @return
     * @throws NoSuchAlgorithmException
     */
    public static Map<String, Object> genKeyPair() throws NoSuchAlgorithmException {
        Map<String, Object> keyMap = new HashMap<String, Object>();
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);
        keyPairGenerator.initialize(KEY_LENGTH); // 秘钥字节数
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();
        keyMap.put(PUBLIC_KEY, publicKey);
        keyMap.put(PRIVATE_KEY, privateKey);
        return keyMap;
    }

    /**
     * 公钥加密
     *
     * @param data
     * @param publicKey
     * @return
     * @throws InvalidKeySpecException
     */
    public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {
        // 得到公钥
        byte[] keyBytes = Base64.decodeBase64(publicKey.getBytes());
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        Key key = keyFactory.generatePublic(x509EncodedKeySpec);
        // 加密数据,分段加密
        Cipher cipher = Cipher.getInstance(CIPHER_EN);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        int inputLength = data.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offset = 0;
        byte[] cache;
        int i = 0;
        while (inputLength - offset > 0) {
            if (inputLength - offset > MAX_ENCRYPT_BLOCK) {
                cache = cipher.doFinal(data, offset, MAX_ENCRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(data, offset, inputLength - offset);
            }
            out.write(cache, 0, cache.length);
            i++;
            offset = i * MAX_ENCRYPT_BLOCK;
        }
        byte[] encryptedData = out.toByteArray();
        out.close();
        return encryptedData;
    }

    /**
     * 私钥解密
     *
     * @param data
     * @param privateKey
     * @return
     * @throws Exception
     */
    public static byte[] decryptByPrivateKey(byte[] data, String privateKey) throws Exception {
        // 得到私钥
        byte[] keyBytes = Base64.decodeBase64(privateKey.getBytes());
        PKCS8EncodedKeySpec pKCS8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        Key key = keyFactory.generatePrivate(pKCS8EncodedKeySpec);
        // 解密数据,分段解密
        Cipher cipher = Cipher.getInstance(CIPHER_DE);
        cipher.init(Cipher.DECRYPT_MODE, key);
        int inputLength = data.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offset = 0;
        byte[] cache;
        int i = 0;
        byte[] tmp;
        while (inputLength - offset > 0) {
            if (inputLength - offset > MAX_DECRYPT_BLOCK) {
                cache = cipher.doFinal(data, offset, MAX_DECRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(data, offset, inputLength - offset);
            }
//            out.write(cache, 0, cache.length);
            out.write(cache);
            i++;
            offset = i * MAX_DECRYPT_BLOCK;
        }
        byte[] decryptedData = out.toByteArray();
        out.close();
        return decryptedData;
    }

    /**
     * 获取公钥
     *
     * @param keyMap
     * @return
     */
    public static String getPublicKey(Map<String, Object> keyMap) {
        Key key = (Key) keyMap.get(PUBLIC_KEY);
        String str = new String(Base64.encodeBase64(key.getEncoded()));
        return str;
    }

    /**
     * 获取私钥
     *
     * @param keyMap
     * @return
     */
    public static String getPrivateKey(Map<String, Object> keyMap) {
        Key key = (Key) keyMap.get(PRIVATE_KEY);
        String str = new String(Base64.encodeBase64(key.getEncoded()));
        return str;
    }

    public static void main(String[] args) throws Exception {
        Map<String, Object> keyMap = RSAUtils.genKeyPair();
        String publicKey = RSAUtils.getPublicKey(keyMap);
        String privateKey = RSAUtils.getPrivateKey(keyMap);
        System.out.println("公钥:" + publicKey);
        System.out.println("私钥:" + privateKey);
        // 公钥加密
        String sourceStr = "111";
        System.out.println("加密前:" + sourceStr);
        byte[] encryptStrByte = RSAUtils.encryptByPublicKey(sourceStr.getBytes(), publicKey);
        byte[] btt = Base64.encodeBase64(encryptStrByte);
        String encryptStr = new String(btt);
        System.out.println("加密后:" + encryptStr);
        System.out.println("长度:" + encryptStr.length());

        // 私钥解密
        byte[] decryptStrByte = RSAUtils.decryptByPrivateKey(Base64.decodeBase64(encryptStr), privateKey);
        String sourceStr_1 = new String(decryptStrByte);
        System.out.println("解密后:" + sourceStr_1);

    }


    @NotNull
    // 传入前端加密的密码,解密后输出
    public static String decrypt(String ciphertext) throws Exception {
        byte[] bytes = ciphertext.getBytes(StandardCharsets.UTF_8);
        byte[] passwordBytes = decryptByPrivateKey(Base64.decodeBase64(bytes), privateKey);
        String password = new String(passwordBytes);
        return password;
    }
}

2.2 调用

String RpaPassword = RSAUtils.decrypt(password);

2.3 RSAUtils运行结果

公钥:MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC0yOa2YFKD9bln6ZFyMk46k6maIFreQQT0p6nS+wEtcF+8yGRUdY6Sdkz40bAudA245mKaNVSjkASN/ZzsQ7VLtG+0MywZ7qP8ownRz0ISLnTjuDpx0PtFcDQX35i7q02NJj0lwm5Z0gHha1StU6weCzaCXhI8B6Ze2Cs1Vn9zFQIDAQAB
私钥:MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALTI5rZgUoP1uWfpkXIyTjqTqZogWt5BBPSnqdL7AS1wX7zIZFR1jpJ2TPjRsC50DbjmYpo1VKOQBI39nOxDtUu0b7QzLBnuo/yjCdHPQhIudOO4OnHQ+0VwNBffmLurTY0mPSXCblnSAeFrVK1TrB4LNoJeEjwHpl7YKzVWf3MVAgMBAAECgYEAikl/CZSmqeBF4bGtmy/V3ULkokwLliUgOFEkO4nbPbnO0eZrsJt34prxiAdGAFKvyHcah6ExzCe3BDIyXhvwyd1rjfICjPG5R3rG/iziwRpwdpxScDKboA8oQEMA85PJKaVFtoG5sPUP+MMmNxmFD0lFQZ8ot3jY+ED3rwTPxSUCQQDja6yOUdrDm7/Wb5moVsOgeQ2NYH0AzcVBb9gyLVb6ii8gnE+Vn92Zklwg8UH7w1cmr6OMCA3JZPuKC9z01+a3AkEAy4DpEAhpLHs3lcfKg3TjtTMe4GWIbMiLZd7cwCuAXVZuPlXgrqWBmAgsfF9AQ+qCUb1G4Y1M1DbU/oKzIPHIkwJAI0GeDrJB5/FNXEEQ4TgSO96Ia1J6DpXX7r0YFy9QPKcPh060R83w3M4D2leMkytFZ4nzINJe0MoG9O/B4XNXIQJBAJHcvjBttuTZFIhZAcCjgasZDyKL4/ME81V7HgLnq0Q7dR1c9IR5wJ+2DBzBMRD8/5eS8UEtxEm/W39pMveEFd0CQC6oEFZvbgddQ8IJYyOpAMx4Wj6JrM2sdjXzHq/UxkaaPnBWIwQpI+9iqtgKcQ5Qjdp5rpLI1+dFYCi+G8f0pH0=
加密前:111
加密后:EDj5Sfl3YrOoimFSD30mIv2j4cLZOyDZOzGvnfH5ulg/s4Hgvtl3g4wzYGyJdlRgDDYE8VGCM7jWTNb4EHLR2KO95fSwOBs7wpULfsYgkNvvbVLEvSnBuM8S7XOVKIg0WB1YqiPyKFqcjf3r1ZlxpU4BahjqYKAFTC6Z0jU3VUU=
长度:172
解密后:111
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值