Я пробовал предложения и приемы, читая различные ответы о переполнении стека, но они не кажутся достаточными, или, может быть, я чего-то упускаю. В основном я пытаюсь зашифровать значение в 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) Этот код кажется уязвимым для атак оракула. Было бы здорово, если бы вы могли предложить, как я могу сделать это безопасно.
Спасибо
Проблема может быть в вашей кодировке:
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).
Других решений пока нет …