Node.js / javascript加密AES-128,就像PHP中的mcrypt_ecb一样

时间:2015-07-17 14:36:22

标签: javascript php node.js encryption

我有一个PHP代码,用AES-128加密一个ip地址:

$ip = "MY_IP";
$secret = "MY_KEY";
$ip = @mcrypt_ecb(MCRYPT_RIJNDAEL_128, $secret, $ip, MCRYPT_ENCRYPT); 
$encrypted = bin2hex($ip);  // encrypted: 2854edb405cb7230ba1f4b87acddba8a

我需要做的是使用相同的代码但使用javascript / node.js。我在crypto node.js本机模块中搜索过,但是我无法重现相同的结果:

var crypto = require('crypto');
var ip = "MY_IP";
var secret = "MY_KEY";
var cipher = crypto.createCipher("AES-128-ECB", secret);
var encrypted = cipher.update(ip, 'utf8', 'hex');
encrypted += cipher.final('hex'); // encrypted: e84c06888696edda0139e98fc2c0a8cc

有人有想法吗?

3 个答案:

答案 0 :(得分:3)

我发布得太快,找到了解决方案:

$> npm install mcrypt

然后是代码:

var MCrypt = require('mcrypt').MCrypt;
var ip = "MY_IP";
var secret = "MY_KEY"
var desEcb = new MCrypt('rijndael-128', 'ecb');
desEcb.open(secret);
var cipherText = desEcb.encrypt(ip); // cipherText: 2854edb405cb7230ba1f4b87acddba8a

MCrypt github获取更多加密工具:https://github.com/tugrul/node-mcrypt

答案 1 :(得分:3)

这里的问题是PHP的mcrypt扩展(和节点的createCipher())在幕后做了一些你可能不知道的事情。

首先,createCipher()接受使用MD5进行哈希处理的“密码”,以获取实际键。所以你应该使用的是createCipheriv(),它允许你直接传递密钥(和IV),就像PHP的mcrypt接受的那样。在ECB模式下,IV被忽略,因此您只需为IV参数传入一个空字符串。

其次,如果PHP密码小于密码的块大小和密钥大小,那么PHP的mcrypt会错误地将输入你的密钥用空字节填充。

因此,对于AES-128-ECB,我们需要确保输入和密钥长度是16个字节的倍数。通过所有这些知识,我们发现内置crypto模块的适当代码可能类似于:

var crypto = require('crypto');

function makePadded(str) {
  var buf;
  var len = str.length;
  if (str.length % 16)
    len = str.length + (16 - str.length % 16);
  buf = new Buffer(len);
  buf.fill(0);
  buf.write(str, 0, str.length);
  return buf;
}

var ip = makePadded('MY_IP');
var secret = makePadded('MY_KEY');
var cipher = crypto.createCipheriv("AES-128-ECB", secret, '');
var encrypted = cipher.update(ip, 'binary', 'hex');
encrypted += cipher.final('hex');
// Slice off at 16 bytes to match the input length
encrypted = encrypted.slice(0, 32);

console.log(encrypted);

值得一提的最后一件事是,PHP中的MCRYPT_RIJNDAEL_128可用于执行128,192或256位加密。因此,在PHP 0 < keylen <= 16中,将使用128位加密,如果16 < keylen <= 24将使用24 < keylen <= 32,将使用192位加密,angular.module("demoApp", ['ngRoute']) .config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) { $routeProvider. when('someURL', { templateUrl: 'someTemplate.html', controller: 'CreateGrids' }); $locationProvider.html5Mode(true); } ]) .factory("servers", function () { var servers = {}; ... return servers; }) .factory("setup", function () { var setup = {}; ... return setup; }) .factory("gridservice", ['$http', function ($http) { var gridservice = {}; ... return gridservice; }]) .controller('MainCtrl', ['$route', '$routeParams', '$location', function ($route, $routeParams, $location) { this.$route = $route; this.$location = $location; this.$routeParams = $routeParams; console.log(this.$routeParams); } ]) .controller("CreateGrids", ['$routeParams', '$scope', '$http', 'setup', 'server', 'gridservice', function ($routeParams, $scope, $http, setup, servers, gridservice) { this.name = 'CreateGrids'; this.params = $routeParams; console.log($routeParams); ... }]) .controller("ServerRepeat", ['$scope', 'servers', 'setup', function ($scope, servers, setup) { ... } }]); 将使用256位加密。但是在节点中,您需要适当地调整密码名称,因为节点不会执行PHP所做的那种“自动调整”。

答案 2 :(得分:0)

在nodejs中的

- 密码必须是'二进制'编码的字符串或缓冲区。在PHP中,不推荐使用的@mcrypt_ecb期望一个键是一个字符串