首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AES的CRT模式

AES的CRT模式
EN

Code Review用户
提问于 2017-05-24 18:04:52
回答 1查看 347关注 0票数 1

我需要为AES实现CRT模式,并编写了以下代码。但我不是专家,所以我想知道专家的意见,这是对的,或者我犯了一些会导致安全问题的错误。

为了尽量减少代码的阅读难度,我删除了一些方法,并在它们使用的地方添加了一些注释。

此类可能更改输入数据的大小。我知道在编解码类中这样做不是个好主意,但是根据程序条件,在那里这样做要容易得多。

如果您需要更多的细节,请评论。如果你推荐笔记让它更安全更好的话,我会很感激。

注:我问了这个问题,那里,他们建议我在这里问这个问题。

编辑:谢谢你的回答和评论,但我更关心的是安全。这段代码安全吗?

代码语言:javascript
复制
public class Rij : IDisposable
        {
            private const int defaultMaxRijendaelNumber = 2;
            private const int blockSize = 128;
            private const int blockSizeInBytes = 16;
            public enum Type { Coder, Decoder };
            private Type instanceType = Type.Coder;
            private int maxRijendaelNumber = defaultMaxRijendaelNumber;
            private long allLength = 0;
            private long doneLength = 0;
            private byte[] counter = new byte[blockSizeInBytes];
            private RijndaelManaged rijndael = null;
            private ICryptoTransform crypto = null;
            private bool disposed = false;
            //-----------------------------------------------------------
            public Rij(Type type, string pass, byte[] salt, byte[] counterStartValue, long size)
            {
                int iteration = 50000;
                byte[] passWordSalt = (byte[])salt.Clone();
                byte[] passArray = ConvertToByteArray(pass);
                byte[] passWord = new byte[0];
                Rfc2898DeriveBytes rfcPass = new Rfc2898DeriveBytes(passArray, passWordSalt, iteration);
                FillWithZero(ref passArray);
                passWord = rfcPass.GetBytes(16);
                counter = (byte[])counterStartValue.Clone();
                instanceType = type;

                rijndael = new RijndaelManaged();
                rijndael.Mode = CipherMode.ECB;
                rijndael.Key = passWord;
                rijndael.BlockSize = blockSize;
                rijndael.Padding = PaddingMode.None;

                FillWithZero(ref passWord);
                allLength = size;

                if (type == Type.Coder) { crypto = rijndael.CreateEncryptor(); }
                else { crypto = rijndael.CreateDecryptor(); }
            }
            //-----------------------------------------------------------
            public void RijCoder(ref byte[] bufferToCode)
            {
                try
                {
                    byte[] buffer = bufferToCode;

                    //make size dividable by 16
                    if (doneLength + buffer.Length == allLength && allLength % blockSizeInBytes != 0)
                    {
                        int addableLength = Convert.ToInt32(blockSizeInBytes - (allLength % blockSizeInBytes));
                        byte[] bufferHelper = new byte[buffer.Length + addableLength];
                        byte[] fakeData = new byte[addableLength];
                        Array.Copy(buffer, 0, bufferHelper, 0, buffer.Length);
                        buffer = bufferHelper;
                    }

                    //divide length for useing multi task
                    int[] partsSize = DivideSize(buffer.Length);

                    Task[] tasks = new Task[partsSize.Length];
                    List<byte[]> counters = new List<byte[]>();//counter(iv) for each task
                    int[] startIndexes = new int[partsSize.Length];//start index in buffer for each task

                    int startIndex = 0;
                    int oldStartIndex = 0;
                    for (int i = 0; i < partsSize.Length; i++)
                    {
                        startIndexes[i] = startIndex;

                        //set counter
                        counters.Add((byte[])counter.Clone());

                        //update startIndex,counter 
                        oldStartIndex = startIndex;
                        startIndex += partsSize[i];

                        //update counter
                        increaseCounter(counter, (startIndex - oldStartIndex) / blockSizeInBytes);
                    }

                    //run
                    var parentTask = Task.Factory.StartNew(() =>
                    {
                        for (int m = 0; m < partsSize.Length; m++)
                        {
                            int index = m;

                            tasks[index] = Task.Factory.StartNew(() =>
                            {
                                CodePart(buffer, counters[index], startIndexes[index], partsSize[index]);
                            });
                        }
                    });

                    //wait
                    try
                    {
                        parentTask.Wait();
                        Task.WaitAll(tasks);
                    }
                    catch (AggregateException)
                    { throw new Exception("exeption in encoding tasks"); }

                    bufferToCode = buffer;
                    doneLength += buffer.Length;
                }
                catch (Exception ex)
                {
                    throw new Exception(ex.Message);
                }
            }

            private void CodePart(byte[] buffer, byte[] counterForPart, int startByte, int length)
            {
                try
                {
                    if (length == 0) { return; }

                    for (int i = 0; i < length; i += blockSizeInBytes)
                    {
                        for (int j = 0; j < blockSizeInBytes; j++)
                        { buffer[startByte + i + j] ^= counterForPart[j];  }

                        IncreaseCounterByOne(counterForPart);
                    }

                    Array.Copy(crypto.TransformFinalBlock(buffer, startByte, length), 0, buffer, startByte, length);
                }
                catch (Exception ex)
                {
                    throw new Exception(ex.Message);
                }
            }

            private void IncreaseCounterByOne(byte[] bytes)
            {
                for (int i = bytes.Length - 1; i >= 0; i--)
                {
                    if (bytes[i] == byte.MaxValue)
                    { bytes[i] = 0; }
                    else
                    { bytes[i]++; break; }
                }
            }

            public void Dispose()
            {
                Dispose(true);
                GC.SuppressFinalize(this);
            }

            protected virtual void Dispose(bool disposing)
            {
                if (disposed) { return; }

                rijndael.Dispose();
                disposed = true;
            }
        }
EN

回答 1

Code Review用户

发布于 2017-05-24 19:48:46

像这样的事情

catch (AggregateException) {抛出新异常(“编码任务中的暴露”);}

或者是那个

捕获(异常ex) {抛出新异常(ex.Message);}

我希望你永远不用调试这样的代码。这是你能写的最糟糕的了。你泄露了所有关于哪里出了问题的信息。整个堆栈跟踪、行号、方法名,在第一种情况下,所有内部异常。如果你不处理任何事情,不要做任何事。让它泡泡,让用户来处理它。

票数 4
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/164122

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档