AES 256 GCM encryption decryption in nodejs

折月煮酒 提交于 2020-12-03 07:48:09

问题


I am implementing a basic encryption/decryption set of functions in nodejs and I keep getting the following error in the decryption part:
Error: Unsupported state or unable to authenticate data

This is my code so far:

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()])
}

My error happens in the last line of the decrypt function. I am storing the iv as part of the dataBuffer.

Thanks in advance!


回答1:


I realized I had made a couple of mistakes with the original code that I posted, one of them as @TheGreatContini remarked was the size of the slicing which was being done in bits instead of bytes as it should be. Still, the biggest piece that I was missing was the authTag which always should be included in the decipher function setup.

Here is my working code for anybody interested for future references:

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()])
}


来源:https://stackoverflow.com/questions/53269132/aes-256-gcm-encryption-decryption-in-nodejs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!