简体   繁体   English

如何在.Net中加密AES / ECB / 128消息?

[英]how to encrypt AES/ECB/128 messages in .Net?

Took the vectors from this site http://www.inconteam.com/software-development/41-encryption/55-aes-test-vectors#aes-ecb-128 从这个网站获取载体http://www.inconteam.com/software-development/41-encryption/55-aes-test-vectors#aes-ecb-128

In javascript (sjcl) have the same result 在javascript(sjcl)中有相同的结果

var key = [0x2b7e1516,0x28aed2a6,0xabf71588,0x09cf4f3c];
var test  = [0x6bc1bee2,0x2e409f96,0xe93d7e11,0x7393172a];
aes = new sjcl.cipher.aes(key);
r = aes.encrypt(test);
console.log(r);

But I can not reach it in the C# 但是我无法在C#中达到它

    [TestMethod]
    public void EncryptIntsToInts()
    {
        Int32[] key = { unchecked((Int32)0x2b7e1516), 0x28aed2a6, unchecked((Int32)0xabf71588), 0x09cf4f3c };
        Int32[] test = { 0x6bc1bee2,0x2e409f96,unchecked((Int32)0xe93d7e11),0x7393172a };
        Int32[] answer = { 0x3ad77bb4, 0x0d7a3660, unchecked((Int32)0xa89ecaf3), 0x2466ef97 };

        var r = AES.EncryptIntsToInts(test, key.ToByteArray());

        Assert.IsTrue(r.SequenceEqual(answer));
    }


    static byte[] zeroIV = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

    public static Int32[] EncryptIntsToInts(Int32[] input, byte[] key)
    {
        // Check arguments.
        if (input == null || input.Length <= 0)
            throw new ArgumentNullException("input");
        if (key == null || key.Length <= 0)
            throw new ArgumentNullException("key");

        // Declare the RijndaelManaged object
        // used to encrypt the data.
        RijndaelManaged aesAlg = null;
        byte[] bResult;
        try
        {
            aesAlg = new RijndaelManaged
                         {
                             Key = key,
                             Mode = CipherMode.ECB,
                             Padding = PaddingMode.None,
                             KeySize = 128,
                             BlockSize = 128,
                             IV = zeroIV
                         };
            ICryptoTransform encryptor = aesAlg.CreateEncryptor();

            byte[] bInput = new byte[input.Length * sizeof(int)];
            Buffer.BlockCopy(input, 0, bInput, 0, bInput.Length);

            bResult = encryptor.TransformFinalBlock(bInput, 0, input.Length);
        }
        finally
        {
            if (aesAlg != null)
                aesAlg.Clear();
        }

        int[] iResult = new int[bResult.Length / sizeof(int)];
        Buffer.BlockCopy(bResult, 0, iResult, 0, bResult.Length);
        return iResult;
    }

What is my error? 我的错误是什么?

======================================================== ================================================== ======

Start edit 开始编辑

New code in which right order of the bytes, but it does not work 新代码中的字节顺序正确,但它不起作用

    [TestMethod]
    public void EncryptIntsToInts()
    {
        byte[] key =     "2b7e151628aed2a6abf7158809cf4f3c".HEX2Bytes();
        byte[] test =    "6bc1bee22e409f96e93d7e117393172a".HEX2Bytes();
        byte[] answer =  "3ad77bb40d7a3660a89ecaf32466ef97".HEX2Bytes();

        RijndaelManaged aesAlg = new RijndaelManaged
        {
            Key = key,
            Mode = CipherMode.ECB,
            Padding = PaddingMode.PKCS7,
            KeySize = 128,
            BlockSize = 128,
            IV = zeroIV
        };
        ICryptoTransform encryptor = aesAlg.CreateEncryptor();

        var r = encryptor.TransformFinalBlock(test, 0, test.Length);

        Assert.IsTrue(r.SequenceEqual(answer));
    }

    public static byte[] HEX2Bytes(this string hex)
    {
        if (hex.Length%2 != 0)
        {
            throw new ArgumentException(String.Format(CultureInfo.InvariantCulture,
                                                      "The binary key cannot have an odd number of digits: {0}", hex));
        }

        byte[] HexAsBytes = new byte[hex.Length/2];
        for (int index = 0; index < HexAsBytes.Length; index++)
        {
            string byteValue = hex.Substring(index*2, 2);
            HexAsBytes[index] = byte.Parse(byteValue, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
        }

        return HexAsBytes;
    }

    static byte[] zeroIV = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

Right code (just add a try / using ): 正确的代码(只需添加一个试用 / 使用 ):

        [TestMethod]
        public void EncryptIntsToInts()
        {    
            byte[] key =     "2b7e151628aed2a6abf7158809cf4f3c".HEX2Bytes();
            byte[] test =    "6bc1bee22e409f96e93d7e117393172a".HEX2Bytes();
            byte[] answer =  "3ad77bb40d7a3660a89ecaf32466ef97".HEX2Bytes();

            var r = AES.Encrypt(test, key);

            Assert.IsTrue(answer.SequenceEqual(r));
        }

public static byte[] Encrypt(byte[] input, byte[] key)
{
    var aesAlg = new AesManaged
                     {
                         KeySize = 128,
                         Key = key,
                         BlockSize = 128,
                         Mode = CipherMode.ECB,
                         Padding = PaddingMode.Zeros,
                         IV = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
                     };

    ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
    return encryptor.TransformFinalBlock(input, 0, input.Length);
}

You use 32 bit integers to define the key. 您使用32位整数来定义键。 When you transform them to bytes, you use native endianness, which typically is little endian. 将它们转换为字节时,使用本机字节序,通常是小端。 So your key is 16157e2b a6... and not 2b7e1516 28... . 所以你的关键是16157e2b a6...而不是2b7e1516 28...

I wouldn't use int s to represent a key in the first place. 我不会首先使用int来表示密钥。 But if you really want to, write a big endian conversion function. 但是,如果你真的想,写一个大端转换函数。

I also strongly recommend against ECB mode. 我也强烈建议不要使用ECB模式。 You could use CBC together with HMAC (in an encrypt then mac construction), or use a third party lib to implement GCM. 您可以将CBC与HMAC一起使用(在加密然后是mac构造中),或使用第三方lib来实现GCM。

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

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