RSA前端加密,crypto node-rsa Node後端解密

發現node加密解密比較少,在此記錄下javascript

一,先生成公鑰私鑰
下載安裝windows平臺openssl密鑰生成工具,執行安裝目錄bin下的」openssl.exe」,執行後彈出命令窗口以下
opensslcss

  • 生成私鑰

輸入genrsa -out rsa_private_key.pem 1024,回車,命令窗口以下,在bin目錄下多了一個rsa_private_key.pem文件
將這個文件經過文本編輯器打開,將看到你所須要的私鑰前端

  • 生成公鑰

輸入rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem,在bin目錄下多了一個rsa_public_key.pem文件java

  • RSA私鑰轉換成 PKCS8 格式(可選的)

輸入pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocryptnode

二,Node後端測試加密解密web

const fs = require('fs')
const crypto = require('crypto')

const publicKey = fs.readFileSync('./rsa_public_key.pem').toString('utf-8')
const privateKey = fs.readFileSync('./rsa_private_key.pem').toString('utf-8')

console.log(publicKey) //公鑰
console.log(privateKey) //私鑰

const data = 'ceshi'
var buffer = new Buffer(data)
var encrypted = crypto.publicEncrypt(publicKey, buffer)

// 獲得加密的密文
let encryptedStr = encrypted.toString('base64')
console.log(encryptedStr)
//rkOkBtFX+xVcAMZ+wI7A0qY/HvDy8dRWvcw/+s7AYqsaGULlr12/RhrcRl7npIIb6t+L53/KkTGX56h8NwNsUsDHBVeL5kgOTWm6f5yOzaoz3ppnVGJbsLAO69I9qV26CzrwS8/PMtDMLbrJgpB/la4Nl7WDJX/GgOcmOFbNmTo=


// 解密
var buffer2 = new Buffer(encryptedStr, 'base64')
var decrypted = crypto.privateDecrypt(
    {
        key: privateKey,
        padding: crypto.constants.RSA_PKCS1_OAEP_PADDING
    },
    buffer2
)

console.log(decrypted.toString("utf8"))  //ceshi

三,前端加密 + 後端解密ajax

  • 前端代碼
<script src="https://cdn.bootcss.com/jsencrypt/3.0.0-beta.1/jsencrypt.min.js"></script> //須要引入一個rsa算法

<script type="text/javascript">
//封裝的fetch - ajax
function AJAX (url,method,body) {
  return new Promise((resolve, reject) => { fetch(url, { method: method, headers: { 'Content-Type':'application/x-www-form-urlencoded' }, body: body }).then(response => { response.json().then(data => { resolve(data) }) }).catch(err => { reject(err) }) }) } ;(async ()=> { const key = await AJAX('http://127.0.0.1:3001/key','GET') //先從後端獲得公鑰 let encrypt = new JSEncrypt(); encrypt.setPublicKey(key.publicKey) const userInfo = 'username@password' //須要加密的帳號密碼 const encryptKey = encrypt.encrypt(userInfo); //使用公鑰加密,獲得密文 console.log(encryptKey) const key2 = await AJAX('http://127.0.0.1:3001/user','POST', `key=${encryptKey}`)//發送密文 console.log(key2.publicKey) console.log(key2.publicKey == encryptKey) //測試發送的數據和後端接收的數據是否一致,頗有必要!!! })(); </script>
  • 後端代碼
//index本身開啓一個koa或者express
const Router = require('koa-router')
const router = new Router()
const fs = require('fs')
const crypto = require('crypto')    
const  publicKey = fs.readFileSync('./rsa_public_key.pem').toString('utf-8')
const  privateKey = fs.readFileSync('./rsa_private_key.pem').toString('utf-8')

//發送公鑰
router.get('/key', (ctx) => { ctx.body = { publicKey:publicKey } }) //接收傳遞的密文 router.post('/user', (ctx) => { //接收到的密文自動把+號替換成空了,這裏替換了下。 let userInfo = ctx.request.body.key.replace(/\s+/g, '+') console.log(userInfo) let buffer2 = new Buffer(userInfo, 'base64') let decrypted = crypto.privateDecrypt({ key: privateKey, padding: crypto.constants.RSA_PKCS1_PADDING }, buffer2 ) userInfo =decrypted.toString('utf-8') console.log(userInfo); //打印解密後的密文。 //PS 若是獲得空值,是由於格式不正確,貌似只能夠用字符串加密解密。 ctx.body = { publicKey: userInfo //返回獲得的密文,與前端發送的測試是否一致 } }) 

四,node-rsa模塊解密算法

  • 前端不變,只修改後端部分,這個貌似更簡單,模塊中生成密鑰
const NodeRSA = require('node-rsa')
const key = new NodeRSA({b: 512})  
key.setOptions({encryptionScheme: 'pkcs1'})

router.get('/key', (ctx) => { let publicKey = key.exportKey('public') //生成公鑰 console.log(publicKey) ctx.body = { publicKey:publicKey } }) router.post('/user', (ctx) => { let userInfo = ctx.request.body.key.replace(/\s+/g, '+') let decrypted = key.decrypt(userInfo, 'utf8'); //解密 console.log(decrypted); ctx.body = { publicKey: userInfo } })