我需要为AES实现CRT模式,并编写了以下代码。但我不是专家,所以我想知道专家的意见,这是对的,或者我犯了一些会导致安全问题的错误。
为了尽量减少代码的阅读难度,我删除了一些方法,并在它们使用的地方添加了一些注释。
此类可能更改输入数据的大小。我知道在编解码类中这样做不是个好主意,但是根据程序条件,在那里这样做要容易得多。
如果您需要更多的细节,请评论。如果你推荐笔记让它更安全更好的话,我会很感激。
注:我问了这个问题,那里,他们建议我在这里问这个问题。
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;
}
}发布于 2017-05-24 19:48:46
像这样的事情
catch (AggregateException) {抛出新异常(“编码任务中的暴露”);}
或者是那个
捕获(异常ex) {抛出新异常(ex.Message);}
我希望你永远不用调试这样的代码。这是你能写的最糟糕的了。你泄露了所有关于哪里出了问题的信息。整个堆栈跟踪、行号、方法名,在第一种情况下,所有内部异常。如果你不处理任何事情,不要做任何事。让它泡泡,让用户来处理它。
https://codereview.stackexchange.com/questions/164122
复制相似问题