前端匹配java的RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING规范

最近项目登录需要加密,用的是AES和RSA组合加密,公钥加密密钥,密钥加密数据,将这两个参数传给后端,后端再用私钥解密出密钥,然后密钥解密出数据。

本来用的RSA/ECB/PKCS1Padding规范,demo都调通了。放到项目中后端java有漏洞,只能改成RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING这种规范,后端只改个名字就ok。前端得改用node-forge插件才行。

后端自己搜有几篇,我在这放一下前端vue的

需要安装npm install jsrsasign --save,npm install crypto-js --save,npm install node-forge --save

utils下新建encryption.js文件:

import jsCookie from 'js-cookie' // 导入 cookie
import jsrsasign from 'jsrsasign' // 导入 生成公钥密钥 插件
import CryptoJS from 'crypto-js' // 导入 AES 插件
import forge from 'node-forge'
// 公钥加密密钥 的方法
function pubencrypt(aeskey, pubencryptKey) {
    const publicKeyAll = '-----BEGIN PUBLIC KEY-----\n' + pubencryptKey + '\n-----END PUBLIC KEY-----'
    var publicKey = forge.pki.publicKeyFromPem(publicKeyAll)
    var buffer = forge.util.createBuffer(aeskey, 'utf8')
    var bytes = buffer.getBytes()
    var pubencryptedText = forge.util.encode64(publicKey.encrypt(bytes, 'RSA-OAEP', {
        md: forge.md.sha256.create(),
        mgf1: {
            md: forge.md.sha1.create()
        }
    }))
    return pubencryptedText
}
// 生成 公钥和私钥 的方法
export function jsrsasignFn() {
    var rsaKeypair = jsrsasign.KEYUTIL.generateKeypair('RSA', 1024)
    var private1 = jsrsasign.KEYUTIL.getPEM(rsaKeypair.prvKeyObj, 'PKCS1PRV')
    var public1 = jsrsasign.KEYUTIL.getPEM(rsaKeypair.pubKeyObj)
    var rsaKey = {
        'privateKey': private1.substring(31, private1.length - 31).replace(/\r\n/g, ''),
        'publicKey': public1.substring(28, public1.length - 28).replace(/\r\n/g, '')
    }
    return rsaKey
}
// AES 加密  data:要加密解密的数据,AES_KEY:密钥,IV:偏移量
function encrypt(data, AES_KEY, IV) {
    const key = CryptoJS.enc.Utf8.parse(AES_KEY)
    const iv = CryptoJS.enc.Utf8.parse(IV)
    const encrypted = CryptoJS.AES.encrypt(data, key, {
        iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    })
    return encrypted.toString()
}
// 生成16位随机数
function getmm(num = 16) {
    var amm = ['!', '@', '#', '$', '%', '&', '*', '(', ')', '_', 1, 2, 3, 4, 5, 6, 7, 8, 9]
    var tmp = Math.floor(Math.random() * num)
    var s = tmp
    s = s + amm[tmp]
    for (let i = 0; i < Math.floor(num / 2) - 1; i++) {
        tmp = Math.floor(Math.random() * 26)
        s = s + String.fromCharCode(65 + tmp)
    }
    for (let i = 0; i < (num - Math.floor(num / 2) - 1); i++) {
        tmp = Math.floor(Math.random() * 26)
        s = s + String.fromCharCode(97 + tmp)
    }
    return s
}
// 参数加密 的方法
export function resEncryption(data, publicKey) {
    // 生成随机密钥(key+iv)
    var key = getmm()
    var iv = getmm()
    // 密钥 加密 数据(将json转成字符串再进行加密)
    var newStr = encrypt(JSON.stringify(data), key, iv)
    // 公钥 加密 密钥(key+iv组成)
    var appSecret = pubencrypt(key + iv, jsCookie.get('publicKey'))
    // 返回数据
    var formData = new URLSearchParams()
    formData.append('encryptedData', newStr)
    formData.append('appSecret', appSecret)
    return formData
}

页面中使用

import { resEncryption } from '@/utils/encryption.js'
sendDataFn() {
    const encData = {
                    phoneNumber: '123',
                    token: 'abc'
                }
                getSendCode(resEncryption(encData),
                    { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } 
    }).then(res => {
                    if (res.code === 1000) {
                        this.$message({
                            message: '成功!',
                            type: 'success'
                        })
                    }
                }).catch(err => {
                    console.log(err)
                })
}
  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值