mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-09-23 15:34:34 +00:00
Refactor all cryptography codes to RarRijndael
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user