【问题标题】:AES 256 GCM encryption decryption in nodejsnodejs中的AES 256 GCM加密解密
【发布时间】:2018-11-12 19:01:28
【问题描述】:

我在 nodejs 中实现了一组基本的加密/解密函数,我在解密部分不断收到以下错误:
Error: Unsupported state or unable to authenticate data

这是我目前的代码:

import crypto from 'crypto'
import logger from './logger'

const ALGORITHM = 'aes-256-gcm'

export const encrypt = (keyBuffer, dataBuffer, aadBuffer) => {
  // iv stands for "initialization vector"
  const iv = Buffer.from(crypto.randomBytes(12), 'utf8')
  logger.debug('iv: ', iv)
  const encryptor = crypto.createCipheriv(ALGORITHM, keyBuffer, iv)
  logger.debug('encryptor: ', encryptor)
  logger.debug('dataBuffer: ', dataBuffer)
  return Buffer.concat([iv, encryptor.update(dataBuffer, 'utf8'), encryptor.final()])
}

export const decrypt = (keyBuffer, dataBuffer, aadBuffer) => {
  const iv = dataBuffer.slice(0, 96)

  const decryptor = crypto.createDecipheriv(ALGORITHM, keyBuffer, iv)
  return Buffer.concat([decryptor.update(dataBuffer.slice(96), 'utf8'), decryptor.final()])
}

我的错误发生在解密函数的最后一行。我将 iv 存储为 dataBuffer 的一部分。

提前致谢!

【问题讨论】:

  • 我可能错了,但是切片不是指定字节数(不是位)吗?如果是这种情况,那么您应该切片 12 个字节,而不是 96 个。

标签: encryption aes node.js


【解决方案1】:

我意识到我在发布的原始代码中犯了几个错误,其中一个正如 @TheGreatContini 所说的那样是切片的大小,它是以位而不是应该的字节来完成的。不过,我缺少的最大部分是 authTag,它始终应该包含在解密函数设置中。

这是我的工作代码,供有兴趣的人参考:

import crypto from 'crypto'
import logger from './logger'

const ALGORITHM = 'aes-256-gcm'

export const encrypt = (keyBuffer, dataBuffer, aadBuffer) => {
  // iv stands for "initialization vector"
  const iv = crypto.randomBytes(12)
  const cipher = crypto.createCipheriv(ALGORITHM, keyBuffer, iv)
  const encryptedBuffer = Buffer.concat([cipher.update(dataBuffer), cipher.final()])
  const authTag = cipher.getAuthTag()
  let bufferLength = Buffer.alloc(1)
  bufferLength.writeUInt8(iv.length, 0)
  return Buffer.concat([bufferLength, iv, authTag, encryptedBuffer])
}

export const decrypt = (keyBuffer, dataBuffer, aadBuffer) => {
  const ivSize = dataBuffer.readUInt8(0)
  const iv = dataBuffer.slice(1, ivSize + 1)
  // The authTag is by default 16 bytes in AES-GCM
  const authTag = dataBuffer.slice(ivSize + 1, ivSize + 17)
  const decipher = crypto.createDecipheriv(ALGORITHM, keyBuffer, iv)
  decipher.setAuthTag(authTag)
  return Buffer.concat([decipher.update(dataBuffer.slice(ivSize + 17)), decipher.final()])
}

【讨论】:

    猜你喜欢
    • 2021-06-04
    • 2021-09-03
    • 2020-12-03
    • 2021-03-05
    • 2021-11-07
    • 1970-01-01
    • 2020-07-03
    • 2021-01-10
    • 2021-09-24
    相关资源
    最近更新 更多