首页 文章

C#AES 128 CBC与-naltalt产生的结果不同于openssl AES -128-cbc -nosalt

提问于
浏览
0

我有一个来自第三方的加密示例,我需要与...集成

我应该发送他们加密的消息,他们确实解密它并执行所需的操作 .

他们为我提供了一个示例,就是他们期望字符串被加密的方式 .

echo -n ['String to encrypt'] | openssl enc -aes-128-cbc -A -a -nosalt -K [Hexption EncryptionKey] -iv 3030303030303030303030303030303030

我给出的沙盒encryptionKey Hex是313233343536373839

目前我无法使用上面指定的密钥和IV ...因为.Net中的AES实现引发了我的错误,其中显示“指定的密钥不是此算法的有效大小”

然后我只用0填充键以匹配32个字节并截断IV以匹配16个字节..

然后我能够至少运行代码但是我的c#代码中的加密字符串无法在openssl上解密 .

以下是我的代码..

public static string EncryptString(string plainText, string password)
    {

        byte[] key, iv;
        //converting key to hex
        byte[] ba = Encoding.ASCII.GetBytes("0123456789abcdef");
        string encryptionKeyHex = BitConverter.ToString(ba);
        encryptionKeyHex = encryptionKeyHex.Replace("-", "");

        // Padding key hex with zeros to match the size that .Net algo expects
        if (encryptionKeyHex.Length < 32)
        {
            while (encryptionKeyHex.Length < 32)
            {
                encryptionKeyHex += "0";
            }
        }

        var keyBytes = Encoding.ASCII.GetBytes(encryptionKeyHex);
        var ivBytes = Encoding.ASCII.GetBytes("3030303030303030"); // truncated the original IV specified in the question description to match the size.

        iv = ivBytes;
        key = keyBytes;

        var amAes = new AesManaged();
        amAes.Mode = CipherMode.CBC;
        amAes.Padding = PaddingMode.PKCS7;
        amAes.KeySize = 128;
        amAes.BlockSize = 128;
        amAes.Key = key;
         amAes.IV = iv;

        var icTransformer = amAes.CreateEncryptor();
        var msTemp = new MemoryStream();

        var csEncrypt = new CryptoStream(msTemp, icTransformer, CryptoStreamMode.Write);
        var sw = new StreamWriter(csEncrypt);
        sw.Write(plainText);
        sw.Close();
        sw.Dispose();

        csEncrypt.Clear();
        csEncrypt.Dispose();

        byte[] bResult = msTemp.ToArray();
        //var sha = new SHA1CryptoServiceProvider();
        //var result = sha.ComputeHash(bResult);
        string sResult = Convert.ToBase64String(bResult);
        sResult = HttpUtility.UrlEncode(sResult);

        if (System.Diagnostics.Debugger.IsAttached)
        {
            string debugDetails = "";
            debugDetails += "==> INPUT     : " + plainText + Environment.NewLine;
            debugDetails += "==> SECRET    : " + password + Environment.NewLine;
            //debugDetails += "==> SALT      : " + Program.ByteArrayToHexString(salt) + Environment.NewLine;
            debugDetails += "==> KEY       : " + Encoding.ASCII.GetString(amAes.Key) + " (" + amAes.KeySize.ToString() + ")" + Environment.NewLine;
            debugDetails += "==> IV        : " + Encoding.ASCII.GetString(amAes.IV) + Environment.NewLine;
            debugDetails += "==> ENCRYPTED : " + sResult;
            Console.WriteLine(debugDetails);
        }

        return sResult;
    }

OUTPUT:

==> INPUT:{“filter.accession_number.equals”:“0987654321”}

==> SECRET:==> KEY:30313233343536373839000000000000(256)

==> IV:3030303030303030

==>加密:B2uDRjnekFAlRDEKDldTs09lWiE4u16ZunVwDGi6gKm6YsaRlW4HU6eKJqfYZc7b

Update

已经注意到,使用相同的方法在Windows框上加密时比在Linux Box上获得不同的结果 .

在使用openssl的linux机器上,我们得到..

命令:echo -n'{“filter.accession_number.equals”:“0987654321”}'| openssl enc -aes-128-cbc -A -a -nosalt -K 313233343536373839 -iv 3030303030303030303030303030303030

结果:MTAusb6rYkxYf9 / REbFq9M1XwR 6Q58FfSJPTxDNwgs6z3jZ8ru 7ysnKuy2p3ox

加密的字符串工作得很好..我能够成功解密它 .

在windows框上发出相同的命令到openssl给我们..

命令:echo -n'{“filter.accession_number.equals”:“0987654321”}'| openssl enc -aes-128-cbc -A -a -nosalt -K 313233343536373839 -iv 3030303030303030303030303030303030

结果:Db9829q6QX6CPwLkE rs6zqRJJQaGZ9xk7fbztaGqsKcHPcr7equz3yOJPLc S6yvW4jXQTzoOk43F16GW7sPw ==

这个字符串不起作用......

2 回答

  • 1

    你只是忘了解码十六进制; Encoding.ASCII.GetBytes 仅获取密钥和IV的ASCII表示 .

    检查答案here以正确转换为字节(即用 StringToByteArray 替换 Encoding.ASCII.GetBytes ) .

  • 0

    以下是任何陷入类似问题的人的工作代码示例... @Maarten Bodewes您确实指出了我正确的方向,只需重新安排代码使其工作 . 谢谢 :)

    public static string EncryptString(string plainText)
        {
            byte[] key, iv;
    
            byte[] rawKey = Encoding.ASCII.GetBytes("123456789abcdef");
            string encryptionKeyHex = BitConverter.ToString(rawKey);
    
            byte[] hexKayBytes = FromHex(encryptionKeyHex); // convert to bytes with 'dashes'
            byte[] data = FromHex("30-30-30-30-30-30-30-30-30-30-30-30-30-30-30-30");
    
            encryptionKeyHex = ByteArrayToHexString(hexKayBytes);
    
    // modifying key size to match the algorithm validation on key size
    
            if (encryptionKeyHex.Length < 32)
            {
                while (encryptionKeyHex.Length < 32)
                {
                    encryptionKeyHex += "0";
                }
            }
    
            var ivOriginal = BitConverter.ToString(data);
            ivOriginal = ivOriginal.Replace("-", "");
    
            if (ivOriginal.Length < 16)
            {
                while (ivOriginal.Length < 16)
                {
                    ivOriginal += "0";
                }
            }            
    
            var keyBytes = StringToByteArray(encryptionKeyHex);
            var ivBytes = StringToByteArray(ivOriginal);
    
            iv = ivBytes;
            key = keyBytes;
    
            var amAes = new AesManaged();
            amAes.Mode = CipherMode.CBC;
            amAes.Padding = PaddingMode.PKCS7;
            amAes.KeySize = 128;
            amAes.BlockSize = 128;
            amAes.Key = key;
             amAes.IV = iv;
    
            var icTransformer = amAes.CreateEncryptor();
            var msTemp = new MemoryStream();
    
            var csEncrypt = new CryptoStream(msTemp, icTransformer, CryptoStreamMode.Write);
            var sw = new StreamWriter(csEncrypt);
            sw.Write(plainText);
            sw.Close();
            sw.Dispose();
    
            csEncrypt.Clear();
            csEncrypt.Dispose();
    
            byte[] bResult = msTemp.ToArray();
            string sResult = Convert.ToBase64String(bResult);
    
            if (System.Diagnostics.Debugger.IsAttached)
            {
                string debugDetails = "";
                debugDetails += "==> INPUT     : " + plainText + Environment.NewLine;
                debugDetails += "==> SECRET    : " + password + Environment.NewLine;
                //debugDetails += "==> SALT      : " + Program.ByteArrayToHexString(salt) + Environment.NewLine;
                debugDetails += "==> KEY       : " + Encoding.ASCII.GetString(amAes.Key) + " (" + amAes.KeySize.ToString() + ")" + Environment.NewLine;
                debugDetails += "==> IV        : " + Encoding.ASCII.GetString(amAes.IV) + Environment.NewLine;
                debugDetails += "==> ENCRYPTED : " + sResult;
                Console.WriteLine(debugDetails);
            }
    
            return sResult;
        }
    
        public static byte[] FromHex(string hex)
        {
            hex = hex.Replace("-", "");
            byte[] raw = new byte[hex.Length / 2];
            for (int i = 0; i < raw.Length; i++)
            {
                raw[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16);
            }
            return raw;
        }
    
        private static string ByteArrayToHexString(byte[] bytes)
        {
            StringBuilder sbHex = new StringBuilder();
    
            foreach (byte b in bytes)
                sbHex.AppendFormat("{0:x2}", b);
    
            return sbHex.ToString();
        }
    
        public static byte[] StringToByteArray(String hex)
        {
            int NumberChars = hex.Length;
            byte[] bytes = new byte[NumberChars / 2];
            for (int i = 0; i < NumberChars; i += 2)
                bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
            return bytes;
        }
    

相关问题