Модуль NodeJS aes256
не поддерживает ваш алгоритм шифрования PHP. Он использует AES-256-CTR
для шифрования и SHA256
в качестве функции вывода ключа. IV генерируется случайным образом и добавляется к зашифрованному тексту.
Если вы хотите использовать этот модуль, вы должны быть в состоянии зашифровать - расшифровать ваши данные в PHP, используя функции ниже.
function encrypt($plaintext, $passphrase) {
$key = hash('SHA256', $passphrase, true);
$iv = openssl_random_pseudo_bytes(16);
$ct = openssl_encrypt($plaintext, 'AES-256-CTR', $key, 1, $iv);
return base64_encode($iv.$ct);
}
function decrypt($ciphertext, $passphrase) {
$data = base64_decode($ciphertext);
$ciphertext = substr($data, 16);
$key = hash('SHA256', $passphrase, true);
$iv = substr($data, 0, 16);
$pt = openssl_decrypt($ciphertext, 'AES-256-CTR', $key, 1, $iv);
return $pt;
}
Модуль aes256
использует crypto
для внутреннего использования. crypto
- это встроенный модуль, который поддерживает AES-256-ECB
, поэтому вы все равно можете перенести свой PHP-код на JS, но я бы не рекомендовал этого. AES-256-ECB
- очень слабый алгоритм шифрования, и он не обеспечивает аутентификацию.
Как PHP7, так и crypto
поддерживают аутентифицированные алгоритмы шифрования, так что вы можете использовать GCM, например. Также лучше всего использовать PBKDF2 (который также поддерживается PHP и crypto
) для создания ключа.
PHP-шифрование с AES-256-GCM, PBKDF2 с SHA256:
function encrypt($plaintext, $passphrase) {
$salt = openssl_random_pseudo_bytes(16);
$nonce = openssl_random_pseudo_bytes(12);
$key = hash_pbkdf2("sha256", $passphrase, $salt, 40000, 32, true);
$ciphertext = openssl_encrypt($plaintext, 'aes-256-gcm', $key, 1, $nonce, $tag);
return base64_encode($salt.$nonce.$ciphertext.$tag);
}
function decrypt($ciphertext, $passphrase) {
$input = base64_decode($ciphertext);
$salt = substr($input, 0, 16);
$nonce = substr($input, 16, 12);
$ciphertext = substr($input, 28, -16);
$tag = substr($input, -16);
$key = hash_pbkdf2("sha256", $passphrase, $salt, 40000, 32, true);
$plaintext = openssl_decrypt($ciphertext, 'aes-256-gcm', $key, 1, $nonce, $tag);
return $plaintext;
}
JS-шифрование с AES-256-GCM, PBKDF2 с SHA256:
var crypto = require('crypto');
function encrypt(plaintext, passphrase) {
var salt = crypto.randomBytes(16);
var nonce = crypto.randomBytes(12);
var key = crypto.pbkdf2Sync(passphrase, salt, 40000, 32, 'sha256');
var cipher = crypto.createCipheriv('aes-256-gcm', key, nonce);
var ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()]);
var output = Buffer.concat([salt, nonce, ciphertext, cipher.getAuthTag()]);
return output.toString('base64');
}
function decrypt(ciphertext, passphrase) {
var input = new Buffer(ciphertext, 'base64');
var salt = input.slice(0, 16);
var nonce = input.slice(16, 28);
ciphertext = input.slice(28, -16);
var tag = input.slice(-16);
var key = crypto.pbkdf2Sync(passphrase, salt, 40000, 32, 'sha256');
var cipher = crypto.createDecipheriv('aes-256-gcm', key, nonce);
cipher.setAuthTag(tag);
var plaintext = Buffer.concat([cipher.update(ciphertext), cipher.final()]);
return plaintext.toString('utf-8');
}
Эти функции дают совместимые результаты, поэтому зашифрованный текст, созданный с помощью encrypt
в PHP, можно расшифровать с помощью decrypt
в JS, и наоборот.