javascript — шифрование в PHP и дешифрование в node.js

Я пробовал предложения и приемы, читая различные ответы о переполнении стека, но они не кажутся достаточными, или, может быть, я чего-то упускаю. В основном я пытаюсь зашифровать значение в php и передать его на веб-страницу, откуда оно читается JavaScript, и отправить на сервер узла для обработки. Но я не могу получить то же значение обратно на сервер узла, который я зашифровал в php.

Ниже приведен код php и версия php 5.5.12, работающая на 64-битной Windows 7:

function encrypt($string){
$key = hash("SHA256", '1d417e2ffb2a00a3', true);
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$blockSize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$padding = $blockSize - (strlen($string) % $blockSize);
$string .= str_repeat(chr($padding), $padding);

$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key,$string, MCRYPT_MODE_CBC, $iv);
$result['cipher'] = base64_encode($ciphertext);
$result['iv'] = base64_encode($iv);
return $result;
}

Моя версия node.js — 0.10.31, работающая на 64-битной Windows 7, и код ниже: —

var express = require("express");
var Server = require("http").Server;
var cookie = require("cookie");
var app = express();
var server = Server(app);
var sio = require("socket.io")(server);
var crypto = require('crypto');

sio.sockets.on("connection", function(socket) {
try{
socket.on('incoming_data', function(data){
var txt = new Buffer(data.encrypted_text,'base64');
var key = new Buffer('1d417e2ffb2a00a3','utf8');
var iv = new Buffer(data.iv,'base64');
var decipher = crypto.createDecipheriv('aes-128-cbc',key,iv);
var chunks = [];
chunks.push(decipher.update(txt,'hex','binary'));
chunks.push(decipher.final('binary'));
var fuid = chunks.join('');
console.log(fuid);
});
}catch(e){
console.log("err:-"+e);
console.log(e);
}
});// on connection ends
server.listen(9267, function(){
console.log('Node server listening on *:9267');
});

process.on('uncaughtException', function(err) {
console.log("FATAL: "+new Date().getTime()+": "+err);
});

Ошибка, которую я получаю от печати fuid в консоли nodejs, выглядит следующим образом:

FATAL: 1414483246855: TypeError: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt

Я ищу решения для следующих ответов: —

1) Проблемы с моим кодом и что нужно исправить, чтобы вернуть то же значение на сервере узла, что и строка.

2) Хотел бы объединить зашифрованный текст и iv и отправить их как одну строку в кодировке base64 на сервер. Поэтому хотелось бы, чтобы код, который потребуется для их разделения на сервере узлов, был готов к передаче в криптомодуль.

3) Этот код кажется уязвимым для атак оракула. Было бы здорово, если бы вы могли предложить, как я могу сделать это безопасно.

Спасибо

0

Решение

Проблема может быть в вашей кодировке:

chunks.push(decipher.update(txt,'hex','binary'));

hex выглядит странно, так как ваши входные данные являются буферами, а не строками.

Следующий быстрый тест работает (также ответы 2.):

PHP:

$key = 'secretsecretsecr';
$string = 'attack at dawn';

$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$blockSize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$padding = $blockSize - (strlen($string) % $blockSize);
$string .= str_repeat(chr($padding), $padding);
$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key,$string, MCRYPT_MODE_CBC, $iv);

$packet = chr($iv_size) . $iv . $ciphertext;

print base64_encode($packet);

узел:

var crypto = require('crypto');

var key = 'secretsecretsecr';
var data = 'paste what the php code printed';

var txt = new Buffer(data,'base64');
var iv_size = txt[0];
var iv = txt.slice(1, iv_size + 1);
var ct = txt.slice(iv_size + 1);
var decipher = crypto.createDecipheriv('aes-128-cbc',key,iv);
var chunks = [];
chunks.push(decipher.update(ct));
chunks.push(decipher.final());

console.log(chunks.join(''));

Передавая размер iv, вы также можете просто жестко закодировать его на стороне узла.

Что касается 3), я ни в коем случае не эксперт, из того, что я прочитал, обходной путь заключается в том, чтобы подписать ваши зашифрованные пакеты с помощью HMAC, чтобы убедиться, что они поступают из вашего приложения, а не из «оракула» (http://www.ietf.org/id/draft-mcgrew-aead-aes-cbc-hmac-sha2-05.txt).

0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector