У нас есть Java-бэкэнд, который шифрует некоторые столбцы с помощью:
Encryptors.queryableText(secretKey, new String(Hex.encode(salt.getBytes(Charsets.UTF_8))));
Это создает объект типа TextEncryptor в определенной конфигурации, который затем может шифроваться с помощью textEncryptor.encrypt(msg)
и расшифровываться с помощью textEncryptor.decrypt(msg)
. Этот метод шифрования, предоставляемый Spring Security, используется, чтобы сделать зашифрованные столбцы доступными для запросов. Один и тот же текст всегда будет приводить к одной и той же зашифрованной строке.
Другим бэкэндам node.js теперь необходим доступ к некоторым зашифрованным столбцам для создания агрегированных отчетов.
Я нашел статью, которая кажетсярешить эту проблему довольно хорошо: https://stackanswers.net/questions/spring-4-encryptors-vs-cryptojs
Я изменил этот код в соответствии со своими потребностями. IV и соль должны были быть исправлены, как указано Encryptors.queryableText()
:
/*!
* Author: flohall
* date: 2019-11-05
* file: module/textEncryptor.js
*/
var CryptoJS = require("crypto-js");
var config = require('../config.json');
//keySize and iteration like specified in spring for AesBytesEncryptor
const keySize = 256;
const iterations = 1024;
//see config.json
const salt = CryptoJS.enc.Hex.parse(config.textEncryptor.hexEncodedSalt);
const secretKey = config.textEncryptor.secretKey;
const key = CryptoJS.PBKDF2(secretKey, salt, {
keySize: keySize / 32,
iterations: iterations
});
//same as NULL_IV_GENERATOR of AesBytesEncryptor - so encryption creates always same cipher text for same input
const iv = {words: [0, 0, 0, 0, 0, 0, 0, 0], sigBytes: 0}
const cfg = {
iv: iv,
padding: CryptoJS.pad.Pkcs7,
mode: CryptoJS.mode.CBC
}
exports.encrypt = function (msg) {
const encrypted = CryptoJS.AES.encrypt(msg, key, cfg);
return encrypted.ciphertext.toString();
}
exports.decrypt = function (encryptedMessage) {
var decrypted = CryptoJS.AES.decrypt(encryptedMessage, key, cfg)
return decrypted.toString(CryptoJS.enc.Utf8);
}
Пока все хорошо - важно знать, что config.textEncryptor.hexEncodedSalt, предоставленный функции node.js, уже является шестнадцатеричным. поваренная соль. Я сгенерировал его, используя:
//salt is read from application.yml and not hexencoded yet
System.out.println(new String(Hex.encode(salt.getBytes(Charsets.UTF_8))));
Метод node.js textEncryptor.encrypt(msg)
генерирует такое же зашифрованное сообщение, как textEncryptor.encrypt(msg)
в java, но все же textEncryptor.decrypt(msg)
в node.js не может расшифроватьтак же, как textEncryptor.decrypt(msg)
в java.
Этот тестовый код в node.js не работает:
var textEncryptor = require('./modules/textEncryptor.js');
var encrypted = textEncryptor.encrypt("helloWorld")
var decrypted = textEncryptor.decrypt(encrypted)
console.log(encrypted);
console.log(decrypted);
Он выводит только расшифрованный текст, за которым следует пустая строка.
Есть идеи - чего мне не хватает?