Node.js从MySQL解密加密字符串会导致EVP_DecryptFinal_ex:错误的最终块长度
我在加密服务类中有两个函数。1用于加密数据,1用于解密数据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 =
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();