我怎样才能从 DecryptStringFromBytes_Aes 获得与我在 .NET C# 中但在 Node js 中相同的结果?
How can I get the same result from DecryptStringFromBytes_Aes that I have in .NET C # but in Node js?
我需要在 Node js 中获取与我在 .NET C 中从我的网站获取的解密值相同的值#
我在 .NET C# class 中称为 Crypto 的代码是:
private static readonly string key = "Z8,omB0pxZwñ3h9s";
public string Encrypt(string data)
{
string encData = null;
byte[][] keys = GetHashKeys(key);
try
{
encData = EncryptStringToBytes_Aes(data, keys[0], keys[1]);
return encData;
}
catch (CryptographicException) {
return null;
}
catch (ArgumentNullException) {
return null;
}
}
public string Decrypt(string data)
{
string decData = null;
byte[][] keys = GetHashKeys(key);
try
{
decData = DecryptStringFromBytes_Aes(data, keys[0], keys[1]);
}
catch (CryptographicException) { }
catch (ArgumentNullException) { }
return decData;
}
private byte[][] GetHashKeys(string key)
{
byte[][] result = new byte[2][];
Encoding enc = Encoding.UTF8;
SHA256 sha2 = new SHA256CryptoServiceProvider();
byte[] rawKey = enc.GetBytes(key);
byte[] rawIV = enc.GetBytes(key);
byte[] hashKey = sha2.ComputeHash(rawKey);
byte[] hashIV = sha2.ComputeHash(rawIV);
Array.Resize(ref hashIV, 16);
result[0] = hashKey;
result[1] = hashIV;
return result;
}
//source: https://msdn.microsoft.com/de-de/library/system.security.cryptography.aes(v=vs.110).aspx
private static string EncryptStringToBytes_Aes(string plainText, byte[] Key, byte[] IV)
{
if (plainText == null || plainText.Length <= 0)
throw new ArgumentNullException("plainText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("IV");
byte[] encrypted;
using (AesManaged aesAlg = new AesManaged())
{
aesAlg.Key = Key;
aesAlg.IV = IV;
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt =
new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}
return Convert.ToBase64String(encrypted);
}
//source: https://msdn.microsoft.com/de-de/library/system.security.cryptography.aes(v=vs.110).aspx
private static string DecryptStringFromBytes_Aes(string cipherTextString, byte[] Key, byte[] IV)
{
byte[] cipherText = Convert.FromBase64String(cipherTextString);
if (cipherText == null || cipherText.Length <= 0)
throw new ArgumentNullException("cipherText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("IV");
string plaintext = null;
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = Key;
aesAlg.IV = IV;
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
{
using (CryptoStream csDecrypt =
new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
return plaintext;
}
我现在在 Node js 中拥有的是:
var sys = require ('sys'),
url = require('url'),
http = require('http'),
qs = require('querystring');
crypto = require('crypto-js');
var express = require('express');
var app = express();
var sql = require('mssql');
const getConn = require('./configVariables');
var config={
server : getConn.getServer(),
database : getConn.getDatabase(),
user : getConn.getUser(),
password : getConn.getPass(),
port:getConn.getPort(),
options: {
encrypt: false
}
};
http.createServer(function (req, res) {
try{
res.writeHead(200, {"Content-Type": "text/html;charset=UTF-8"});
var key = "Z8,omB0pxZwñ3h9s";
var secret = "ZZZZZZ";
e1 = crypto.AES.encrypt(secret, key, {mode: crypto.mode.CBC, padding: crypto.pad.Pkcs7});
console.log("key: " + crypto.enc.Base64.stringify(e1.key));
console.log("iv: " + crypto.enc.Base64.stringify(e1.iv));
console.log("salt: " + crypto.enc.Base64.stringify(e1.salt));
console.log("ciphertext: " + crypto.enc.Base64.stringify(e1.ciphertext));
p = crypto.AES.decrypt(e1, key, {mode: crypto.mode.CBC, padding: crypto.pad.Pkcs7});
console.log("decrypted: " + crypto.enc.Utf8.stringify(p));
var isResponse = JSON.stringify({StatusCode:"200", info:"true", values:p})
res.end(isResponse);
}catch(err){
var errorResponse = JSON.stringify({StatusCode:"400", Descripcion:"ERROR: " + err})
res.end(errorResponse);
}
}).listen(process.env.PORT);
如果我在 .NET 中加密,变量 ZZZZZZ 会给出我需要的结果。
但是在 Node js 中虽然结果可能有点相似,但它与我在 .NET 中得到的结果不同,我真的需要加密和解密的结果完全相同。
拜托,我需要帮助。我完全不懂什么是加密
问题不仅仅是因为 IV 不同。我在下面提供了更多详细信息:
在 .NET C# 中,hashKey 是一个 32 字节的数组,它来自一个 16 字节的文本键字符串。但是hashIV是一个数组,相当于hashKey数组的前半部分。
所以在Node.js中使用的算法是'aes-256-cbc'为keystring和IV变量分配每个对应的Buffer.from字节,这必须与C#中的相同.
接下来我保留给出相同结果的 Node.js 解决方案。
const crypto = require('crypto');
algorithm = "aes-256-cbc",
keystring = Buffer.from([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]),
iv = Buffer.from([ 1, 2, 3, 4, 5, ,6 ,7 ,8 9, 10, 11, 12, 13, 14, 15, 16]);
inputEncoding = 'utf8',
outputEncoding = 'base64';
function Encrypt(text) {
let cipher = crypto.createCipheriv(algorithm,keystring, iv);
let encrypted = cipher.update(text, inputEncoding, outputEncoding)
encrypted += cipher.final(outputEncoding);
return encrypted;
}
function Decrypt(encrypted) {
let decipher = crypto.createDecipheriv(algorithm,keystring, iv)
let dec = decipher.update(encrypted, outputEncoding, inputEncoding)
dec += decipher.final(inputEncoding);
return dec;
}
var enc = Encrypt("ZZZZZZ");
console.log("enc: " + enc);
var dec = Decrypt(enc);
console.log("dec: " + dec);
答案中指定的字节并不是真正在 C# 中捕获的字节,但我将它们留作示例。
如果对某人有效,那就太好了。
我需要在 Node js 中获取与我在 .NET C 中从我的网站获取的解密值相同的值#
我在 .NET C# class 中称为 Crypto 的代码是:
private static readonly string key = "Z8,omB0pxZwñ3h9s";
public string Encrypt(string data)
{
string encData = null;
byte[][] keys = GetHashKeys(key);
try
{
encData = EncryptStringToBytes_Aes(data, keys[0], keys[1]);
return encData;
}
catch (CryptographicException) {
return null;
}
catch (ArgumentNullException) {
return null;
}
}
public string Decrypt(string data)
{
string decData = null;
byte[][] keys = GetHashKeys(key);
try
{
decData = DecryptStringFromBytes_Aes(data, keys[0], keys[1]);
}
catch (CryptographicException) { }
catch (ArgumentNullException) { }
return decData;
}
private byte[][] GetHashKeys(string key)
{
byte[][] result = new byte[2][];
Encoding enc = Encoding.UTF8;
SHA256 sha2 = new SHA256CryptoServiceProvider();
byte[] rawKey = enc.GetBytes(key);
byte[] rawIV = enc.GetBytes(key);
byte[] hashKey = sha2.ComputeHash(rawKey);
byte[] hashIV = sha2.ComputeHash(rawIV);
Array.Resize(ref hashIV, 16);
result[0] = hashKey;
result[1] = hashIV;
return result;
}
//source: https://msdn.microsoft.com/de-de/library/system.security.cryptography.aes(v=vs.110).aspx
private static string EncryptStringToBytes_Aes(string plainText, byte[] Key, byte[] IV)
{
if (plainText == null || plainText.Length <= 0)
throw new ArgumentNullException("plainText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("IV");
byte[] encrypted;
using (AesManaged aesAlg = new AesManaged())
{
aesAlg.Key = Key;
aesAlg.IV = IV;
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt =
new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}
return Convert.ToBase64String(encrypted);
}
//source: https://msdn.microsoft.com/de-de/library/system.security.cryptography.aes(v=vs.110).aspx
private static string DecryptStringFromBytes_Aes(string cipherTextString, byte[] Key, byte[] IV)
{
byte[] cipherText = Convert.FromBase64String(cipherTextString);
if (cipherText == null || cipherText.Length <= 0)
throw new ArgumentNullException("cipherText");
if (Key == null || Key.Length <= 0)
throw new ArgumentNullException("Key");
if (IV == null || IV.Length <= 0)
throw new ArgumentNullException("IV");
string plaintext = null;
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = Key;
aesAlg.IV = IV;
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
{
using (CryptoStream csDecrypt =
new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
return plaintext;
}
我现在在 Node js 中拥有的是:
var sys = require ('sys'),
url = require('url'),
http = require('http'),
qs = require('querystring');
crypto = require('crypto-js');
var express = require('express');
var app = express();
var sql = require('mssql');
const getConn = require('./configVariables');
var config={
server : getConn.getServer(),
database : getConn.getDatabase(),
user : getConn.getUser(),
password : getConn.getPass(),
port:getConn.getPort(),
options: {
encrypt: false
}
};
http.createServer(function (req, res) {
try{
res.writeHead(200, {"Content-Type": "text/html;charset=UTF-8"});
var key = "Z8,omB0pxZwñ3h9s";
var secret = "ZZZZZZ";
e1 = crypto.AES.encrypt(secret, key, {mode: crypto.mode.CBC, padding: crypto.pad.Pkcs7});
console.log("key: " + crypto.enc.Base64.stringify(e1.key));
console.log("iv: " + crypto.enc.Base64.stringify(e1.iv));
console.log("salt: " + crypto.enc.Base64.stringify(e1.salt));
console.log("ciphertext: " + crypto.enc.Base64.stringify(e1.ciphertext));
p = crypto.AES.decrypt(e1, key, {mode: crypto.mode.CBC, padding: crypto.pad.Pkcs7});
console.log("decrypted: " + crypto.enc.Utf8.stringify(p));
var isResponse = JSON.stringify({StatusCode:"200", info:"true", values:p})
res.end(isResponse);
}catch(err){
var errorResponse = JSON.stringify({StatusCode:"400", Descripcion:"ERROR: " + err})
res.end(errorResponse);
}
}).listen(process.env.PORT);
如果我在 .NET 中加密,变量 ZZZZZZ 会给出我需要的结果。 但是在 Node js 中虽然结果可能有点相似,但它与我在 .NET 中得到的结果不同,我真的需要加密和解密的结果完全相同。
拜托,我需要帮助。我完全不懂什么是加密
问题不仅仅是因为 IV 不同。我在下面提供了更多详细信息:
在 .NET C# 中,hashKey 是一个 32 字节的数组,它来自一个 16 字节的文本键字符串。但是hashIV是一个数组,相当于hashKey数组的前半部分。
所以在Node.js中使用的算法是'aes-256-cbc'为keystring和IV变量分配每个对应的Buffer.from字节,这必须与C#中的相同.
接下来我保留给出相同结果的 Node.js 解决方案。
const crypto = require('crypto');
algorithm = "aes-256-cbc",
keystring = Buffer.from([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]),
iv = Buffer.from([ 1, 2, 3, 4, 5, ,6 ,7 ,8 9, 10, 11, 12, 13, 14, 15, 16]);
inputEncoding = 'utf8',
outputEncoding = 'base64';
function Encrypt(text) {
let cipher = crypto.createCipheriv(algorithm,keystring, iv);
let encrypted = cipher.update(text, inputEncoding, outputEncoding)
encrypted += cipher.final(outputEncoding);
return encrypted;
}
function Decrypt(encrypted) {
let decipher = crypto.createDecipheriv(algorithm,keystring, iv)
let dec = decipher.update(encrypted, outputEncoding, inputEncoding)
dec += decipher.final(inputEncoding);
return dec;
}
var enc = Encrypt("ZZZZZZ");
console.log("enc: " + enc);
var dec = Decrypt(enc);
console.log("dec: " + dec);
答案中指定的字节并不是真正在 C# 中捕获的字节,但我将它们留作示例。
如果对某人有效,那就太好了。