繁体   English   中英

相当于 PHP7 openssl 的 C# 加密/解密方法

[英]C# encrypt/decrypt methods which are equivalent to PHP7 openssl

我在加密/解密数据的 PHP 7 程序中有以下几行:

$key = base64_decode("mykey===");
$iv = substr(hash('sha256', "myiv======"), 0, 16);
printf(base64_encode(openssl_encrypt("hello", "aes-256-cbc", $key, OPENSSL_RAW_DATA, $iv)));
printf("<br>");
printf(openssl_decrypt(base64_decode("2XJxQXSbPuJ9LMsZ/FESGw=="), "aes-256-cbc", $key, OPENSSL_RAW_DATA, $iv));

这是有效的,PHP 将“hello”解密为“2XJxQXSbPuJ9LMsZ/FESGw==”,反之亦然。 但是,我正在尝试使用 C# 解密和加密相同的数据(来自数据库),但似乎无法弄清楚。 我使用以下方法进行解密(C#):

private string aes_decrypt(string cipherText, string key, string iv)
    {
        RijndaelManaged aes = new RijndaelManaged();
        aes.KeySize = 256;
        aes.BlockSize = 128;
        aes.Mode = CipherMode.CBC;
        aes.Padding = PaddingMode.None;
        aes.Key = Convert.FromBase64String(key);
        aes.IV = Encoding.UTF8.GetBytes(iv);

        if (aes.Key.Length < 32)
        {
            var paddedkey = new byte[32];
            Buffer.BlockCopy(aes.Key, 0, paddedkey, 0, aes.Key.Length);
            aes.Key = paddedkey;
        }

        var decrypt = aes.CreateDecryptor();
        byte[] xBuff = null;
        using (var ms = new MemoryStream())
        {
            using (var cs = new CryptoStream(ms, decrypt, CryptoStreamMode.Write))
            {
                byte[] xXml = Convert.FromBase64String(cipherText);
                cs.Write(xXml, 0, xXml.Length);
            }

            xBuff = ms.ToArray();
        }

        String Output = Encoding.UTF8.GetString(xBuff);
        return Output;

    }

但是调用这个方法:

string encryptionkey = "mykey===";
string encryptioniv = GenerateSHA256String("myiv======").Substring(0, 16);
string str = aes_decrypt("2XJxQXSbPuJ9LMsZ/FESGw==", encryptionkey, encryptioniv);
Console.WriteLine(@str);

返回:HellO++++??????+

加密方法似乎也不起作用(在线引用并修改):

private static String EncryptIt(String s, string akey, string aIV)
    {
        String result;
        byte[] key = Convert.FromBase64String(akey);
        byte[] IV = Encoding.UTF8.GetBytes(aIV);

        RijndaelManaged rijn = new RijndaelManaged();
        rijn.Mode = CipherMode.CBC;
        rijn.Padding = PaddingMode.PKCS7;
        rijn.KeySize = 256;
        rijn.BlockSize = 128;

        using (MemoryStream msEncrypt = new MemoryStream())
        {
            using (ICryptoTransform encryptor = rijn.CreateEncryptor(key, IV))
            {
                using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                    {
                        swEncrypt.Write(s);
                    }
                }
            }
            result = Convert.ToBase64String(msEncrypt.ToArray());
        }
        rijn.Clear();

        return result;
    }

调用此方法: EncryptIt("hello", encryptionkey, encryptioniv); 返回 ul0axDR0WWGcpeijPRNusg== 而不是由 PHP 生成的 2XJxQXSbPuJ9LMsZ/FESGw==。 有谁知道这里出了什么问题?

作为参考,我在 IV 中使用了这些方法,它们工作正常:

private string GenerateSHA256String(string inputString)
    {
        SHA256 sha256 = SHA256Managed.Create();
        byte[] bytes = Encoding.UTF8.GetBytes(inputString);
        byte[] hash = sha256.ComputeHash(bytes);
        return GetStringFromHash(hash);
    }
    private string GetStringFromHash(byte[] hash)
    {
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < hash.Length; i++)
        {
            result.Append(hash[i].ToString("X2"));
        }
        return result.ToString();
    }

老问题,但我最近又遇到了这个问题。

当使用 PHP 7.2 openssl_decrypt/openssl_encrypt 填充作为 OPENSSL_RAW_DATA 时,它仅在 chsarp AES 填充设置为 PaddingMode.PKCS7 时对我有用。

原始帖子有用于解密的 PaddingMode.None 和用于加密的 PaddingMode.PKCS7。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM