当前位置: 首页 > 知识库问答 >
问题:

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

郎仰岳
2023-03-14

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

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

他们为我提供了一个例子,这就是他们希望字符串被加密的方式。

echo -n ['要加密的字符串']| OpenSSL enc-AES-128-CBC-A-A-no salt-K[十六进制加密密钥]-iv 3030303030303030303030303030

我得到的沙盒加密关键十六进制313233343536373839

目前我还不能使用上面指定的键和IV...中的AES实现。Net抛出一个错误,说“指定的键对于这个算法来说不是一个有效的大小”

然后,我用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;
    }

输出:

==

==

==

==

更新

已经注意到,在Windows盒子上加密时,我们得到的结果与在Linux盒子上加密时,使用相同的方法。

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

命令:echo-n‘{“filter.accession_number.equals”:“0987654321”}‘|openssl enc-aes-128-cbc-A-nosalt-K 31323343535363737389-iv 3030303033030303030

结果为:mtausb 6 rykxyf 9/reb FQ 9 m1 xwr 6 q 58 ffsjptxdnwgs 6 z 3 JZ 8 ru 7 ysnkuy 2 P3 ox

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

在windowsbox上向openssl发出相同的命令时。。

命令:echo-n‘{“filter.accession_number.equals”:“0987654321”}‘|openssl enc-aes-128-cbc-A-nosalt-K 31323343535363737389-iv 3030303033030303030

结果: Db9829q6QX6CPwLe rs6zqRJQAZ9xk7fbztaGqsKHC7equz3yOJPLc S6yvW4jXQTzoOk43F16GW7sPw==

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

共有2个答案

缪宪
2023-03-14

这是任何陷入类似问题的人的工作代码示例... @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;
    }
庄飞
2023-03-14

你只是忘了解码十六进制。<代码>编码。GetBytes只获取键和IV的ASCII表示。

检查此处的答案以正确转换为字节(即,将编码.ASCII.GetBytes 替换为字符串字节数组)。

 类似资料:
  • 我正在尝试在Kotin/Java中实现aes-128-cbc加密。不幸的是,加密结果与使用相同参数的OpenSSL输出不同。 论据: Kotlin实施: OpenSSL-CMD: 结果: 使用OpenSSL解密结果会产生以下错误: 更新:将填充更改为PKCS5-相同的输出。

  • 我正在使用OpenNLP处理诸如“在洛杉矶工作的医生”和“住在好莱坞并在圣莫尼卡工作的女性”之类的查询。对于理解人类的英语来说,这些句子很明显,主题是“医生”和“女性”。然而,当我使用opennlp时,它将句子标记为 [女性生活][好莱坞] 这是另一个句子“住在圣莫尼卡、在马里布工作和踢足球的人”被处理为 为什么OpenNLP的POS标记器错误地标记了它们?这些句子有最简单的语法结构。如果最先进的

  • 我只想用这3种模式测试openSSL中的AES:128192和256密钥长度,但我解密的文本与我的输入不同,我不知道为什么。此外,当我传递一个巨大的输入长度(比如1024字节)时,我的程序显示。。。我的意见总是一样的,但这并不重要,至少现在是这样。代码如下: 编辑: 当我将输出大小更改为而不是时,我得到了结果: 那么,是否有可能存在Outpus大小和IV大小的问题?它们应该有什么尺寸(AES-CB

  • 问题内容: 我有一个名为“单词”的列表,其中包含字符串。在这里Log.i可以很好地处理“ word”标签,但不会执行“step”语句。似乎如果条件不能很好地工作。尽管“单词”列表包含类似的字符串,但这种方法永远不会进入它。怎么了 请帮助 问题答案: 您需要使用,不。检查两个Object引用是否引用相同的内容Object: 从部分15.21.3引用相等运算符==和=!在的Java语言规范3.0: 虽

  • 如果这个数学是在计算器上完成的,“百分比”的值是0.424。但是,如果在代码中运行它,该值将四舍五入为0.43,这是不准确的。我怎样才能阻止这种情况发生? 注意:请不要质疑10000的数字,我也需要结果完全正确的数字(0.424),这是非常重要的在这种情况下!

  • 问题内容: PHP功能: Java函数 } 返回null。 请注意,我们不允许更改PHP代码。有人可以帮助我们在Java中获得相同的结果吗?非常感谢。 问题答案: 如果您不只是简单地将例程中的可能内容吞噬掉,那么您将对发生的事情有了更好的了解。如果函数正在返回,那么显然发生了异常,您需要知道它是什么。 实际上,例外是: 可以肯定的是,您的纯文本长度只有11个Java字符,按照您的默认编码,它将为1