使用openssl#u encrypt/openssl_decrypt将C#TripleDES ECB decrypt/encrypt转换为PHP

使用openssl#u encrypt/openssl_decrypt将C#TripleDES ECB decrypt/encrypt转换为PHP,c#,php,php-openssl,tripledes,ecb,C#,Php,Php Openssl,Tripledes,Ecb,我正在尝试使用openssl加密和openssl解密在PHP中使用PKCS7填充重新创建以下TripleDES ECB的C#实现 private static string Key = "<some random key with umlauts and special characters length of 24>"; public static string Decrypt(string cypherText) { using(var des = CreateDes(

我正在尝试使用openssl加密和openssl解密在PHP中使用PKCS7填充重新创建以下TripleDES ECB的C#实现

private static string Key = "<some random key with umlauts and special characters length of 24>";

public static string Decrypt(string cypherText)
{
    using(var des = CreateDes(Key))
    {
        var ct     = des.CreateDecryptor();
        var input  = Convert.FromBase64String(cypherText);
        var output = ct.TransformFinalBlock(input, 0, input.Length);
        return Encoding.UTF8.GetString(output);
    }
}

public static string Encrypt(string plainText)
{
    using(var des = CreateDes(Key))
    {
        var ct     = des.CreateEncryptor();
        var input  = Encoding.UTF8.GetBytes(plainText);
        var output = ct.TransformFinalBlock(input, 0, input.Length);
        return Convert.ToBase64String(output);
    }
}

private static TripleDES CreateDes(string key)
{
    MD5       md5    = new MD5CryptoServiceProvider();
    TripleDES des    = new TripleDESCryptoServiceProvider();
    var       desKey = md5.ComputeHash(Encoding.UTF8.GetBytes(key));
    des.Key     = desKey;
    des.IV      = new byte[des.BlockSize / 8];
    des.Padding = PaddingMode.PKCS7;
    des.Mode    = CipherMode.ECB;
    return des;
}
private static string Key=”“;
公共静态字符串解密(字符串密码文本)
{
使用(var des=CreateDes(键))
{
var ct=des.CreateDecryptor();
var输入=Convert.FromBase64String(cypherText);
变量输出=ct.TransformFinalBlock(输入,0,输入.长度);
返回Encoding.UTF8.GetString(输出);
}
}
公共静态字符串加密(字符串明文)
{
使用(var des=CreateDes(键))
{
var ct=des.CreateEncryptor();
var输入=Encoding.UTF8.GetBytes(纯文本);
变量输出=ct.TransformFinalBlock(输入,0,输入.长度);
返回Convert.tobase64字符串(输出);
}
}
私有静态三元组CreateDes(字符串键)
{
MD5 MD5=新的MD5CryptoServiceProvider();
TripleDES des=新的TripleDESCryptoServiceProvider();
var desKey=md5.ComputeHash(Encoding.UTF8.GetBytes(key));
des.Key=desKey;
des.IV=新字节[des.BlockSize/8];
des.Padding=PaddingMode.PKCS7;
des.Mode=CipherMode.ECB;
返回des;
}
到目前为止,我已经设法弄明白,我必须在PHP中使用md5函数的raw_输出参数来获得完全相同的密钥(与C#中的断点和PHP中的getByteFromString函数相比),加密/解密基本上在双方都起作用。除了用C#加密的值不能用PHP解密,反之亦然,因为加密结果不一样

到目前为止,我在PHP中得到了:

函数getByteFromString($value) { $ret=''; 对于($i=0;$i'.ord($value[$i])。“
”; } 返回$ret; } 函数加密($key,$value) { if(函数_存在('openssl_encrypt')) { 返回base64_encode(openssl_encrypt($value,'DES-EDE3',$key,openssl_RAW_DATA)); } 返回“缺少openssl”; } 函数解密($key,$value) { if(函数_存在('openssl_decrypt')) { 返回openssl_decrypt(base64_decode($value),'DES-EDE3',$key,openssl_原始数据); } 返回“缺少openssl”; } $sKey=md5(“,true); $number='1234567890'; $encrypted=加密($sKey,$number); $decrypted=解密($sKey,$encrypted); //仅适用于密钥调试: 回显“键:
”。getByteFromString($sKey)。'
'; 回显“加密:”。var_导出($encrypted,true)。'
'; echo“已解密:”。var_导出($decrypted,true)。'
';
我知道不应该再使用TripleDES,尤其是ECB模式,但我无法更改C代码,因此PHP代码必须创建与C相同的结果,并且必须能够解密用C加密的值以及加密值,以便C可以解密它们-使用TripleDES和ECB。我只是不知道我在PHP方面缺少了什么。

好的,所以我通过阅读相关问题找到了解决方案。我在一个7年前的问题中发现了它,尽管它是针对不推荐使用的mcrypt函数提出的,但不知何故,它仍然可以使用openssl函数

所要做的就是将原始密钥的前8个字节附加到自身,如下所示:

$sKey=md5(“,true);
$sKey.=substr($sKey,0,8);
其中给出了以下PHP工作示例:

函数加密($key,$value)
{
if(函数_存在('openssl_encrypt'))
{
返回base64_encode(openssl_encrypt($value,'DES-EDE3',$key,openssl_RAW_DATA));
}
返回“缺少openssl”;
}
函数解密($key,$value)
{
if(函数_存在('openssl_decrypt'))
{
返回openssl_decrypt(base64_decode($value),'DES-EDE3',$key,openssl_原始数据);
}
返回“缺少openssl”;
}
$sKey=md5(“,true);
$sKey.=substr($sKey,0,8)//添加此行以修复它
$number='1234567890';
$encrypted=加密($sKey,$number);
$decrypted=解密($sKey,$encrypted);
回显“加密:”。var_导出($encrypted,true)。'
'; echo“已解密:”。var_导出($decrypted,true)。'
';
如果有人可以评论为什么这是解决方案,请这样做。虽然我对它的工作很满意,但我真的很想了解它工作的原因。我在C#中看不到类似的事情发生,那么为什么我必须在PHP中这样做呢