将perl哈希转换为C#

时间:2016-03-18 07:52:27

标签: c# perl hash hex

我有一个用于验证帖子消息的哈希和hexes参数的perl脚本。我必须在C#中编写相同的程序,但到目前为止还没有运气。这是perl代码:

my $sha1_user_pwd = sha1_base64($user_pwd);
$sha1_user_pwd .= '=' x (4 - (length($sha1_user_pwd) % 4));

my $sha1_ws_pwd = sha1_base64($ws_pwd);
$sha1_ws_pwd    .= '=' x (4 - (length($sha1_ws_pwd) % 4)); # Padding; if neccesary.

my $utc_time = time;

my ($utc_time, $kontekst, $projekt, $userid, $sha1_user_pwd) = @_;
my $auth = calc_hmac($sha1_ws_pwd, $sha1_user_pwd, $utc_time, $kontekst, $projekt, $userid);

sub calc_hmac {
    my ($sha1_ws_pwd, $sha1_user_pwd, $utc_time, $kontekst, $projekt, $userid) = @_;
    my $hmac = Digest::HMAC_SHA1->new($sha1_ws_pwd . $sha1_user_pwd);
    $hmac->add($utc_time . $kontekst . $projekt . $userid);
    return $hmac->hex digest;
}

$ kontekst,$ projekt,$ userid和$ ws_userid都是原始字符串值。

最后发布消息(我已插入换行符以便于阅读)

wsBrugerid=$ws_userid
&UTCtime=$utc_time
&kontekst=$kontekst
&projekt=$projekt
&BrugerId=$userid
&Auth=$auth

我试图用C#复制程序:

    const string APP_KEY = "APP_KEY";
    Encoding enc = Encoding.ASCII;
    HMACSHA1 hmac = new HMACSHA1(enc.GetBytes(APP_KEY));
    hmac.Initialize();

    string ws_user      = "ws_usr";
    string ws_password  = "ws_pwd";

    DateTime epochStart = new System.DateTime(1970, 1, 1, 8, 0, 0, System.DateTimeKind.Utc);
    int time            = (int) (System.DateTime.UtcNow - epochStart).TotalSeconds;
    string context      = "context";
    string project      = "project";

    string user_id      = "user_id";
    string user_pwd     = "user_pwd";

    string sha1_ws_pwd  = System.Convert.ToBase64String(hmac.ComputeHash(enc.GetBytes(ws_password)));
    sha1_ws_pwd += '=';

    string sha1_user_pwd = System.Convert.ToBase64String(hmac.ComputeHash(enc.GetBytes(user_pwd)));
    sha1_user_pwd += '=';

    string k0           = sha1_ws_pwd + sha1_user_pwd;
    string m0           = time + context + project + user_id;
    byte[] _auth        = hmac.ComputeHash(enc.GetBytes(k0 + m0));
    string auth         = BitConverter.ToString(_auth).Replace("-", string.Empty);

    string url = "https://auth.emu.dk/mauth?wsBrugerid="+ws_user+
    "&UTCtime="+time+
    "&kontekst="+context+
    "&projekt="+project+
    "&BrugerId="+user_id+
    "&Auth="+auth;

    print("AuthenticationManager, url: " + url);

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    request.Method = "POST";

    Encoding encoding = System.Text.Encoding.GetEncoding("utf-8");

    String responseString = "";

    HttpWebResponse response = (HttpWebResponse) request.GetResponse();
    using (Stream stream = response.GetResponseStream()){
        StreamReader reader = new StreamReader(stream, encoding);
        responseString = reader.ReadToEnd();
    }

    JSONNode json = JSON.Parse(responseString);
    print("AuthenticationManager, response: " + json[0] + " - " + json[1]);

我无权访问提供响应的服务器或应用程序。当然,真正的价值观已被交换。例如,APP_KEY不是“APP_KEY”,而是用于验证的实际字符串。我知道数据是正确的,因为它传递了perl脚本。 我非常感谢我能得到的任何帮助。

1 个答案:

答案 0 :(得分:0)

我明白了!

现在不是时候,而是hmac键。我使用APP_KEY作为键,但perl脚本使用sha1_ws_pwd + sha1_user_pwd。 (这是一个愚蠢的错误......)

my $hmac = Digest::HMAC_SHA1->new($sha1_ws_pwd . $sha1_user_pwd);

最后我还要在C#中小写auth。所以C#的变化是:

// sha1 hash the passwords
string sha1_ws_pwd   = System.Convert.ToBase64String(sha1.ComputeHash(enc.GetBytes(ws_password)));
string sha1_user_pwd = System.Convert.ToBase64String(sha1.ComputeHash(enc.GetBytes(user_pwd)));

…

string k0 = sha1_ws_pwd + sha1_user_pwd;
HMACSHA1 hmac = new HMACSHA1(enc.GetBytes(k0));

…

string auth = BitConverter.ToString(_auth).Replace("-", string.Empty).ToLower(); 

感谢您的时间和答案。