Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP和C#HMAC SHA256_C#_Php_Sha256_Hmac - Fatal编程技术网

PHP和C#HMAC SHA256

PHP和C#HMAC SHA256,c#,php,sha256,hmac,C#,Php,Sha256,Hmac,我需要在C#中转换以下php代码: 在哪里 及 我使用以下C代码: 在哪里 public byte[] HashHMAC(string ent, byte[] key) { byte[] toEncryptArray =System.Text.Encoding.GetEncoding(28591).GetBytes(ent); HMACSHA256 hash = new HMACSHA256(key); return hash.ComputeHash(toEncryptArr

我需要在C#中转换以下php代码:

在哪里

我使用以下C代码:

在哪里

public byte[] HashHMAC(string ent, byte[] key)
{
   byte[] toEncryptArray =System.Text.Encoding.GetEncoding(28591).GetBytes(ent);

   HMACSHA256 hash = new HMACSHA256(key);
   return hash.ComputeHash(toEncryptArray);
}
完整的php源代码在这里提供

我也检查了这个帖子

这个呢


但是结果不一样。

此代码应该可以实现以下功能:

static byte[] hmacSHA256(String data, String key)
{
    using (HMACSHA256 hmac = new HMACSHA256(Encoding.ASCII.GetBytes(key)))
    {
        return hmac.ComputeHash(Encoding.ASCII.GetBytes(data));
    }
}
如果我将此代码称为:

Console.WriteLine(BitConverter.ToString(hmacSHA256("1234", "1234")).Replace("-", "").ToLower());
public static string GetParameters(string merchantCode, string terminal, int currency, string transactionType, decimal amount, string merchantOrder, string merchantIdentifier, string merchantPost, string urlOk, string urlKo)
        {
            var jsonValues = new Dictionary<string, string>
            {
                { "Ds_Merchant_Amount", amount.ToString().Replace(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator, "") },
                { "Ds_Merchant_Order", merchantOrder},
                { "Ds_Merchant_MerchantCode", merchantCode },
                { "Ds_Merchant_Currency", currency.ToString() },
                { "Ds_Merchant_TransactionType", transactionType },
                { "Ds_Merchant_Terminal", terminal },
                { "Ds_Merchant_Identifier", merchantIdentifier },
                { "Ds_Merchant_MerchantURL", merchantPost },
                { "Ds_Merchant_UrlOK", urlOk},
                { "Ds_Merchant_UrlKO",  urlKo}
            }.Select(kvp => "\"{0}\":\"{1}\"".Formato(kvp.Key.ToUpper(), kvp.Value));

            var jsonString = "{" + string.Join(",", jsonValues) + "}";

            return Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(jsonString));
        }
它返回:

4e4feaea959d426155a480dc07ef92f4754ee93edbe56d993d74f131497e66fb
当我在PHP中运行时:

echo hash_hmac('sha256', "1234", "1234", false);
它回来了

4e4feaea959d426155a480dc07ef92f4754ee93edbe56d993d74f131497e66fb

我很确定您正在处理新的RedSys SHA256签名实现。我还看到,您对PHP和C#之间的3DES加密存在一些问题

首先,您必须获取包含所有付款参数的base 64字符串。您可以通过以下代码来实现:

Console.WriteLine(BitConverter.ToString(hmacSHA256("1234", "1234")).Replace("-", "").ToLower());
public static string GetParameters(string merchantCode, string terminal, int currency, string transactionType, decimal amount, string merchantOrder, string merchantIdentifier, string merchantPost, string urlOk, string urlKo)
        {
            var jsonValues = new Dictionary<string, string>
            {
                { "Ds_Merchant_Amount", amount.ToString().Replace(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator, "") },
                { "Ds_Merchant_Order", merchantOrder},
                { "Ds_Merchant_MerchantCode", merchantCode },
                { "Ds_Merchant_Currency", currency.ToString() },
                { "Ds_Merchant_TransactionType", transactionType },
                { "Ds_Merchant_Terminal", terminal },
                { "Ds_Merchant_Identifier", merchantIdentifier },
                { "Ds_Merchant_MerchantURL", merchantPost },
                { "Ds_Merchant_UrlOK", urlOk},
                { "Ds_Merchant_UrlKO",  urlKo}
            }.Select(kvp => "\"{0}\":\"{1}\"".Formato(kvp.Key.ToUpper(), kvp.Value));

            var jsonString = "{" + string.Join(",", jsonValues) + "}";

            return Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(jsonString));
        }
如您所见,RedSys提供的加密密钥是base 64字符串,因此不需要为3DES算法计算MD5哈希

然后我们选择SHA256签名:

public static string GetSignature(string base64Parameters, string base64tranEncryptKey)
        {
            using (var sha = new HMACSHA256(Convert.FromBase64String(base64tranEncryptKey)))
            {
                var hash = sha.ComputeHash(ASCIIEncoding.ASCII.GetBytes(base64Parameters));

                return Convert.ToBase64String(hash);
            }
        }

祝你好运

Redsys为php和java提供了库

从java库开始,我将ApiMacSha256类翻译成C#


“CreateCommerchantsignature”主方法需要一个嵌入json结构的商人参数base64编码的字符串、商人的密钥和OrderId。

这能帮到你吗?:@Ivar我使用了链接中报告的函数,但结果与我的(hashmac)相同。在我的示例中,根据进一步调查,密钥长度为8字节。报告如果键长小于64,则应自动填充。PHP和C在填充操作上有区别吗?谢谢。我解决了将redsys提供的php类“traslating”到C#中的问题,它可以工作。我使用了以下链接[PHP和C#3DES Encryption]中提供的建议(),您的回答是正确的,但请注意散列hmac->hash hmac中的参数bool raw_输出('sha256',“1234”,“1234”,true);如果raw_输出设置为true,则不必使用BitConverter.ToString替换“-”to”和ToLower()。然后c#中的代码变成just:hmacSHA256(“1234”、“1234”)
public static string GetParameters(string merchantCode, string terminal, int currency, string transactionType, decimal amount, string merchantOrder, string merchantIdentifier, string merchantPost, string urlOk, string urlKo)
        {
            var jsonValues = new Dictionary<string, string>
            {
                { "Ds_Merchant_Amount", amount.ToString().Replace(CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator, "") },
                { "Ds_Merchant_Order", merchantOrder},
                { "Ds_Merchant_MerchantCode", merchantCode },
                { "Ds_Merchant_Currency", currency.ToString() },
                { "Ds_Merchant_TransactionType", transactionType },
                { "Ds_Merchant_Terminal", terminal },
                { "Ds_Merchant_Identifier", merchantIdentifier },
                { "Ds_Merchant_MerchantURL", merchantPost },
                { "Ds_Merchant_UrlOK", urlOk},
                { "Ds_Merchant_UrlKO",  urlKo}
            }.Select(kvp => "\"{0}\":\"{1}\"".Formato(kvp.Key.ToUpper(), kvp.Value));

            var jsonString = "{" + string.Join(",", jsonValues) + "}";

            return Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(jsonString));
        }
public static string GetTransactionEncryptionKey(string merchantOrder, string encryptKey)
        {
            using (var tdes = new TripleDESCryptoServiceProvider())
            {
                tdes.IV = new byte[8] { 0, 0, 0, 0, 0, 0, 0, 0 };
                tdes.Key = Convert.FromBase64String(encryptKey);
                tdes.Padding = PaddingMode.Zeros;
                tdes.Mode = CipherMode.CBC;

                var toEncrypt = ASCIIEncoding.ASCII.GetBytes(merchantOrder);
                var result = tdes.CreateEncryptor().TransformFinalBlock(toEncrypt, 0, toEncrypt.Length);

                return Convert.ToBase64String(result);
            }
        }
public static string GetSignature(string base64Parameters, string base64tranEncryptKey)
        {
            using (var sha = new HMACSHA256(Convert.FromBase64String(base64tranEncryptKey)))
            {
                var hash = sha.ComputeHash(ASCIIEncoding.ASCII.GetBytes(base64Parameters));

                return Convert.ToBase64String(hash);
            }
        }
public class ApiMacSha256 {
    //////////////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////////////////
    ////////////                    FUNCIONES AUXILIARES:                              ///////////
    //////////////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////////////////

    /** 3DES Function */
    private byte[] encrypt_3DES(byte[] key, string data) {
        //http://www.mywebexperiences.com/2012/12/11/crypting-data-using-3des-c/
        //http://stackoverflow.com/a/33479952/2938518
        using (var tdes = new TripleDESCryptoServiceProvider()) {
            tdes.IV = new byte[8] { 0, 0, 0, 0, 0, 0, 0, 0 };
            tdes.Key = key;
            tdes.Padding = PaddingMode.Zeros;
            tdes.Mode = CipherMode.CBC;

            var toEncrypt = Encoding.ASCII.GetBytes(data);
            var result = tdes.CreateEncryptor().TransformFinalBlock(toEncrypt, 0, toEncrypt.Length);

            return result;
        }
    }

    /** MAC Function */
    private byte[] mac256(string dsMerchantParameters, byte[] secretKo) {
        //http://stackoverflow.com/a/17315619/2938518
        byte[] hash;
        using (var hmac = new HMACSHA256(secretKo)) {
            hash = hmac.ComputeHash(Encoding.ASCII.GetBytes(dsMerchantParameters));
        }

        return hash;
    }

    /** Base64 Functions */
    private string encodeB64String(byte[] data) {
        return Convert.ToBase64String(data, Base64FormattingOptions.None);
    }

    //////////////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////////////////
    ////////////        FUNCIONES PARA LA GENERACIÓN DEL FORMULARIO DE PAGO:          ////////////
    //////////////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////////////////
    public String createMerchantSignature(string merchantParamsB64, string claveComercio, string OrderId) {
        byte[] clave = Convert.FromBase64String(claveComercio);
        byte[] secretKo = encrypt_3DES(clave, OrderId);

        // Se hace el MAC con la clave de la operación "Ko" y se codifica en BASE64
        byte[] hash = mac256(merchantParamsB64, secretKo);
        String res = encodeB64String(hash);
        return res;
    }
}