简体   繁体   English

如何在没有第三方库的情况下在浏览器上加密消息并在节点服务器上解密?

[英]How to encrypt message on browser and decrypt on node server without third-party libraries?

For some reason I can't rely on SSL encryption.出于某种原因,我不能依赖 SSL 加密。 And I don't want to use any third-party libraries.而且我不想使用任何第三方库。 So I tried to use native browser's crypto.subtle and node's crypto modules, aes-256-cbc, but with no luck:所以我尝试使用本机浏览器的 crypto.subtle 和节点的加密模块 aes-256-cbc,但没有运气:

Creating the key and encrypting test message in browser:在浏览器中创建密钥并加密测试消息:

(async function() {
  const {key, keyStr} = await generateKey()
  console.log(`string key for the node server: ${keyStr}`)
  const {iv, encrypted} = await encrypt(key, 'test message')
  console.log(`base64 iv: ${iv}, base64 encrypted message: ${encrypted}`)
})()

async function generateKey() {
  const key = await crypto.subtle.generateKey(
    {name: 'AES-CBC', length: 256},
    true,
    ['encrypt', 'decrypt']
  )
  const jwk = await crypto.subtle.exportKey('jwk', key)
  return {key, keyStr: jwk.k}
}

async function encrypt(key, text) {
  const iv = crypto.getRandomValues(new Uint8Array(16))
  const encrypted = await crypto.subtle.encrypt(
    {name: 'AES-CBC', iv},
    key,
    str2buf(text),
  )
  return {
    iv: buf2base64(iv),
    encrypted: buf2base64(encrypted),
  }
}

// helpers
function str2buf(str) {
  const bytes = new Uint8Array(str.length)
  for (let i = 0; i < str.length; i++) bytes[i] = str.charCodeAt(i)
  return bytes
}
function buf2base64(buf) {
  let binary = ''
  let bytes = new Uint8Array(buf)
  let len = bytes.byteLength
  for (let i = 0; i < len; i++) binary += String.fromCharCode(bytes[i])
  return btoa(binary)
}

Output: string key for node server: 9ffC8m6BhFFf0mYTPrf5SAzDVCAGg1ce59LP5dqGnVc base64 iv: XTRis0eBYEl+NAt8adZN+w==, encrypted message: uReCH7g3p8FNKpwo6E+kfw==

How can I decrypt the message on the node server?如何解密节点服务器上的消息? I tried to crypto.createDecipheriv and following gives the 'Invalid key length' error:我试图crypto.createDecipheriv并且下面给出了“无效的密钥长度”错误:

const crypto = require('crypto')

const key = '9ffC8m6BhFFf0mYTPrf5SAzDVCAGg1ce59LP5dqGnVc'
const iv = 'XTRis0eBYEl+NAt8adZN+w=='
const encryptedMessage = 'uReCH7g3p8FNKpwo6E+kfw=='

const decipher = crypto.createDecipheriv('aes-256-cbc', key, Buffer.from(iv, 'base64'))
let decrypted = decipher.update(Buffer.from(encryptedMessage, 'base64'))
decrypted += decipher.final('utf8')
console.log(decrypted)

The key is also Base64 encoded and must therefore be decoded like the IV, eg:密钥也是 Base64 编码的,因此必须像 IV 一样解码,例如:

const key = Buffer.from('9ffC8m6BhFFf0mYTPrf5SAzDVCAGg1ce59LP5dqGnVc', 'base64') 

With this change the ciphertext is decrypted to test message .通过此更改,密文被解密为test message

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用 Node.js 下载文件(不使用第三方库)? - How to download a file with Node.js (without using third-party libraries)? 如何在用户脚本中集成第三方JavaScript库 - how to integrate third-party JavaScript libraries in userscripts 工兵 如何在全球范围内使用第三方库 - Sapper. How to globally use third-party libraries 如何在不使用第三方库的情况下使用 Node.js 读取 PDF 文件? - How to read PDF files with Node.js without using third-party library? Hyperledger Composer事务可以支持第三方javascript库/node.js包吗? - Can Hyperledger Composer transactions support third-party javascript libraries/node.js packages? 如何在上传前预览视频 - vanilla JavaScript 没有第三方库 - How to preview a video before upload - vanilla JavaScript no third-party libraries 如何将第三方JavaScript库添加到Meteor应用程序? - How can I add third-party JavaScript libraries to a Meteor application? 使用第三方库中的异步功能调试JavaScript? - Debugging JavaScript with asynchronous functions in third-party libraries? 基准测试WebCrypto比第三方库慢得多? - Benchmarking WebCrypto is much slower than third-party libraries? SvelteJS是否将第三方库代码转换为纯Javascript? - Does SvelteJS convert third-party libraries code to plain Javascript?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM