2016-10-27 18 views
1

Я пытаюсь расшифровать строку, ранее зашифрованную сторонним программным обеспечением с использованием PHP RIJNDAEL_128 в режиме CBC, используя node.js.Расшифровать строку в node.js из PHP RIJNDAEL_128 CBC

В интерактивной ссылке следующего кода PHP в песочнице, чтобы вы могли скомпилировать и посмотреть сами. http://sandbox.onlinephpfunctions.com/code/504a7d052c5b123fac8103a073c05c2ff5f80571

исходный PHP код:

<?php 
class CryptClass{ 

    private $key; 

    public function __construct($key){ 
     $this->key = $key; 
    } 

    public function cryptage($message){ 

     $key = base64_decode($this->key); 
     $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); 
     $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); 

     $ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $message, MCRYPT_MODE_CBC, $iv); 
     $ciphertext = $iv . $ciphertext; 

     return base64_encode($ciphertext); 
    } 

    public function decryptage($message){ 
     $key = base64_decode($this->key); 
     $iv_size2 = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); 
     $ciphertext_dec = base64_decode($message); 
     $iv_dec = substr($ciphertext_dec, 0, $iv_size2); 
     $ciphertext_dec = substr($ciphertext_dec, $iv_size2); 

     $message_decrypt = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key,$ciphertext_dec, MCRYPT_MODE_CBC, $iv_dec); 

     return str_replace("\0", "", $message_decrypt); 
    } 
} 

// Secret key and data 
define('KEY', 'azertyuiolskzif'); 
define('DATA', '[email protected]|1477576941|origin.com'); 

// Crypt 
$Crypt = new CryptClass(base64_encode(KEY)); 
$encodedData = base64_encode($Crypt->cryptage(DATA)); 

// Decrypt 
$decodedData = $Crypt->decryptage(base64_decode($encodedData)); 

echo 'base64_encode: '.base64_encode(KEY); 
echo "\nDATA: ".DATA; 
echo "\nDATA length: ".strlen(DATA); 
echo "\n\nencodedData: ".$encodedData; 
echo "\n\ndata: ".$decodedData; 
echo "\n\ndata length: ".strlen($decodedData); 
echo "\n\ncrypt/decrypt match?: ".(DATA == $decodedData ? 'yes':'no'); 

Вот моя реализация в Node.js: НЕ РАБОТАЕТ, см ниже рабочего раствора

var crypto = require('crypto'); 

var textToEncrypt = '[email protected]|1477576941|origin.com'; 
var encryptionMethod = 'AES-128-CBC'; 
var secret = "azertyuiolskzif"; 
var iv = 'aaaabbbbccccdddd'; 


var encrypt = function (plain_text, encryptionMethod, secret, iv) { 
    var encryptor = crypto.createCipheriv(encryptionMethod, secret, iv); 
    return encryptor.update(plain_text, 'utf8', 'base64') + encryptor.final('base64'); 
}; 

var decrypt = function (encryptedMessage, encryptionMethod, secret, iv) { 
    var decryptor = crypto.createDecipheriv(encryptionMethod, secret, iv); 
    return decryptor.update(encryptedMessage, 'base64', 'utf8') + decryptor.final('utf8'); 
}; 

var encryptedMessage = encrypt(textToEncrypt, encryptionMethod, secret, iv); 
var decryptedMessage = decrypt(encryptedMessage, encryptionMethod, secret, iv); 

console.log(decrypt()); 
console.log(encryptedMessage); 
console.log(decryptedMessage); 

Я попытался многие вещи, и я теряюсь здесь между Invalid key length и другими ошибками или сообщений. Одна вещь, которую я не совсем понимаю, заключается в том, что KEY, по-видимому, используемый для шифрования данных: azertyuiolskzif, который длится 15 символов, в то время как большинство сценариев используют требуемую строку 32 символов. Может быть, PHP не нуждается в строковой строчке 32, но Node делает ?

Возможно, это связано с различием между 128 и 256. Или это связано с различием заполнения между PHP и Node-реализацией?

Я попытался следовать советам, указанным в Encrypt string in PHP and decrypt in Node.js, но даже tho мне еще не удалось шифровать мои данные в узле.


Edit:

После некоторых более копаться (и спасибо за объяснения в ответах), я наконец сделал склепа/дешифрования работы в Node.js. Но мне еще не удалось расшифровать что-то, зашифрованное PHP.

var crypto = require('crypto'); 

var AES = {}; 

AES.encrypt = function(dataToEncrypt, encryptionMethod, secret, iv, padding) { 
    var encipher = crypto.createCipheriv(encryptionMethod, secret, iv); 
    encipher.setAutoPadding(padding || 0); // "true" or "128" would work with aes-128-cbc 
    var encryptedData = encipher.update(dataToEncrypt, 'utf8', 'base64'); 

    encryptedData += encipher.final('base64'); 
    return encryptedData; 
}; 

AES.decrypt = function(encryptedData, encryptionMethod, secret, iv, padding) { 
    var decipher = crypto.createDecipheriv(encryptionMethod, secret, iv); 
    decipher.setAutoPadding(padding || 0); // "true" or "128" would work with aes-128-cbc 
    var decoded = decipher.update(encryptedData, 'base64', 'utf8'); 

    decoded += decipher.final('utf8'); 
    return decoded; 
}; 

// ---- 

var textToEncrypt = '[email protected]|1477576941|origin.com'; 
var secret = "aaaabbbbccccdddd"; // Must be 16 chars 
var iv = crypto.randomBytes(16); // Must be 16 chars 
var encryptionMethod = 'AES-128-CBC'; 

// Testing crypt/decrypt using Node.js algorithm. 
var encryptedMessage = AES.encrypt(textToEncrypt, encryptionMethod, secret, iv, 128); 
var decryptedMessage = AES.decrypt(encryptedMessage, encryptionMethod, secret, iv, 128); 

console.log('encryptedMessage', encryptedMessage); // Displays "GWpMWORNKkqlrHJDPuNgSmTKr1vJhaAApHP+ssK3SH5EALTkdWneUZRp9PXNpVQ2" 
console.log('decryptedMessage', decryptedMessage); // Displays "[email protected]|1477576941|origin.com" 


// Testing decrypt from a string generated by PHP algorithm. 
// XXX Doesn't work "Error: error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length" 
// XXX Probably due to wrong padding between PHP/Node implementation? 
var stringToDecode = 'RlM3Wkl3N3JRM0dnaEh4SkdoZWFDRy9mZGRoTnkxNlZUL2IvcHl4TkdzUUlRSXQwSWNwWUZ5OFpaRENZQys3S2t0bFZIUWoweUVsZGxUU21sYU9tS0E9PQ=='; 
console.log('stringToDecode', stringToDecode); 
console.log(AES.decrypt(
    stringToDecode, 
    encryptionMethod, secret, iv, 128 
)); 
+0

У меня нет слова в оригинальной реализации, я сомневаюсь, что они изменят его ... (Это клиент) Но спасибо за информацию :) – Vadorequest

+1

128 в MCRYPT_RIJNDAEL_128 - размер блока, размер ключа определяется размером фактического ключевого аргумента. Это общий и запутанный аспект для mcrypt. Rijndael поддерживает несколько размеров блоков, и для AES была выбрана версия с 128-строчным размером блока. См. [Шифры Mcrypt] (http://php.net/manual/en/mcrypt.ciphers.php) и [AES в PHP с использованием Mcrypt] (https://www.leaseweb.com/labs/2014/02/aes -PHP-Mcrypt ключ-набивка /). – zaph

ответ

1

Ключи AES должны быть точно такими же, как 128, 192 или 256 бит. Некоторые реализации будут каким-то образом вставлять клавиши, но на это не следует полагаться. Сделайте ключ правильного размера.

 Смежные вопросы

  • Нет связанных вопросов^_^