【问题标题】:AES (Rijndael) Encryption 128 bits key ecbAES (Rijndael) 加密 128 位密钥 ecb
【发布时间】:2016-05-26 00:58:59
【问题描述】:

我正在尝试为代表 16 字节数据的 32 字节十六进制字符串创建解密函数,这是我迄今为止尝试过的(我在这里找到了一个有效的 JS 示例:http://www.hanewin.net/encrypt/aes/aes-test.htm):

public static string DecryptString(string code)
    {

        string text = hex2s("0102030405060708090a0b0c0d0e0f11");
        string key = hex2s("ed7c0c82daf513b81c32f6655e8fd4ee");

        //Expected result: 260fe45846fb26dbb1d28d8166d4a89f

        return BitConverter.ToString(Encoding.Default.GetBytes(decrypt(text, key)));
    }


    private static string hex2s(string hex)
    {
        var r = "";
        if (hex.IndexOf("0x") == 0 || hex.IndexOf("0X") == 0) hex = hex.Substring(2);

        if (hex.Length % 2 > 0) hex += '0';

        for (var i = 0; i < hex.Length; i += 2)
        {
            int thisCharCode = hex[i];
            char newCharCode = (char)(thisCharCode);
            r = r + newCharCode;
        }
        return r;
    }

    public static String decrypt(String imput, String key)
    {
        byte[] data = Convert.FromBase64String(imput);
        String decrypted;

        using (RijndaelManaged rijAlg = new RijndaelManaged())
        {
            rijAlg.Key = Encoding.ASCII.GetBytes(key);
            rijAlg.Mode = CipherMode.ECB;
            rijAlg.BlockSize = 128;
            rijAlg.Padding = PaddingMode.Zeros;

            ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, null);
            using (MemoryStream msDecrypt = new MemoryStream(data))
            {
                using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                {
                    using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                    {
                        decrypted = srDecrypt.ReadToEnd();
                    }
                }
            }
        }
        return decrypted;
    }

我收到错误消息:“要解密的数据长度无效。”

我将非常感谢任何建议。

【问题讨论】:

  • 您检查要解密的数据的长度是多少?是16的乘法吗?错误发生在哪里(哪一行)?
  • 它以小写十六进制字符串格式发送的数据,其中每个字节为 2 个字符。 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x11
  • 这是发生错误的地方 decrypted = srDecrypt.ReadToEnd();
  • 对于初学者,我会避免在任何地方使用string。此外,您在未由 Base64 编码生成的字符串上使用 FromBase64String
  • 切勿使用ECB mode。它是确定性的,因此在语义上不安全。您至少应该使用像CBCCTR 这样的随机模式。最好对您的密文进行身份验证,以免像padding oracle attack 这样的攻击是不可能的。这可以通过 GCM 或 EAX 等认证模式或encrypt-then-MAC 方案来完成。

标签: c# encryption cryptography aes rijndael


【解决方案1】:

查看您的 cmets 后,我找到了解决方案:

public static string DecryptString(string code)
    {

        byte[] text = FromHex("0102030405060708090a0b0c0d0e0f11");
        byte[] key = FromHex("ed7c0c82daf513b81c32f6655e8fd4ee");

        //Expected result: 260fe45846fb26dbb1d28d8166d4a89f

        return BitConverter.ToString(Encoding.Default.GetBytes(decrypt(text, key)));
    }

    public static byte[] FromHex(string hex)
    {
        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;
    } 


    public static String decrypt(byte[] input, byte[] key)
    {
        byte[] data = input;
        String decrypted;

        using (RijndaelManaged rijAlg = new RijndaelManaged())
        {
            rijAlg.Key = key;
            rijAlg.Mode = CipherMode.ECB;
            rijAlg.BlockSize = 128;
            rijAlg.Padding = PaddingMode.Zeros;

            ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, null);
            using (MemoryStream msDecrypt = new MemoryStream(data))
            {
                using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                {
                    using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                    {
                        decrypted = srDecrypt.ReadToEnd();
                    }
                }
            }
        }
        return decrypted;
    }

感谢@Damien_The_Unbeliever 和@Ian 的帮助

【讨论】:

  • 描述解决方案更有帮助,用眼睛区分 SO 上的两个来源实际上是不可能或没有帮助的。
  • @zaph 这只是一个解码问题。我很高兴找到了解决方案,但这不适合后代。
猜你喜欢
  • 1970-01-01
  • 2019-04-18
  • 1970-01-01
  • 2013-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-20
相关资源
最近更新 更多