2012-01-17 71 views
1

tripledes encryption not yielding same results in PHP and C#这个C#加密代码在NodeJS中看起来像什么?

public static string Encrypt(string toEncrypt, string key, bool useHashing) 
    {  
     byte[] keyArray;  
     byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);  

     if (useHashing)  
     {   
      MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider(); 
      keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));  
     }  
     else 
      keyArray = UTF8Encoding.UTF8.GetBytes(key);  

     TripleDESCryptoServiceProvider tdes 
      = new TripleDESCryptoServiceProvider(); 
     tdes.Key = keyArray;  
     tdes.Mode = CipherMode.ECB;  
     tdes.Padding = PaddingMode.PKCS7;  

     ICryptoTransform cTransform = tdes.CreateEncryptor();  
     byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, 
      toEncryptArray.Length);  
     return Convert.ToBase64String(resultArray, 0, resultArray.Length); 
    } 

上述职位和代码有位漂亮的直线前进(或因此我认为)逻辑加密/用3DES和私钥解密的字符串。

我发现了几个例子,说明如何在nodejs中使用crypt库实现类似的东西,但是我迄今为止试过的所有东西都产生了垃圾(并且正确如此)。

想法?

UPDATE1:

这里是有点C#代码来生成我的工作数据:

String key = "abcdefghijklmnop"; 
    String text = "12345"; 
    String encrypted = Encrypt(text, key, false); 
    //Returns "QI3I65+aWSk=" 

而这里的的NodeJS代码,我正在同的最新版本:

var crypto = require('crypto'); 
    var key = 'abcdefghijklmnop'; 
    var encrypted = 'QI3I65+aWSk='; 
    var expected = '12345'; 

    var algs = [ 'des3', 'des-ede', 'des-ede3', 'des-ecb', 'aes-128-ecb']; 
    for(var i in algs) 
    { 
     var decipher = crypto.createDecipher(algs[i], key); 
     var result = '' 
     result += decipher.update(encrypted, 'hex', 'binary'); 
     result += decipher.final('binary'); 

     console.log('Algorithm: ' + algs[i] 
     + ', Matched Expected: ' + (result === expected)); 
    } 

..返回

Algorithm: des3, Matched Expected: false 
    Algorithm: des-ede, Matched Expected: false 
    Algorithm: des-ede3, Matched Expected: false 
    Algorithm: des-ecb, Matched Expected: false 
    Algorithm: aes-128-ecb, Matched Expected: false 

我不清楚究竟使用哪种算法(我的列表在以前的尝试中显着更长),现在我确定要使用什么编码组合(二进制/十六进制)。

再次感谢。

UPDATE2: 复制加密方法从引用的帖子:

tripledes encryption not yielding same results in PHP and C#

+0

可以ypu发布你的尝试。 – fent 2012-01-17 04:50:36

+0

@DeaDEnD:我添加了几个样本来处理。希望这会给我们更多的工作。谢谢。 – user1153154 2012-01-17 08:25:13

+0

更新了JavaScript代码,因为我试图清理干净的东西,删除了正确的“预期”,并将它用于加密输入和预期输出。该代码已更新,但显然它仍然无法正常工作。 – user1153154 2012-01-17 16:09:39

回答

0

您输入的编码看起来应该是“的base64” ......在你的链接中提到值得注意问题是填充技术也可能有所不同。

1

那么,我花了一段时间才弄清楚这一点。

首先大约DES算法,DES算法需要一个IV(初始向量)来加密,以及所述。未指定时,System.Security.Cryptography中的DES算法将生成IV randomly。当解密时,您需要同时使用密钥IV

这就是为什么你的代码不会有任何效果,为您解密程序只是不知道是什么在加密中使用的IV,并会产生另一个IV本身,这不符合随机一个。

其次你的javascript代码是错误的,在许多地方:

decipher.update(encrypted, 'hex', 'binary') 

其中encrypted不以十六进制,但在base64编码,并且需要将结果输出为Base64,而不是二进制。 阅读document

[ 'DES3', 'DES-EDE', '脱EDE3', 'DES-ECB', 'AES-128-ECB']

,其中所有这些算法是不一样的您使用的加密算法。正如你指定使用CipherMode.ECB这是not recommended和openssh根本不支持,所以它是不可能解密的。

所有加起来,你的代码将无法正常工作。

这是正确的做法:

using System; 
using System.Text; 
using System.Security.Cryptography; 

public class Test 
{ 
    public static string Encrypt(string toEncrypt, string key, bool useHashing) 
    {  
     byte[] keyArray;  
     byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);  

     if (useHashing)  
     {   
      MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider(); 
      keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));  
     }  
     else 
      keyArray = UTF8Encoding.UTF8.GetBytes(key);  

     var tdes = new TripleDESCryptoServiceProvider(); 
     tdes.Key = keyArray;  
     // tdes.Mode = CipherMode.CBC; // which is default  
     // tdes.Padding = PaddingMode.PKCS7; // which is default 

     Console.WriteLine("iv: {0}", Convert.ToBase64String(tdes.IV)); 

     ICryptoTransform cTransform = tdes.CreateEncryptor();  
     byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, 
      toEncryptArray.Length);  
     return Convert.ToBase64String(resultArray, 0, resultArray.Length); 
    } 

    public static void Main() 
    { 
     Console.WriteLine("encrypted as: {0}", Encrypt("12345", "abcdefghijklmnop", false)); 
    } 
} 

其输出

iv: pdMBMjdeFdo= 
encrypted as: 3uDkdT6aQ3c= 

,并使用正确的算法DES-EDE-CBC在node.js中:

var crypto = require('crypto'); 

var alg = 'des-ede-cbc'; 

var key = new Buffer('abcdefghijklmnop', 'utf-8'); 
var iv = new Buffer('pdMBMjdeFdo=', 'base64'); 

var encrypted = new Buffer('3uDkdT6aQ3c=', 'base64'); 
var source = '12345'; 

var cipher = crypto.createCipheriv(alg, key, iv); 
var encoded = cipher.update(source, 'ascii', 'base64'); 
encoded += cipher.final('base64'); 

console.log(encoded, encrypted.toString('base64')); 

var decipher = crypto.createDecipheriv(alg, key, iv); 
var decoded = decipher.update(encrypted, 'binary', 'ascii'); 
decoded += decipher.final('ascii'); 

console.log(decoded, source); 

其输出

3uDkdT6aQ3c= 3uDkdT6aQ3c= 
12345 12345 

现在问题解决了。

相关问题