2017-08-11 40 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