2017-08-11 78 views
1

描述:hash_hmac在PHP中,相当于CSHARP 3个PARAMS,JavaScript的

看来我无法弄清楚如何PHP产生如下:

echo hash_hmac("sha1", "what is this", true); 
echo PHP_EOL; // end of line 
echo base64_encode(hash_hmac("sha1", "what is this", true)); 

链接以查看output在线(复制/粘贴需要)。

由于文件说,你需要数据关键适当输出创建SHA1哈希HMAC。

string hash_hmac(string $algo, string $data, string $key [, bool $raw_output = false]) 

我要的是创建精确的输出与CSHARP的JavaScript


尝试:

这很好,当我有数据关键,我可产生IE编程和JavaScript相同的SHA1哈希HMAC。

// PHP 
echo base64_encode(hash_hmac("sha1", "data", "key", true)); 

链接看output在线(需要复制/粘贴)。

// CSharp 
public static void Main(string[] args) 
{ 
    Console.WriteLine(CreatePhpSha1HmacHash("data", "key")); 
} 

public static string CreatePhpSha1HmacHash(string data, string key) 
{ 
    if (data == null) 
    { 
     data = string.Empty; 
    } 

    var encoding = new System.Text.UTF8Encoding(); // It's UTF-8 for my example 

    var keyBytes = encoding.GetBytes(key); 
    var dataBytes = encoding.GetBytes(data); 

    using (var hmac = new System.Security.Cryptography.HMACSHA1(keyBytes)) 
    { 
     var hash = hmac.ComputeHash(dataBytes); 

     return Convert.ToBase64String(hash); 
    } 
} 

链接看output在线(复制/粘贴需要)。

// Javascript 
var hash = CryptoJS.HmacSHA1('data', 'key'); 
var base64 = CryptoJS.enc.Base64.stringify(hash); 

console.log('Sha1 hmac hash: ' + base64); 

链接看到output在线。


问题

如何创建精确的输出时不是使用需要两个参数的描述中显示PHP的例子吗?有人可以向我解释在这种情况下,php正在做什么?


ANSWER

@GentlemanMax:PHP将在内部投TRUE到STRING所以KEY将被转换为“1”为字符串值。当raw_output设置为TRUE时,它输出原始二进制数据。 FALSE输出小写的hexits。


SOLUTION

// CSharp 
public static void Main(string[] args) 
{ 
    // echo base64_encode(hash_hmac("sha1", "what is this", true)); 
    // echo base64_encode(hash_hmac("sha1", "what is this", true, false)); 
    Console.WriteLine(ToBase64EncodedHmacSha1("what is this", "1", false)); 
    Console.WriteLine(ToBase64EncodedHmacSha1("what is this", "1", false.ToString())); 

    // echo base64_encode(hash_hmac("sha1", "what is this", true, true)); 
    Console.WriteLine(ToBase64EncodedHmacSha1("what is this", "1", true)); 
    Console.WriteLine(ToBase64EncodedHmacSha1("what is this", "1", true.ToString())); 
} 

public static string ToBase64EncodedHmacSha1(string data, string key, bool rawOutput = false) 
{ 
    bool result; 

    if (bool.TryParse(key, out result)) 
    { 
     key = result ? 1.ToString() : 0.ToString(); 
    } 

    var keyBytes = Encoding.UTF8.GetBytes(key); 
    var dataBytes = Encoding.UTF8.GetBytes(data); 

    using (var hmac = new HMACSHA1(keyBytes)) 
    { 
     var hash = hmac.ComputeHash(dataBytes); 

     if (rawOutput) 
     { 
      // output: raw binary 
      return Convert.ToBase64String(hash); 
     } 

     // Convert an array of bytes to a string of hex digits. 
     var hex = string.Concat(hash.Select(x => x.ToString("x2").ToLower())); 

     var hexBytes = Encoding.UTF8.GetBytes(hex); 

     // output: lowercase hexits 
     return Convert.ToBase64String(hexBytes); 
    } 
} 

链接看output在线(需要复制/粘贴)。


// Javascript 
function toBase64EncodedHmacSha1(data, key, rawOutput) { 
    // if boolean, cast to string 
    if (typeof(key) === 'boolean') { 
     key = key ? '1' : '0'; 
    } 

    // optional 
    if (typeof(rawOutput) === 'undefined') { 
     rawOutput = false; 
    } 

    // check type 
    if (typeof(rawOutput) !== 'boolean') { 
     throw new Error('Raw output is Boolean value: true/false'); 
    } 

    var hash = CryptoJS.HmacSHA1(data, key); 

    if (rawOutput) { 
     // output: raw binary 
     return CryptoJS.enc.Base64.stringify(hash); 
    } 

    var hex = CryptoJS.enc.Hex.stringify(hash); 
    var wordArray = CryptoJS.enc.Utf8.parse(hex); 

    // output: lowercase hexits 
    return CryptoJS.enc.Base64.stringify(wordArray); 
} 

// echo base64_encode(hash_hmac("sha1", "what is this", true)); 
// echo base64_encode(hash_hmac("sha1", "what is this", true, false)); 
console.log(toBase64EncodedHmacSha1('what is this', true)); 
console.log(toBase64EncodedHmacSha1('what is this', true, false)); 

// echo base64_encode(hash_hmac("sha1", "what is this", true, true)); 
console.log(toBase64EncodedHmacSha1('what is this', true, true)); 

console.log(toBase64EncodedHmacSha1('what is this', true, 'This will throw error')); 

链接以查看output在线。

回答

1

这里关键的一点是,PHP会在内部将true转换为字符串。在PHP中,true强制转换为"1"所以

hash_hmac("sha1", "data", true); 

如果不通过一个4参数hash_hmac完全等同于

hash_hmac("sha1", "data", "1") 

然后将其输出十六进制的哈希值。这不是你在你的C#或JavaScript中做什么。下面是一些换算公式为您的工作与:

//PHP 
hash_hmac("sha1", "data", true) 

将输出一样

//JS 
var hash = CryptoJS.HmacSHA1('data', "1") 
console.log (CryptoJS.enc.Hex.stringify(hash)); //Note .Hex instead of .Base64 

同样,

//PHP 
base64_encode(hash_hmac("sha1", "data", true, true)); 

是一样的做

//JS 
var hash = CryptoJS.HmacSHA1('data', "1") 
console.log (CryptoJS.enc.Base64.stringify(hash)); 

另外,PHP会尝试转换所有非字符串$key的值为字符串。您可以通过调用strval($key)来查看您实际使用的密钥是什么。

+0

谢谢你的解释。 – Admir