gpt4 book ai didi

node.js - 在不同于 .net 的 Node 中创建的安全 token

转载 作者:搜寻专家 更新时间:2023-11-01 00:41:19 25 4
gpt4 key购买 nike

我正在尝试实现 reCaptcha Secure Tokens在 nodejs 中。

查看了 Java 中的示例在.NET并为 Node 创建了这个版本:

exports.getSecureToken = function() {
var algorithm = 'aes-128-ecb';
var tokenObj = { session_id: 'ab0069ec-3c2c-436c-868b-43c7a10db229'/*uuid.v4()*/, ts_ms: 1446560931992/*(new Date()).getTime()*/ };
var text = JSON.stringify(tokenObj);

var shaHash = new Buffer(crypto.createHash('sha1').update('6LeyNOTTVALIDH2RLNaivqrrpm2zh56Y3uHqOjFO'/*config.reCAPTCHASecret*/).digest('hex'), 'hex');

var key = shaHash.slice(0, 16);

var cipher = crypto.createCipher(algorithm, key, key);

var encryptedToken = cipher.update(text, 'utf8', 'base64') + cipher.final('base64');

var result = encryptedToken.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');

return result;
};

问题是,在 .NET 中,我得到了一个有效的 token (使用帖子中未包含的正确 key ),但在 Node 中,我为相同的输入获得了不同的 token ,但它不起作用:

.NET - LhPTUELia5vc0X6aDGDtqpsbmB7oqm6vUnzk5BL2auactYXRU5TEUzML8gZ_JubXG07rvJxk1Sb5_a-wqVUGEf_UuO1gGi-WO83yJHOxnjI

Node - EGr7drd1JEylwzLGakZ6dpPRSf2nFdpzHOrJlLZlyHYmVRj5obAw7WjPt4W5l0vsywNEqCQ-2_d7qIZOMiOedianfBrQPOBaOmmq44IOB8Q

我看到 key 和输入在加密之前的那一刻是相同的(在 .NET 和 Node 中),所以问题一定(?)是密码,有什么线索吗?

.NET引用代码:

public static void Main(string[] args)
{
//Your code goes here
Console.WriteLine(EncryptJsonToken(GetJsonToken()));
}

public static string GetJsonToken()
{
//Example: {"session_id": e6e9c56e-a7da-43b8-89fa-8e668cc0b86f,"ts_ms":1421774317718}
string jsonRequest = "{" + string.Format("\"session_id\": {0},\"ts_ms\":{1}", "ab0069ec-3c2c-436c-868b-43c7a10db229", 1446560931992) + "}";
return jsonRequest;
}

public static byte[] getKey()
{
string secretKey = "6LeyNOTTVALIDH2RLNaivqrrpm2zh56Y3uHqOjFO";
SHA1 sha = SHA1.Create();
byte[] dataToHash = Encoding.UTF8.GetBytes(secretKey);
byte[] shaHash = sha.ComputeHash(dataToHash);
byte[] first16OfHash = new byte[16];
Array.Copy(shaHash, first16OfHash, 16);
return first16OfHash;
}

public static byte[] EncryptStringToBytes_Aes(string plainText, byte[] Key, byte[] IV)
{
// Check arguments.
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;
// Create an AesManaged object
// with the specified key and IV.
using (AesManaged aesAlg = new AesManaged())
{
aesAlg.Key = Key;
aesAlg.IV = IV;
aesAlg.Padding = PaddingMode.PKCS7;
aesAlg.Mode = CipherMode.ECB;

// Create a decrytor to perform the stream transform.
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

// Create the streams used for encryption.
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{

//Write all data to the stream.
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}
// Return the encrypted bytes from the memory stream.
return encrypted;
}

public static string EncryptJsonToken(string jsonToken)
{
byte[] encrypted = EncryptStringToBytes_Aes(jsonToken, getKey(), getKey());

//Base64 encode the encrypted data
//Also applys the URL variant of base64 encoding, unfortunately the HttpServerUtility.UrlTokenEncode(encrypted) seems to truncate the last value from the string so we can't use it?
return Convert.ToBase64String(encrypted, Base64FormattingOptions.None).Replace("=", String.Empty).Replace('+', '-').Replace('/', '_');
}

要在 .NET 中调试:DEMO

最佳答案

你有两个问题:

  • 您正在使用 JSON.stringify() 生成有效的 JSON 字符串,但 C# 代码中的 GetJsonToken() 方法不会生成一个有效的 JSON 字符串。 UUID 缺少 " 并且由于某种原因 session_id 键与其值之间有一个空格。您必须在 JavaScript 中反射(reflect)这些差异:

    var uuidToken = "ab0069ec-3c2c-436c-868b-43c7a10db229";
    var time = 1446560931992;
    var text = "{\"session_id\": "+uuidToken+",\"ts_ms\":"+time+"}";
  • 没有这样的函数 crypto.createCipher(algorithm, key, key)。但是有 crypto.createCipheriv(algorithm, key, iv)createCipher(algorithm, password) 如果您有密码而不是您没有的 key ,则可以使用。由于 ECB 模式没有 IV,您可以传入一个空(二进制)字符串作为 IV。

完整代码:

var crypto = require("crypto");

var algorithm = 'aes-128-ecb';

var uuidToken = "ab0069ec-3c2c-436c-868b-43c7a10db229";
var time = 1446560931992;
var text = "{\"session_id\": "+uuidToken+",\"ts_ms\":"+time+"}";
console.log("Token: " + text);

var shaHash = crypto.createHash('sha1').update('6LeyNOTTVALIDH2RLNaivqrrpm2zh56Y3uHqOjFO').digest();
var key = shaHash.slice(0, 16);

var cipher = crypto.createCipheriv(algorithm, key, "");
var encryptedToken = cipher.update(text, 'utf8', 'base64') + cipher.final('base64');

var result = encryptedToken.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');

console.log("result: " + result);
console.log("expected: LhPTUELia5vc0X6aDGDtqpsbmB7oqm6vUnzk5BL2auactYXRU5TEUzML8gZ_JubXG07rvJxk1Sb5_a-wqVUGEf_UuO1gGi-WO83yJHOxnjI");

输出:

Token: {"session_id": ab0069ec-3c2c-436c-868b-43c7a10db229,"ts_ms":1446560931992}result:   LhPTUELia5vc0X6aDGDtqpsbmB7oqm6vUnzk5BL2auactYXRU5TEUzML8gZ_JubXG07rvJxk1Sb5_a-wqVUGEf_UuO1gGi-WO83yJHOxnjIexpected: LhPTUELia5vc0X6aDGDtqpsbmB7oqm6vUnzk5BL2auactYXRU5TEUzML8gZ_JubXG07rvJxk1Sb5_a-wqVUGEf_UuO1gGi-WO83yJHOxnjI

关于node.js - 在不同于 .net 的 Node 中创建的安全 token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33503595/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com