【发布时间】:2016-11-17 20:13:23
【问题描述】:
我有一个 C# 应用程序,它使用以下方法对数据库中的密码进行加密和解密:
public static string Encrypt(string input, string key)
{
TripleDESCryptoServiceProvider tripleDES = new TripleDESCryptoServiceProvider();
tripleDES.Key = UTF8Encoding.UTF8.GetBytes(key);
tripleDES.Mode = CipherMode.ECB;
tripleDES.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = tripleDES.CreateEncryptor();
byte[] inputArray = UTF8Encoding.UTF8.GetBytes(input);
byte[] resultArray = cTransform.TransformFinalBlock(inputArray, 0, inputArray.Length);
tripleDES.Clear();
return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
public static string Decrypt(string input, string key)
{
byte[] inputArray = Convert.FromBase64String(input);
TripleDESCryptoServiceProvider tripleDES = new TripleDESCryptoServiceProvider();
tripleDES.Key = UTF8Encoding.UTF8.GetBytes(key);
tripleDES.Mode = CipherMode.ECB;
tripleDES.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = tripleDES.CreateDecryptor();
byte[] resultArray = cTransform.TransformFinalBlock(inputArray, 0, inputArray.Length);
tripleDES.Clear();
return UTF8Encoding.UTF8.GetString(resultArray);
}
因此,如果我使用密钥0123456789012345 加密密码testing,那么结果将是+dc6bsOFg00=。
现在我必须从 NodeJS 应用程序中读取这些密码(使用 CryptoJS),但我不知道该怎么做,因为在 C# 中加密是面向字节的(请注意,在input 和 key 的代码都转换为 byte[]),而在 CryptoJS 中它更面向字符串。
我尝试使用这个 JavaScript 函数但没有成功:
var CryptoJS = require("crypto-js");
function decrypt(input, key) {
var inputArray = new Buffer(input, 'base64');
var inputString = inputArray.toString();
var resultArray = CryptoJS.TripleDES.decrypt(inputString, key, {'mode': CryptoJS.mode.ECB, 'pad': CryptoJS.pad.Pkcs7});
return resultArray.toString();
}
console.log(decrypt("+dc6bsOFg00=", "0123456789012345"));
更新:我知道加密密码是个坏主意,而且 Triple DES 不是最好的算法,但是 C# 应用程序无法修改(在至少现在不是),所以我无法更改密码的加密方式,我必须照原样阅读它们。
【问题讨论】:
-
不要加密密码,当攻击者得到数据库时,他也会得到加密密钥。使用随机盐在 HMAC 上迭代大约 100 毫秒,然后将盐与哈希一起保存。使用 password_hash、PBKDF2、Bcrypt 等函数和类似函数。关键是让攻击者花费大量时间通过蛮力寻找密码。
-
最好不要使用 3DES,而是使用 AES。 3DES 密钥是 24 字节,问题中的密钥是 16 字节。不要使用 ECB 模式,它不安全,请参阅ECB mode,向下滚动到 Penguin。
-
你最好只使用内置的
crypto模块而不是第三方模块。 -
调用
inputArray.toString()时,默认使用UTF-8编码。也许这应该是inputArray.toString('binary')? -
没必要,你已经给出了你的建议,没必要钻研它。让我们保持积极的态度,唯一的结果是在 cmets 中进行了长时间的讨论,无处可去(是的,我去过那里)。我猜@RogerN 已经搞定了。
标签: c# .net node.js encryption cryptojs