我在PHP中有一个字符串,它被转换为字节数组并进行散列。
转换为字节数组的字符串如下所示:
“G”。 chr(0)。 “大便”;
我需要在C#中使用等效的字节数组,这样我才能获得相同的哈希值。
编辑:这是完全问题,导致哈希不一样。
PHP
$api_secret = '5432919427bd18884fc2a6e48b65dfba48fd9a1a46e3468b52fadbc6d6b463425';
$data = 'payment_currency=USD&group_orders=0&count=100&nonce=1385689989977529';
$endpoint = '/info/orderbook';
$signature = hash_hmac('sha512', $endpoint . chr(0) . $data, $api_secret);
$result = base64_encode($signature);
C#
var apiSecret = "5432919427bd18884fc2a6e48b65dfba48fd9a1a46e3468b52fadbc6d6b463425";
var data = "payment_currency=USD&group_orders=0&count=100&nonce=1385689989977529";
var endPoint = "/info/orderbook";
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
String message = endpPoint + Convert.ToChar(0) + data;
var hmacsha512 = new HMACSHA512(encoding.GetBytes(message));
var result = Convert.ToBase64String(hmacsha512.Hash);
我尝试了不同的base64编码,如:
public static string ByteToString(byte[] buff)
{
string sbinary = "";
for (int i = 0; i < buff.Length; i++)
sbinary += buff[i].ToString("X2"); /* hex format */
return sbinary;
}
但最终问题似乎是由于chr(0)php使用而被哈希的byteArray。
答案 0 :(得分:3)
我再次回答,因为你已经改变了整个问题,所以你的新问题有了新的解决方案。
首先,HMACSHA512不会提供与php代码相同的结果。顺便说一下,PHP生成的哈希是:
41028bb90af31dc6e7fa100a8ceb1e220bfedf67ea723292db9a4e1c14f69c73adf30eeba61ab054cdc91c82f6be2f76dd602392be630b5e99b1f86da1460cbe
为了在C#中产生相同的结果,我创建了BillieJeansSHA512
类以使哈希等于PHP。另外使用encoding.GetBytes
将byte []转换为String我创建了方法ByteToString
以便正确转换。
噢,下面的代码并不像PHP那么简单,但我挑战你或者任何人使用相同的PHP哈希来做这个更简单!我敢,你我敢惹你!我们来看看代码:
//These are not default imports, so you need to use it
using System.Text;
using System.Security.Cryptography;
//Before your actual class, you need to make your custom 512
public class BillieJeansSHA512 : HMAC
{
public BillieJeansSHA512(byte[] key)
{
HashName = "System.Security.Cryptography.SHA512CryptoServiceProvider";
HashSizeValue = 512;
BlockSizeValue = 128;
Key = (byte[])key.Clone();
}
}
//Now, there's your actual class
public class HelloWorld{
//First, use this method to convert byte to String like a boss
static string ByteToString(byte[] buff)
{
string sbinary = "";
for (int i = 0; i < buff.Length; i++)
sbinary += buff[i].ToString("x2"); /* hex format */
return sbinary;
}
//Now let's get it started!
public static void Main(String []args){
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
//Your data
var apiSecret = "5432919427bd18884fc2a6e48b65dfba48fd9a1a46e3468b52fadbc6d6b463425";
var data = "payment_currency=USD&group_orders=0&count=100&nonce=1385689989977529";
var endPoint = "/info/orderbook";
String message = endPoint + Convert.ToChar(0) + data;
//Hash will be stored here
String hash = "";
//put your key at your custom 512
BillieJeansSHA512 hmacsha512 = new BillieJeansSHA512(encoding.GetBytes(apiSecret));
//hash'em all
byte[] result = hmacsha512.ComputeHash(encoding.GetBytes(message));
//convert bytes to string
hash = ByteToString(result);
//See it :)
Console.WriteLine(hash);
//Or if you using it at a web-page, this is it.
//Response.Write(hash)
//Now the easy part, convert it to base64
var bytesTo64 = System.Text.Encoding.UTF8.GetBytes(hash);
String hash64 = System.Convert.ToBase64String(bytesTo64);
}
}
......好吧,就是这样。 String hash
具有与PHP相同的哈希值:
41028bb90af31dc6e7fa100a8ceb1e220bfedf67ea723292db9a4e1c14f69c73adf30eeba61ab054cdc91c82f6be2f76dd602392be630b5e99b1f86da1460cbe
和String hash64
具有与PHP相同的编码base64值:
NDEwMjhiYjkwYWYzMWRjNmU3ZmExMDBhOGNlYjFlMjIwYmZlZGY2N2VhNzIzMjkyZGI5YTRlMWMxNGY2OWM3M2FkZjMwZWViYTYxYWIwNTRjZGM5MWM4MmY2YmUyZjc2ZGQ2MDIzOTJiZTYzMGI1ZTk5YjFmODZkYTE0NjBjYmU=
答案 1 :(得分:1)
他还将其视为byte
数组,这是最重要的,因为必须使用字符到字节转换:
//Conversion object
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
//Your any String text
String stringText = "g" + Convert.ToChar(0) + "poo";
//Convert to the wanted byte array
byte[] byteArray = encoding.GetBytes(stringText);
如果您愿意,也可以在一行中执行相同的操作:)
byte[] byteArray = new System.Text.UTF8Encoding().GetBytes("g" + Convert.ToChar(0) + "poo");
答案 2 :(得分:0)
您可以使用Convert.ToChar(Int32)
方法将unicode值表示为字符。
用法:"g" + Convert.ToChar(0) + "poo"