繁体   English   中英

在PowerShell中以十六进制为字符串,即python方式

[英]Hex to string, the python way, in powershell

也许是一个奇怪的问题,但我正在尝试复制一个python示例,他们从一系列参数创建HMAC SHA256哈希。

我遇到了一个问题,我应该将十六进制中的api键转换为ascii并将其用作秘密,但我不能让输出与python相同。

>>> import hmac
>>> import hashlib
>>> apiKey = "76b02c0c4543a85e45552466694cf677937833c9cce87f0a628248af2d2c495b"
>>> apiKey.decode('hex')
'v\xb0,\x0cEC\xa8^EU$fiL\xf6w\x93x3\xc9\xcc\xe8\x7f\nb\x82H\xaf-,I['

如果我在网上理解了这个材料,那么它应该代表ascii字符中的十六进制字符串。

现在来到powershell脚本:

$apikey = '76b02c0c4543a85e45552466694cf677937833c9cce87f0a628248af2d2c495b';

$hexstring = ""

for($i=0; $i -lt $apikey.Length;$i=$i+2){
    $hexelement = [string]$apikey[$i] + [string]$apikey[$i+1]
    $hexstring += [CHAR][BYTE][CONVERT]::toint16($hexelement,16)
}

这输出如下:

v°,♀EC¨^EU$fiLöw?x3ÉÌè⌂
b?H¯-,I[

它们几乎相同,但并不完全,并且在HMAC中使用它们作为秘密会产生不同的结果。 有任何想法吗?

陈述显而易见:这个例子中的关键不是真正的关键。

更新:它们看起来或多或少相同,但输出的编码是不同的。 我还在多个在线函数中验证了十六进制到ASCII,而powershell版本似乎是正确的。

有谁知道如何比较两种不同的输出?

更新2:我将每个字符转换为整数,Python和Powershell都生成相同的数字,即内容应该相同。

附加脚本

电源外壳:

Function generateToken {

    Param($apikey, $url, $httpMethod, $queryparameters=$false, $postData=$false)


    #$timestamp = [int]((Get-Date -UFormat %s).Replace(",", "."))
    $timestamp = "1446128942"

    $datastring = $httpMethod + $url

    if($queryparameters){ $datastring += $queryparameters }
    $datastring += $timestamp
    if($postData){ $datastring += $postData }


    $hmacsha = New-Object System.Security.Cryptography.HMACSHA256

    $apiAscii = HexToString -hexstring $apiKey

    $hmacsha.key = [Text.Encoding]::ASCII.GetBytes($apiAscii)
    $signature = $hmacsha.ComputeHash([Text.Encoding]::ASCII.GetBytes($datastring))
    $signature
}

Function HexToString {

    Param($hexstring)

    $asciistring = ""

    for($i=0; $i -lt $hexstring.Length;$i=$i+2){
        $hexelement = [string]$hexstring[$i] + [string]$hexstring[$i+1]
        $asciistring += [CHAR][BYTE][CONVERT]::toint16($hexelement,16)
    }

    $asciistring
}

Function TokenToHex {

    Param([array]$Token)

    $hexhash = ""

    Foreach($element in $Token){
        $hexhash += '{0:x}' -f $element
    }

    $hexhash
}


$apiEndpoint = "http://test.control.llnw.com/traffic-reporting-api/v1"
#what you see in Control on Edit My Profile page#
$apikey = '76b02c0c4543a85e45552466694cf677937833c9cce87f0a628248af2d2c495b';
$queryParameters = "shortname=bulkget&service=http&reportDuration=day&startDate=2012-01-01"
$postData = "{param1: 123, param2: 456}"

$token = generateToken -uri $apiEndpoint -httpMethod "GET" -queryparameters $queryParameters, postData=postData, -apiKey $apiKey
TokenToHex -Token $token

蟒蛇:

import hashlib
import hmac
import time
try: import simplejson as json
except ImportError: import json
class HMACSample:
        def generateSecurityToken(self, url, httpMethod, apiKey, queryParameters=None, postData=None):
                #timestamp = str(int(round(time.time()*1000)))
                timestamp = "1446128942"
                datastring = httpMethod + url
                if queryParameters != None : datastring += queryParameters
                datastring += timestamp
                if postData != None : datastring += postData
                token = hmac.new(apiKey.decode('hex'), msg=datastring, digestmod=hashlib.sha256).hexdigest()
                return token
if __name__ == '__main__':
        apiEndpoint = "http://test.control.llnw.com/traffic-reporting-api/v1"
        #what you see in Control on Edit My Profile page#
        apiKey = "76b02c0c4543a85e45552466694cf677937833c9cce87f0a628248af2d2c495b";
        queryParameters = "shortname=bulkget&service=http&reportDuration=day&startDate=2012-01-01"
        postData = "{param1: 123, param2: 456}"
        tool = HMACSample()
        hmac = tool.generateSecurityToken(url=apiEndpoint, httpMethod="GET", queryParameters=queryParameters, postData=postData, apiKey=apiKey)
        print json.dumps(hmac, indent=4)

带有“test”的apiKey而不是转换后的十六进制到ASCII字符串输出相同的值,这使我怀疑转换是问题所在。 现在我不知道该相信什么了。

/帕特里克

ASCII编码支持此代码点范围为0-127的字符。 这个范围之外的任何字符,用字节63编码,对应于? ,以防您将字节数组解码回字符串。 因此,使用您的代码,您可以通过对其应用ASCII编码来破坏密钥。 但如果你想要的是一个字节数组,那你为什么要做Hex String -> ASCII String -> Byte Array而不只是Hex String -> Byte Array

以下是与Python代码生成相同结果的PowerShell代码:

function GenerateToken {
    param($apikey, $url, $httpMethod, $queryparameters, $postData)

    $datastring = -join @(
        $httpMethod
        $url
        $queryparameters
        #[DateTimeOffset]::Now.ToUnixTimeSeconds()
        1446128942
        $postData
    )

    $hmacsha = New-Object System.Security.Cryptography.HMACSHA256

    $hmacsha.Key = @($apikey -split '(?<=\G..)(?=.)'|ForEach-Object {[byte]::Parse($_,'HexNumber')})

    [BitConverter]::ToString($hmacsha.ComputeHash([Text.Encoding]::UTF8.GetBytes($datastring))).Replace('-','').ToLower()
}

$apiEndpoint = "http://test.control.llnw.com/traffic-reporting-api/v1"
#what you see in Control on Edit My Profile page#
$apikey = '76b02c0c4543a85e45552466694cf677937833c9cce87f0a628248af2d2c495b';
$queryParameters = "shortname=bulkget&service=http&reportDuration=day&startDate=2012-01-01"
$postData = "{param1: 123, param2: 456}"

GenerateToken -url $apiEndpoint -httpMethod "GET" -queryparameters $queryParameters -postData $postData -apiKey $apiKey

我还修复了PowerShell代码中的一些其他错误。 特别是, GenerateToken函数调用的参数。 另外,我将ASCII更改为UTF8以进行$datastring编码。 如果所有字符都在ASCII范围内,UTF8会产生完全相同的字节,因此在您的情况下无关紧要。 但是如果你想在$datastring使用ASCII范围以外的字符,那么你应该选择相同的编码,就像你在Python中使用的那样,否则你将得不到相同的结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM