Refactor all cryptography codes to RarRijndael

This commit is contained in:
Hamdanil Rasyid
2013-07-15 23:43:26 +08:00
parent a73c831647
commit 3370fadbd1
3 changed files with 70 additions and 63 deletions

View File

@@ -11,9 +11,8 @@ namespace SharpCompress.Common.Rar
{
private readonly Stream _actualStream;
private byte[] _salt;
private Rijndael _rijndael;
private RarRijndael _rijndael;
private readonly string _password;
private byte[] _aesInitializationVector;
private Queue<byte> _data = new Queue<byte>();
public RarCryptoWrapper(Stream actualStream, string password)
@@ -35,7 +34,7 @@ namespace SharpCompress.Common.Rar
private void InitializeAes()
{
_rijndael = RarRijndael.Initialize(out _aesInitializationVector, _password, _salt);
_rijndael = RarRijndael.InitializeFrom(_password, _salt);
}
@@ -75,33 +74,16 @@ namespace SharpCompress.Common.Rar
byte[] cipherText = new byte[RarRijndael.CryptoBlockSize];
_actualStream.Read(cipherText, 0, RarRijndael.CryptoBlockSize);
byte[] plainText = new byte[RarRijndael.CryptoBlockSize];
var decryptor = _rijndael.CreateDecryptor();
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
csDecrypt.ReadFully(plainText);
}
}
var readBytes = _rijndael.ProcessBlock(cipherText);
foreach(var readByte in readBytes)
_data.Enqueue(readByte);
for (int j = 0; j < plainText.Length; j++)
{
_data.Enqueue((byte) (plainText[j] ^ _aesInitializationVector[j%16])); //32:114, 33:101
}
for (int j = 0; j < _aesInitializationVector.Length; j++)
{
_aesInitializationVector[j] = cipherText[j];
}
}
for (int i = 0; i < count; i++)
{
buffer[offset+i] = _data.Dequeue();
}
}
return count;

View File

@@ -1,30 +1,42 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
namespace SharpCompress.Common.Rar
{
class RarRijndael
class RarRijndael : IDisposable
{
private readonly string _password;
private readonly byte[] _salt;
private byte[] _aesInitializationVector;
private Rijndael _rijndael;
private RarRijndael(string password, byte[] salt)
{
_password = password;
_salt = salt;
}
internal const int CryptoBlockSize = 16;
internal static Rijndael Initialize(out byte[] aesInitializationVector, string password, byte[] salt)
private void Initialize()
{
var rijndael = new RijndaelManaged() {Padding = PaddingMode.None};
aesInitializationVector = new byte[CryptoBlockSize];
int rawLength = 2 * password.Length;
_rijndael = new RijndaelManaged() {Padding = PaddingMode.None};
_aesInitializationVector = new byte[CryptoBlockSize];
int rawLength = 2 * _password.Length;
byte[] rawPassword = new byte[rawLength + 8];
byte[] passwordBytes = Encoding.UTF8.GetBytes(password);
for (int i = 0; i < password.Length; i++)
byte[] passwordBytes = Encoding.UTF8.GetBytes(_password);
for (int i = 0; i < _password.Length; i++)
{
rawPassword[i * 2] = passwordBytes[i];
rawPassword[i * 2 + 1] = 0;
}
for (int i = 0; i < salt.Length; i++)
for (int i = 0; i < _salt.Length; i++)
{
rawPassword[i + rawLength] = salt[i];
rawPassword[i + rawLength] = _salt[i];
}
var sha = new SHA1Managed();
@@ -40,7 +52,7 @@ namespace SharpCompress.Common.Rar
if (i % (noOfRounds / CryptoBlockSize) == 0)
{
digest = sha.ComputeHash(bytes.ToArray());
aesInitializationVector[i / (noOfRounds / CryptoBlockSize)] = digest[19];
_aesInitializationVector[i / (noOfRounds / CryptoBlockSize)] = digest[19];
}
}
@@ -55,10 +67,44 @@ namespace SharpCompress.Common.Rar
((digest[i * 4 + 2] * 0x100) & 0xff00) |
digest[i * 4 + 3] & 0xff) >> (j * 8));
rijndael.IV = new byte[CryptoBlockSize];
rijndael.Key = aesKey;
rijndael.BlockSize = CryptoBlockSize * 8;
_rijndael.IV = new byte[CryptoBlockSize];
_rijndael.Key = aesKey;
_rijndael.BlockSize = CryptoBlockSize * 8;
return;
}
public static RarRijndael InitializeFrom(string password, byte[] salt)
{
var rijndael = new RarRijndael(password, salt);
rijndael.Initialize();
return rijndael;
}
public byte[] ProcessBlock(byte[] cipherText)
{
var plainText = new byte[CryptoBlockSize];
var decryptedBytes = new List<byte>();
var decryptor = _rijndael.CreateDecryptor();
using (var msDecrypt = new MemoryStream(cipherText))
{
using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
csDecrypt.ReadFully(plainText);
}
}
for (int j = 0; j < plainText.Length; j++)
decryptedBytes.Add((byte)(plainText[j] ^ _aesInitializationVector[j % 16])); //32:114, 33:101
for (int j = 0; j < _aesInitializationVector.Length; j++)
_aesInitializationVector[j] = cipherText[j];
return decryptedBytes.ToArray();
}
public void Dispose()
{
_rijndael.Dispose();
}
}
}

View File

@@ -14,7 +14,7 @@ namespace SharpCompress.IO
private readonly string _password;
private byte[] _aesInitializationVector;
private byte[] _aesKey = new byte[16];
private Rijndael _rijndael;
private RarRijndael _rijndael;
private Queue<byte> _data = new Queue<byte>();
public MarkingBinaryReader(Stream stream, string password = null)
@@ -38,7 +38,7 @@ namespace SharpCompress.IO
private void InitializeAes()
{
_rijndael = RarRijndael.Initialize(out _aesInitializationVector, _password, _salt);
_rijndael = RarRijndael.InitializeFrom(_password, _salt);
}
@@ -100,30 +100,9 @@ namespace SharpCompress.IO
{
//long ax = System.currentTimeMillis();
byte[] cipherText = base.ReadBytes(16);
byte[] plainText = new byte[16];
var decryptor = _rijndael.CreateDecryptor();
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
csDecrypt.ReadFully(plainText);
}
}
for (int j = 0; j < plainText.Length; j++)
{
_data.Enqueue((byte)(plainText[j] ^ _aesInitializationVector[j % 16])); //32:114, 33:101
}
for (int j = 0; j < _aesInitializationVector.Length; j++)
{
_aesInitializationVector[j] = cipherText[j];
}
var readBytes = _rijndael.ProcessBlock(cipherText);
foreach (var readByte in readBytes)
_data.Enqueue(readByte);
}