Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/279.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
从C#到PHP的函数_C#_Php_Encryption - Fatal编程技术网

从C#到PHP的函数

从C#到PHP的函数,c#,php,encryption,C#,Php,Encryption,我需要将这些用C#开发的加密系统转换成PHP。这些是输入数据。客户ID、转换为字符串的JSON对象和私钥 Codigo客户:1002 datos:{“codigoCliente”:1002,“codigoArticulo”:“30-07483”,“cantidad”:1} claveSecretaServicio:RFlTfDIwMjBXZWJQYWdlX0V4dGVybmF 我需要得到这个散列结果:wghgey830j3weado4ngnlyz9ly7xvquol5ige+hLU= 这是C#中

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

Codigo客户:1002

datos:{“codigoCliente”:1002,“codigoArticulo”:“30-07483”,“cantidad”:1}

claveSecretaServicio:RFlTfDIwMjBXZWJQYWdlX0V4dGVybmF

我需要得到这个散列结果:wghgey830j3weado4ngnlyz9ly7xvquol5ige+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的详细工作原理

我尝试过这个,但是我的哈希结果不同

/********************
 *      3DES
 ********************/
function encrypt_3DES($message, $key)
{
    $method = 'des-ede3-cbc';
    if (strlen($message) % 8) {
        $message = str_pad($message, strlen($message) + 8 - strlen($message) % 8, "\0");
    }
    $iv = "\0\0\0\0\0\0\0\0";
    $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)

但是我仍然需要另外两个来实现有效的散列。也许如果我让你读这篇迈克尔·费尔的文章

你的函数是正确的,我得到了与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编码,而是作为原始二进制数据返回。此外,必须实现与C#code的
Modelo
类相对应的类,并根据发布的示例数据进行初始化,然后作为JSON字符串传递

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




进一步注意:显然,数据(
datos
)要用HMAC散列,用于此(
claveOperation
)的密钥是从客户端ID(
CodigoCliente
)和密码(
claveseretaservicio
)组合而来的。为了推导HMAC的密钥,应用了三重加密。在我看来,更现代的是具有可靠密钥派生函数的派生,如PBKDF2。

这些代码在我的机器上提供了相同的结果。如果在您的计算机上不同,请发布一个完整的示例,即示例数据和对所涉及的方法的调用。添加的函数调用数据和结果字符串来获取。您的添加并没有真正的帮助。仅仅发布测试数据是不够的,有趣的是如何将数据传递给
GetHMACSHA256
mac256
,当然还有输出,请参阅。原始问题中未包含的
GetHash
createHash
方法实际上是不需要的(与此相关的问题将是第二个问题的主题)。我已经重写了问题,以查看现在是否更清楚,我想您现在已经拥有了所有必要的数据。谢谢这个数据仍然不能与C代码一起使用。在密钥数据中缺少填充。但即使添加了此项,Base64解码密钥的长度也为23字节,因此不是有效的3DES密钥。为了进行重新编程,最好在调用
GetHash
方法后使用应提供预期哈希值的参数。非常感谢。这个解决方案非常有效。我做了几次测试,得到的哈希值是正确的。非常感谢Topaco的帮助和参与。
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
/********************
 *      3DES
 ********************/
function encrypt_3DES($message, $key)
{
    $method = 'des-ede3-cbc';
    if (strlen($message) % 8) {
        $message = str_pad($message, strlen($message) + 8 - strlen($message) % 8, "\0");
    }
    $iv = "\0\0\0\0\0\0\0\0";
    $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=
?>