使用哈希进行身份验证

我需要使用我不理解的复杂身份验证过程与 API 建立连接。我知道它涉及多个步骤,我试图模仿它,但我发现文档非常混乱......


这个想法是,我向一个端点发出请求,该端点将向我返回一个令牌,我需要使用它来建立websocket连接。


我确实得到了一个代码示例,它是在Python中,我不知道它的语法,但我可以把它作为一个指南,把它转换为C#语法。


这是蟒蛇代码示例:


import time, base64, hashlib, hmac, urllib.request, json


api_nonce = bytes(str(int(time.time()*1000)), "utf-8")

api_request = urllib.request.Request("https://www.website.com/getToken", b"nonce=%s" % api_nonce)

api_request.add_header("API-Key", "API_PUBLIC_KEY")

api_request.add_header("API-Sign", base64.b64encode(hmac.new(base64.b64decode("API_PRIVATE_KEY"), b"/getToken" + hashlib.sha256(api_nonce + b"nonce=%s" % api_nonce).digest(), hashlib.sha512).digest()))


print(json.loads(urllib.request.urlopen(api_request).read())['result']['token'])

所以我试图把它转换成C#,这是我到目前为止得到的代码:


    static string apiPublicKey = "API_PUBLIC_KEY";

    static string apiPrivateKey = "API_PRIVATE_KEY";

    static string endPoint = "https://www.website.com/getToken";


    private void authenticate()

    {

        using (var client = new HttpClient())

        {

            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;



            // CREATE THE URI

            string uri = "/getToken";



            // CREATE THE NONCE

            /// NONCE = unique identifier which must increase in value with each API call

            /// in this case we will be using the epoch time

            DateTime baseTime = new DateTime(1970, 1, 1, 0, 0, 0);

            TimeSpan epoch = CurrentTime - baseTime;

            Int64 nonce = Convert.ToInt64(epoch.TotalMilliseconds);



            // CREATE THE DATA

            string data = string.Format("nonce={0}", nonce);


            // CALCULATE THE SHA256 OF THE NONCE

            string sha256 = SHA256_Hash(data);



            // DECODE THE PRIVATE KEY

            byte[] apiSecret = Convert.FromBase64String(apiPrivateKey);




            // HERE IS THE HMAC CALCULATION


        }

    }


所以下一部分是我真正挣扎的地方。需要做一些HMAC计算,但我完全迷失在那里。


慕的地6264312
浏览 203回答 1
1回答

www说

这里的主要任务是反转SHA-512 HMAC计算。使用日期时间偏移.Now.ToUnix时间毫秒获取API,它将返回一个Unix时间戳毫秒值。然后,这一切都归结为串联字节数组并生成哈希值。我使用硬编码时间只是为了演示结果;每次计算密钥时,您必须取消注释才能获得当前的Unix时间戳毫秒。API-Signnonceapi_noncestring ApiNonce = DateTimeOffset.Now.ToUnixTimeMillisecondsAPI-Sign蟒蛇生成:API-Signimport time, base64, hashlib, hmac, urllib.request, json# Hardcoce API_PRIVATE_KEY base 64 valueAPI_PRIVATE_KEY = base64.encodebytes(b"some_api_key_1234")# time_use = time.time()# Hardcode the time so we can confirm the same result to C#time_use = 1586096626.919api_nonce = bytes(str(int(time_use*1000)), "utf-8")print("API nonce: %s" % api_nonce)api_request = urllib.request.Request("https://www.website.com/getToken", b"nonce=%s" % api_nonce)api_request.add_header("API-Key", "API_PUBLIC_KEY_1234")print("API_PRIVATE_KEY: %s" % API_PRIVATE_KEY)h256Dig = hashlib.sha256(api_nonce + b"nonce=%s" % api_nonce).digest()api_sign = base64.b64encode(hmac.new(base64.b64decode(API_PRIVATE_KEY), b"/getToken" + h256Dig, hashlib.sha512).digest())# api_request.add_header("API-Sign", api_sign)# print(json.loads(urllib.request.urlopen(api_request).read())['result']['token'])print("API-Sign: %s" % api_sign)将输出:API nonce: b'1586096626919'API_PRIVATE_KEY: b'c29tZV9hcGlfa2V5XzEyMzQ=\n'API-Sign: b'wOsXlzd3jOP/+Xa3AJbfg/OM8wLvJgHATtXjycf5EA3tclU36hnKAMMIu0yifznGL7yhBCYEwIiEclzWvOgCgg=='C# 生成:API-Signstatic string apiPublicKey = "API_PUBLIC_KEY";// Hardcoce API_PRIVATE_KEY base 64 valuestatic string apiPrivateKey = Base64EncodeString("some_api_key_1234");static string endPoint = "https://www.website.com/getToken";public static void Main(){    Console.WriteLine("API-Sign: '{0}'", GenApiSign());}static private string GenApiSign(){    // string ApiNonce = DateTimeOffset.Now.ToUnixTimeMilliseconds().ToString();    // Hardcode the time so we can confirm the same result with Python    string ApiNonce = "1586096626919";    Console.WriteLine("API nonce: {0}", ApiNonce);    Console.WriteLine("API_PRIVATE_KEY: '{0}'", apiPrivateKey);    byte[] ApiNonceBytes = Encoding.Default.GetBytes(ApiNonce);    byte[] h256Dig = GenerateSHA256(CombineBytes(ApiNonceBytes, Encoding.Default.GetBytes("nonce="), ApiNonceBytes));    byte[] h256Token = CombineBytes(Encoding.Default.GetBytes("/getToken"), h256Dig);    string ApiSign = Base64Encode(GenerateSHA512(Base64Decode(apiPrivateKey), h256Token));    return ApiSign;}// Helper functions ___________________________________________________public static byte[] CombineBytes(byte[] first, byte[] second){    byte[] ret = new byte[first.Length + second.Length];    Buffer.BlockCopy(first, 0, ret, 0, first.Length);    Buffer.BlockCopy(second, 0, ret, first.Length, second.Length);    return ret;}public static byte[] CombineBytes(byte[] first, byte[] second, byte[] third){    byte[] ret = new byte[first.Length + second.Length + third.Length];    Buffer.BlockCopy(first, 0, ret, 0, first.Length);    Buffer.BlockCopy(second, 0, ret, first.Length, second.Length);    Buffer.BlockCopy(third, 0, ret, first.Length + second.Length,                     third.Length);    return ret;}public static byte[] GenerateSHA256(byte[] bytes){    SHA256 sha256 = SHA256Managed.Create();    return sha256.ComputeHash(bytes);}public static byte[] GenerateSHA512(byte[] key, byte[] bytes){    var hash = new HMACSHA512(key);    var result = hash.ComputeHash(bytes);    hash.Dispose();    return result;}public static string Base64EncodeString(string plainText){    var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);    return System.Convert.ToBase64String(plainTextBytes);}public static string Base64Encode(byte[] bytes){    return System.Convert.ToBase64String(bytes);}public static byte[] Base64Decode(string base64EncodedData){    var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData);    return base64EncodedBytes;}将输出:API nonce: 1586096626919API_PRIVATE_KEY: 'c29tZV9hcGlfa2V5XzEyMzQ='API-Sign: 'wOsXlzd3jOP/+Xa3AJbfg/OM8wLvJgHATtXjycf5EA3tclU36hnKAMMIu0yifznGL7yhBCYEwIiEclzWvOgCgg=='您可以看到它的工作原理以及此 .NET 小提琴中的结果。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python