2014-10-28 40 views
0

我已经通过阅读关于堆栈溢出的各种答案尝试了一些建议和技巧,但它们似乎并不足够,或者可能存在一些基本的东西。基本上我试图在php中加密一个值,并将它传递到JavaScript所读取的网页并发送到节点服务器进行处理。但我无法获得相同的价值回到节点服务器,我用PHP加密。PHP中的加密和node.js中的解密

下面是PHP代码和PHP的版本是运行在Windows 7 5.5.12 64位: -

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运行在Windows 7 64位和代码如下: -

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); 
}); 

错误我从控制台的NodeJS打印FUID得到的是如下: -

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

我要找答案如下: -

1)我的代码存在问题,需要修复哪些内容才能在节点服务器上获取与字符串相同的值。

2)想要连接加密文本和iv并将它们作为单个base64编码字符串发送到服务器。所以想要将代码分离回节点服务器所需的代码准备好传递给加密模块。

3)此代码似乎容易受到Oracle填充攻击的影响。如果你能建议我怎样才能保证安全,这将是非常棒的。

感谢

回答

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签名您的加密数据包,以确保它们来自您的应用程序而不是来自“oracle”( http://www.ietf.org/id/draft-mcgrew-aead-aes-cbc-hmac-sha2-05.txt)。

+0

关于十六进制输入编码我离开它,因为节点文档说,如果输入是一个缓冲区,那么提供的编码将被忽略。这似乎也许是一个版本问题。你测试了什么环境? – 2014-10-28 09:34:08

+0

@Avdhesh:PHP 5.3.6/Ubuntu,节点v0.11.12/OSX Mavericks。 – georg 2014-10-28 09:37:09

+0

我的不好。实际上我得到了与之前相同的错误“致命:1414489055585:TypeError:错误:06065064:数字信封例程:EVP_DecryptFinal_ex:错误解密” – 2014-10-28 09:39:33