Как зашифровать сообщение в браузере и расшифровать на сервере узла без сторонних библиотек? - PullRequest
1 голос
/ 22 апреля 2020

Почему-то я не могу положиться на шифрование SSL. И я не хочу использовать какие-либо сторонние библиотеки. Поэтому я попытался использовать crypto.subtle и криптомодули нативного браузера, aes-256-cb c, но безуспешно:

Создание ключа и шифрование тестового сообщения в браузере:

(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==

Как мне расшифровать сообщение на сервере узла? Я попытался 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)

1 Ответ

1 голос
/ 22 апреля 2020

Ключ также закодирован Base64 и поэтому должен быть декодирован как IV, например:

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

С этим изменением шифрованный текст расшифровывается до test message.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...