Node.js从MySQL解密加密字符串会导致EVP_DecryptFinal_ex:错误的最终块长度

Node.js从MySQL解密加密字符串会导致EVP_DecryptFinal_ex:错误的最终块长度,mysql,node.js,encryption,Mysql,Node.js,Encryption,我在加密服务类中有两个函数。1用于加密数据,1用于解密数据 export default class EncryptionService { private static algorithm = 'aes-256-cbc'; private static key = createHash('sha256').update(String('keyString')).digest('base64').substr(0, 32); private static iv =

我在加密服务类中有两个函数。1用于加密数据,1用于解密数据

export default class EncryptionService {

    private static algorithm = 'aes-256-cbc'; 

    private static key = createHash('sha256').update(String('keyString')).digest('base64').substr(0, 32);
    private static iv = Buffer.from('ivString');

    public static encryptData(data: string): string {
        const cipher = createCipheriv(this.algorithm, this.key, this.iv);
        let encrypted = cipher.update(data);
        encrypted = Buffer.concat([encrypted, cipher.final()]);
        const encryptedStr = encrypted.toString('base64');
        console.log('encryptedStr: ' + encryptedStr);
        return encryptedStr;
    }

    public static decryptData(data: string): string {
        const decipher = createDecipheriv(this.algorithm, this.key, this.iv);
        const decrypted = decipher.update(data, 'base64');
        const decryptedData = Buffer.concat([decrypted, decipher.final()]).toString();
        console.log('decryptedData: ' + decryptedData);
        return decryptedData;
    }
}
在我的控制器中,当我调用encryptData函数,然后立即调用decryptData函数,传递从encryptData函数返回的加密数据时,我会得到正确的未加密字符串

import EncryptionService from '../services/encryption-service';

export default class MyController {
  public async postData(request: Request, response: Response) {

    const encryptedAudioFileName = EncryptionService.encryptData(request.body.audio_file_name);
    EncryptionService.decryptData(encryptedAudioFileName);
  }
}
但是,当我通过控制器中的post函数将encryptData返回的加密数据存储到mySQL中,然后尝试通过控制器中的get函数对从mySQL检索的数据进行解密时,decryptData函数中出现一个错误,指出“EVP_DecryptFinal_ex:错误的最终块长度”


我做错了什么?

问题是我的列长度和/或类型。加密和解密代码工作正常。从mysql返回的数据被切断,因此无法正确解密。愚蠢的错误。感谢您的帮助。

您可以通过运行SQL
show CREATE table{tablename}
来显示您的表结构吗。存储的长度是多少?检索的长度是多少?创建表
表名
id
bigint(20)非空自动增量,
audio\u文件名
varchar(45)非空,
audio\u对话
mediumtext,
添加的日期
datetime非空,主键(
id
),唯一键
idtable\u唯一
id
)ENGINE=InnoDB AUTO_INCREMENT=59 DEFAULT CHARSET=latin1;我认为您解决了我的问题@danblack。我将列的大小更改为varchar(100)现在就可以了。我真是个白痴……感谢你的洞察力。语言隐藏mysql错误的默认方式让人很难看到。如果存储base64编码,请为
[var]char
列指定一个拉丁文18字符集。如果存储原始数据,请使用
varbinary
而不是
varchar
。(或者,如果是固定长度的,则仅使用
binary
)我最终将blob用于所有需要加密的列。
  public async postData(request: Request, response: Response) {
    Logger.info(request, response, 'Request Received');

    try {
      if (request.body) {
        const dataEntity = new dataEntity();
        dataEntity.audio_file_name = EncryptionService.encryptData(request.body.audio_file_name);

        const result = await getManager().save<dataEntity>(dataEntity);
        if (result) {
          const responseObject = {
            timestamp: new Date().toUTCString(),
            method: request.method,
            status: 'Success',
            statusCode: 201,
            message: 'successfully created.',
            path: request.originalUrl,
            reference: result.id,
          };
          Logger.success(request, response, responseObject);
          response.status(201).json(responseObject);
        } else {
          response.status(400).json(
            ResponseService.badRequestErrorResponseObject(request, response));
        }
      } else {
        response.status(400).json(
          ResponseService.badRequestErrorResponseObject(request, response, 'Body is invalid'));
      }
    } catch (error) {
      response.status(500).json(
        ResponseService.internalErrorResponseObject(request, response, error));
    }
  }

  public async getData(request: Request, response: Response) {
    Logger.info(request, response, 'Request Received');

    try {
      const allData: dataEntity[] =
        await getConnectionManager().get().getRepository(dataEntity).find();
      if (allData) {
        const entityResponseArray = [] as object[];
        allData.forEach( (entity) => {
          const dataResponse = {} as {id: number, audioFileName: string};
          dataResponse.id = entity.id!;
          dataResponse.audioFileName = EncryptionService.decryptData(entity.audio_file_name!);

          entityResponseArray.push(dataResponse);
        });

        Logger.success(request, response, 'Get list of data');
        response.json(entityResponseArray);
      } else {
        response.status(404).json(
          ResponseService.notFoundErrorResponseObject(request, response));
        return;
      }
    } catch (error) {
      response.status(500).json(
        ResponseService.internalErrorResponseObject(request, response, error));
    }
  }
const decryptedData = Buffer.concat([decrypted, decipher.final()]).toString();