簡體   English   中英

具有-nosalt的C#AES 128 CBC與openssl AES -128-cbc -nosalt產生不同的結果

[英]C# AES 128 CBC with -nosalt producing different results than openssl AES -128-cbc -nosalt

我有一個來自第三方的加密示例,我需要與...集成

我應該向他們發送加密的消息,並且他們確實會對其解密並執行所需的操作。

他們為我提供了一個示例,說明他們期望如何對字符串進行加密..

echo -n [“要加密的字符串”] | openssl enc -aes-128-cbc -A -a -nosalt -K [十六進制加密密鑰] -iv 30303030303030303303030303030030

我得到的沙盒加密密鑰十六進制是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;
    }

輸出:

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

==>秘密:==>密鑰:30313233343536373839000000000000(256)

==> IV:3030303030303030

==>加密的:B2uDRjnekFAlRDEKDldTs09lWiE4u16ZunVwDGi6gKm6YsaRlW4HU6eKJqfYZc7b

更新資料

已經注意到,使用相同的方法在Windows盒上進行加密的情況與在Linux盒上進行加密的結果不同。

在使用openssl的Linux機器上,我們得到..

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

結果:MTAusb6rYkxYf9 / REbFq9M1XwR + 6Q58FfSJPTxDNwgs6z3jZ8ru + 7ysnKuy2p3ox

該加密的字符串很好用..我能夠成功解密它。

在windows框上向openssl發出相同的命令時,會給我們..

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

結果:Db9829q6QX6CPwLkE + rs6zqRJJQaGZ9xk7fbztaGqsKcHPcr7equz3yOJPLc + S6yvW4jXQTzoOk43F16GW7sPw ==

該字符串不起作用...

您只是忘了解碼十六進制而已; Encoding.ASCII.GetBytes僅獲取密鑰和IV的ASCII表示形式。

此處檢查答案以正確轉換為字節(即,用StringToByteArray替換Encoding.ASCII.GetBytes )。

這是適合遇到類似問題的任何人的工作代碼示例... @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;
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM