浏览器端rsa加密方案node-forge

并无体验多少库,只看了一个npm里最多人用的一个库:前端

node-forge接口文档node

rsa小知识

  • 加密解密用的key是成对的,分别称为私钥和公钥,私钥必须存放在服务器等别人没法获取到的地方,公钥能够公开,谁均可以获取。
  • 不能把公钥当私钥,私钥当公钥使用,由于私钥能够提取出公钥。
  • 公钥加密的内容,只有私钥能解密,公钥不能解密本身加密的内容。
  • 私钥加密的过程称为签名(sign),由于公钥是公开的,谁都能解密,因此没法保密信息,只能用于验证签名者是私钥持有人。

前端代码

// 他们github有提供 forge.min.js , 不用webpack的项目也能够直接引用
import forge from 'node-forge'

const message = '要加密我了' // 原文长度有限制,并且中文还要url编码,因此不能加密太长的字符串。通常也只用来加密密码。
const publicKey = '-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCqM+l9ZWy1Frt6felFFLmfZNls\nVbU1dKpF8Rx83FtKCsztO5k/iV5N9BbfHFUg9Y40b/EK2j/BPc1xlLYAHMXn6563\nXCwZ4IuCxvfOwz9qT9gkKBxkI5b0rnikkSWTGlJEk2PdZ7Plc73Fa+bx3PvuKvMd\ncKWvd80+vt9+b/7hrwIDAQAB\n-----END PUBLIC KEY-----'
const publicK = forge.pki.publicKeyFromPem(publicKey)
const encrypted = publicK.encrypt(encodeURIComponent(message), 'RSA-OAEP') // 通过url编码,后端解密后须要url解码
console.log('密文:', encrypted) // 虽然乱码,但能够直接发给后端解密

ps. 以上代码建议使用try,由于加密中若是出现问题,会throw Errorwebpack

nodejs端代码

const forge = require('node-forge')
const privateKey = '-----BEGIN PRIVATE KEY-----\nMIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKoz6X1lbLUWu3p9\n6UUUuZ9k2WxVtTV0qkXxHHzcW0oKzO07mT+JXk30Ft8cVSD1jjRv8QraP8E9zXGU\ntgAcxefrnrdcLBngi4LG987DP2pP2CQoHGQjlvSueKSRJZMaUkSTY91ns+VzvcVr\n5vHc++4q8x1wpa93zT6+335v/uGvAgMBAAECgYArxUnou6qnL39rUvIol9ncyfy4\nRZpicuxPLGCdI7Y+ZmSpJciVdGhSN9Gh8xFZdozpo1gj6Fi5A4HQEeR0RvIF9Rgh\nERblj1rRWqxPcsIddOO9VaknQPICWKqEW9+E1bEcyNUblCHA4LGyQwmuEFUb/Tkj\nxAghIHuEBCe0GFiVwQJBAN5i5QSoOIpdFHA0c981E4VhHc/muXwjx1HfE1pcuuFb\nTy3OwEoZdFp3LIjBnBkPRneLTNjo5WTIwrmfsy6VDF8CQQDD7c6d/nKiJwIESlr+\n/idqXAPNR/iS1YX3Nqtk9jgrgf5zULHr2nbk7MDas5S9Z9XPdUmxtnP44dhoGvDk\nzyyxAkB7XBxyQuZqSkvGGjKUhJq5iC/DXddSd35fegEARSQdUktPu7qK4Cfc7vKz\nQcLXW9PZCFqukDJ/f6YU1fPNSTy9AkADQ78hms/GK+g4shR6EzoM56OYlA5sQ+qL\nh/mrIP8mmm/m8/1C9MzuW5OLEVr1HPnPDyE/OM8N4pV8hpZk+Z7BAkEAzaFstazA\nxLzZOBWhvOzzo722glZ7HVezhMocLu7Y3EOXP/nbx09JpU3U7Egp5UVp0aiknh/Q\nez4Cc4ksMedxdA==\n-----END PRIVATE KEY-----\n'
const privateK = forge.pki.privateKeyFromPem(privateKey)
const decrypted = privateK.decrypt(encrypted, 'RSA-OAEP') // encrypted 为前端传过来的密文
console.log('原文:', decodeURIComponent(decrypted)) // decrypted 为原文

ps. 以上代码建议使用try,由于解密中若是出现问题,会throw Errorc++

ps. 以上例子用了RSA-OAEP规则,其实rsa还有不少加密规则,我粗略查了一下,听说RSA-OAEP是目前比较新的方式,另外有一些旧的规则已经不推荐使用了,留着只是为了向上兼容。没有深刻查下去,由于我怕接下来要研究密码学了...git

ps. 若是以为加密后的字符串是乱码很差看,或者担忧传输会出问题,可使用base64转一下,服务端接收到则先解析base64再解密。github

生成密钥公钥对

const forge = require('node-forge')
const { rsa, publicKeyToRSAPublicKeyPem, privateKeyToPem } = forge.pki
rsa.generateKeyPair({ bits: 2048, workers: 2 }, function (err, keypair) {
  if (err) {
    return
  }

  // 这里就生成了字符串的公钥和密钥了,能够把生成结果保存起来
  console.log({
    publicKey: publicKeyToRSAPublicKeyPem(keypair.publicKey, 72).replace(/\r/g, ''),
    privateKey: privateKeyToPem(keypair.privateKey, 72).replace(/\r/g, '')
  })
})
相关文章
相关标签/搜索