将 C# HMAC SHA256 转换为 PHP
Convert C# HMAC SHA256 to PHP
我有一个 C# 方法,我必须将其转换为 PHP。我尝试了几件事,但仍然得到不同的结果。不幸的是,我无法更改 C# 应用程序上的任何内容。它必须保持原样。也许你们中有人可以帮忙?
C#:
static public void Main ()
{
string StringToSign = "test";
string Key = "123456";
//Calculate Signature
string Signature = CalculateSignature(StringToSign, Key);
Console.WriteLine ("StringToSign: " + StringToSign);
Console.WriteLine ("Key: " + Key);
Console.WriteLine ("Signature Caculated: " + Signature + "\r\n");
}
static private string CalculateSignature(String StringToSign, String Key)
{
Encoding enc = Encoding.GetEncoding(65001);
byte[] KeyHex = StringHexValuesToByteArray(Key);
byte[] StringToSign_byte = enc.GetBytes(StringToSign);
//Check Signature
HMACSHA256 hmac = new HMACSHA256(KeyHex);
byte[] hashValue = hmac.ComputeHash(StringToSign_byte);
return BitConverter.ToString(hashValue).Replace("-", "");
}
static public byte[] StringHexValuesToByteArray(string str)
{
if (str.Length % 2 != 0)
return null;
string s = string.Empty;
byte[] ret = new byte[str.Length / 2];
for (int run = 0; run < str.Length / 2; run++)
{
s = str.Substring(run * 2, 2);
ret[run] = Convert.ToByte(s, 16);
}
return ret;
}
PHP:
public function send() {
$stringToSign = 'test';
$key = '123456';
//Calculate Signature
$signature = $this->calculateSignature($stringToSign, $key);
print_r("StringToSign: " . $stringToSign . PHP_EOL);
print_r("Key: " . $key . PHP_EOL);
print_r("Signature Caculated: " . $signature . PHP_EOL);
}
private function calculateSignature($stringToSign, $key) {
// check signature
$hash = strtoupper(hash_hmac('sha256', $stringToSign, $key, false));
return $hash;
}
为了更好地理解,这里是上面代码块的输出:
C#
StringToSign: test
Key: 123456
Signature Caculated:
DA3617974490FB780F04F06287BF93B0F24A7F15970471146428B943FFDC7850
PHP
StringToSign: test
GroupKey: 123456
Signature Caculated: 9D2BB116E1DF997FFE8A5139FC1D187F976C19579A138414A112BC2E39020EBA
如果要修改PHP使其等同于C#
改变
$hash = strtoupper(hash_hmac('sha256', $stringToSign, $key, false));
至
$hash = strtoupper(hash_hmac('sha256', $stringToSign, hex2bin($key), false));
一定要检查代码是否适用于非 ASCII 字符,例如 àèéìòù
。
如果要修改C#代码使其等价于PHP
你把一切都复杂化了:
static private string CalculateSignature(String stringToSign, String key)
{
byte[] key_byte = Encoding.UTF8.GetBytes(key);
byte[] stringToSign_byte = Encoding.UTF8.GetBytes(stringToSign);
//Check Signature
HMACSHA256 hmac = new HMACSHA256(key_byte);
byte[] hashValue = hmac.ComputeHash(stringToSign_byte);
return BitConverter.ToString(hashValue).Replace("-", "");
}
没有十六进制。而不是使用 Encoding.GetEncoding(65001)
通常更好地使用 Encoding.UTF8
,因为它对每个人都更清楚。
请注意,编码可能存在问题。尝试计算 àèéìòù
之类的 hmac 以查看 PHP 使用的是哪种编码。
我有一个 C# 方法,我必须将其转换为 PHP。我尝试了几件事,但仍然得到不同的结果。不幸的是,我无法更改 C# 应用程序上的任何内容。它必须保持原样。也许你们中有人可以帮忙?
C#:
static public void Main ()
{
string StringToSign = "test";
string Key = "123456";
//Calculate Signature
string Signature = CalculateSignature(StringToSign, Key);
Console.WriteLine ("StringToSign: " + StringToSign);
Console.WriteLine ("Key: " + Key);
Console.WriteLine ("Signature Caculated: " + Signature + "\r\n");
}
static private string CalculateSignature(String StringToSign, String Key)
{
Encoding enc = Encoding.GetEncoding(65001);
byte[] KeyHex = StringHexValuesToByteArray(Key);
byte[] StringToSign_byte = enc.GetBytes(StringToSign);
//Check Signature
HMACSHA256 hmac = new HMACSHA256(KeyHex);
byte[] hashValue = hmac.ComputeHash(StringToSign_byte);
return BitConverter.ToString(hashValue).Replace("-", "");
}
static public byte[] StringHexValuesToByteArray(string str)
{
if (str.Length % 2 != 0)
return null;
string s = string.Empty;
byte[] ret = new byte[str.Length / 2];
for (int run = 0; run < str.Length / 2; run++)
{
s = str.Substring(run * 2, 2);
ret[run] = Convert.ToByte(s, 16);
}
return ret;
}
PHP:
public function send() {
$stringToSign = 'test';
$key = '123456';
//Calculate Signature
$signature = $this->calculateSignature($stringToSign, $key);
print_r("StringToSign: " . $stringToSign . PHP_EOL);
print_r("Key: " . $key . PHP_EOL);
print_r("Signature Caculated: " . $signature . PHP_EOL);
}
private function calculateSignature($stringToSign, $key) {
// check signature
$hash = strtoupper(hash_hmac('sha256', $stringToSign, $key, false));
return $hash;
}
为了更好地理解,这里是上面代码块的输出:
C#
StringToSign: test
Key: 123456
Signature Caculated: DA3617974490FB780F04F06287BF93B0F24A7F15970471146428B943FFDC7850
PHP
StringToSign: test
GroupKey: 123456
Signature Caculated: 9D2BB116E1DF997FFE8A5139FC1D187F976C19579A138414A112BC2E39020EBA
如果要修改PHP使其等同于C#
改变
$hash = strtoupper(hash_hmac('sha256', $stringToSign, $key, false));
至
$hash = strtoupper(hash_hmac('sha256', $stringToSign, hex2bin($key), false));
一定要检查代码是否适用于非 ASCII 字符,例如 àèéìòù
。
如果要修改C#代码使其等价于PHP
你把一切都复杂化了:
static private string CalculateSignature(String stringToSign, String key)
{
byte[] key_byte = Encoding.UTF8.GetBytes(key);
byte[] stringToSign_byte = Encoding.UTF8.GetBytes(stringToSign);
//Check Signature
HMACSHA256 hmac = new HMACSHA256(key_byte);
byte[] hashValue = hmac.ComputeHash(stringToSign_byte);
return BitConverter.ToString(hashValue).Replace("-", "");
}
没有十六进制。而不是使用 Encoding.GetEncoding(65001)
通常更好地使用 Encoding.UTF8
,因为它对每个人都更清楚。
请注意,编码可能存在问题。尝试计算 àèéìòù
之类的 hmac 以查看 PHP 使用的是哪种编码。