从C#到PHP的函数

c#

我需要将这些用 C# 开发的加密系统转换为 PHP。这些是输入数据。客户 ID、转换为字符串的 JSON 对象和私钥。

codigoCliente: 1002

数据:{"codigoCliente":1002,"codigoArticulo":"30-07483","cantidad":1}

claveSecretaServicio:RFlTfDIwMjBXZWJQYWdlX0V4dGVybmF

我需要得到这个哈希结果:WGHGEY830J3WeadO1o4NGNLYZ9lY7xvquol5igE+hLU=

这是 C# 中的调用:GetHash(modelo.CodigoCliente.ToString(), JsonSerializer.Serialize(modelo), “WGHGEY830J3WeadO1o4NGNLYZ9lY7xvquol5igE+hLU=”);

转换为 PHP 的 C# 函数是这些。

public static string GetHash(string codigoCliente, string datos, string claveSecretaServicio)
{
    var claveSecretaBytes = System.Convert.FromBase64String(claveSecretaServicio);
    var claveOperacion = Encrypt3DES(codigoCliente, claveSecretaBytes);
    var firmaBytes = GetHMACSHA256(datos, claveOperacion);
    return System.Convert.ToBase64String(firmaBytes);
}

private static byte[] Encrypt3DES(string codigoCliente, byte[] key)
{
    var codigoClienteBytes = System.Text.Encoding.UTF8.GetBytes(codigoCliente);
    TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
    byte[] SALT = new byte[8] { 0, 0, 0, 0, 0, 0, 0, 0 };
    tdes.BlockSize = 64;
    tdes.KeySize = 192;
    tdes.Mode = CipherMode.CBC;
    tdes.Padding = PaddingMode.Zeros;
    tdes.IV = SALT;
    tdes.Key = key;
    var cTransform = tdes.CreateEncryptor();
    byte[] resultArray = cTransform.TransformFinalBlock(codigoClienteBytes, 0, codigoClienteBytes.Length);
    tdes.Clear();
    return resultArray;
}

private static byte[] GetHMACSHA256(string data, byte[] key)
{
    byte[] dataBytes = Encoding.UTF8.GetBytes(data);
    using (HMACSHA256 hmac = new HMACSHA256(key))
    {
        byte[] hashValue = hmac.ComputeHash(dataBytes, 0, dataBytes.Length);
        return hashValue;
    }
}

我不知道 C#,所以我不太了解将它们更改为 PHP 的函数的详细工作原理。

我试过这个,但我的 HASH 结果是不同的。

/********************
 *      3DES
 ********************/
function encrypt_3DES($message, $key)
{
    $method = 'des-ede3-cbc';
    if (strlen($message) % 8) {
        $message = str_pad($message, strlen($message) + 8 - strlen($message) % 8, "");
    }
    $iv = "";
    $encrypted = openssl_encrypt($message, $method, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); //Force zero padding.
    return base64_encode($encrypted);
}

/********************
 *      SHA 256
 ********************/
function mac256($ent, $key)
{
    $res = hash_hmac('sha256', $ent, $key, true); // TRUE (PHP 5 >= 5.1.2)
    return $res;
}

/********************
 *      BASE 64
 ********************/
function encodeBase64($data)
{
    $data = base64_encode($data);
    return $data;
}
function decodeBase64($data)
{
    $data = base64_decode($data);
    return $data;
}

/********************
 *      HASH
 ********************/
function createHash($codigoCliente, $data, $key)
{
    $key = decodeBase64($key);

    $keyOperacion = encrypt_3DES($codigoCliente, $key);

    $res = mac256($data, $keyOperacion);

    return encodeBase64($res);
} 

我得到了一个有效的 3DES PHP 函数(感谢 Michael Fehr)

function encrypt_3DES($message, $key)
{
    $method = 'des-ede3-cbc';
    if (strlen($message) % 8) {
        $message = str_pad($message, strlen($message) + 8 - strlen($message) % 8, "");
    }
    $iv = "";
    $encrypted = openssl_encrypt($message, $method, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); //Force zero padding.
    return base64_encode($encrypted);
}

但我仍然需要另外两个来实现有效的 HASH。也许如果你读了这篇迈克尔·费尔。

你的函数是正确的,我得到了与 C# 相同的中间 3DES 值:PD8fSM4gz3s=

先感谢您。

回答

发布的 Base64 编码密钥RFlTfDIwMjBXZWJQYWdlX0V4dGVybmF结果 Base64 解码DYS|2020WebPage_Externa,因此长度为 23 个字节。这对于需要 24 字节密钥的 TripleDES 来说太短了。另外具有所需长度 24 字节的似是而非的密钥DYS|2020WebPage_External是 Base64 编码的RFlTfDIwMjBXZWJQYWdlX0V4dGVybmFs。这可能是复制/粘贴问题。

由于传入的数据对应一个 JSON 字符串,Modelo因此必须定义一个相应的类,在下面称为,根据发布的示例数据进行初始化并作为 JSON 字符串传递。

然后以下 C# 代码返回预期的哈希值:

class Modelo
{
    public int CodigoCliente { get; set; }
    public string CodigoArticulo { get; set; }
    public int Cantidad { get; set; }
}
...
Modelo modelo = new Modelo
{
    CodigoCliente = 1002,
    CodigoArticulo = "30-07483",
    Cantidad = 1
};
string hash = GetHash(modelo.CodigoCliente.ToString(), JsonSerializer.Serialize(modelo), "RFlTfDIwMjBXZWJQYWdlX0V4dGVybmFs");
Console.WriteLine(hash); // WGHGEY830J3WeadO1o4NGNLYZ9lY7xvquol5igE+hLU=

在 PHP 代码中,在encrypt_3DES方法中,返回的结果不能是 Base64 编码的,而是作为原始二进制数据返回的。此外,还Modelo必须实现一个与C#代码的类对应的类,根据贴出的示例数据进行初始化,并以JSON字符串的形式传递。

以下 PHP 代码返回与 C# 代码对应的预期哈希值:

<?php
/********************
 *      3DES
 ********************/
function encrypt_3DES($message, $key)
{
    $method = 'des-ede3-cbc';
    if (strlen($message) % 8) {
        $message = str_pad($message, strlen($message) + 8 - strlen($message) % 8, "");
    }
    $iv = "";
    $encrypted = openssl_encrypt($message, $method, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); //Force zero padding.
    return $encrypted; // base64_encode($encrypted); // Fix: Return the raw data and not the Base64 encoded data
}

/********************
 *      SHA 256
 ********************/
function mac256($ent, $key)
{
    $res = hash_hmac('sha256', $ent, $key, true); // TRUE (PHP 5 >= 5.1.2)
    return $res;
}

/********************
 *      BASE 64
 ********************/
function encodeBase64($data)
{
    $data = base64_encode($data);
    return $data;
}
function decodeBase64($data)
{
    $data = base64_decode($data);
    return $data;
}

/********************
 *      HASH
 ********************/
function createHash($codigoCliente, $data, $key)
{
    $key = decodeBase64($key);

    $keyOperacion = encrypt_3DES($codigoCliente, $key);

    $res = mac256($data, $keyOperacion);

    return encodeBase64($res);
} 

// Define a Modelo class as in the C# code
class Modelo 
{
    var $CodigoCliente;
    var $CodigoArticulo;
    var $Cantidad;
    function __construct( $CodigoCliente, $CodigoArticulo, $Cantidad)
    {
        $this->CodigoCliente = $CodigoCliente;
        $this->CodigoArticulo = $CodigoArticulo;
        $this->Cantidad = $Cantidad;
    }
}

$modelo = new Modelo(1002, '30-07483', 1);
$hash = createHash($modelo->CodigoCliente, json_encode($modelo), "RFlTfDIwMjBXZWJQYWdlX0V4dGVybmFs");
print($hash); // WGHGEY830J3WeadO1o4NGNLYZ9lY7xvquol5igE+hLU=
?>

进一步说明:显然数据 ( datos) 将使用 HMAC 进行散列,用于此 ( claveOperacion)的密钥来自客户端 ID ( CodigoCliente) 和密码 ( claveSecretaServicio)。为了导出 HMAC 的密钥,应用了 TripleDES 加密。在我看来,更现代的推导具有可靠的密钥推导函数,例如 PBKDF2。


以上是从C#到PHP的函数的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>