W
William Stacey [MVP]
The Decypt2() method below does not work. It completes, but does not do the
right thing. The first transform request returns 0 bytes. The first
Decypt() method works as we work on a stream instead of blocks. I would
like to know how to get the block method working. TIA.
using System;
using System.IO;
using System.Security.Cryptography;
namespace SocketServers.Crypto
{
/// <summary>
/// Summary description for MyCrypto.
/// </summary>
public class MyCrypto
{
const string s_plaintext = @"c:\mytext.txt";
const string s_ciphertext = @"c:\mytext.bin";
const string s_decrypted = @"c:\mytext2.txt";
public void RunTest()
{
using(SymmetricAlgorithm algo = SymmetricAlgorithm.Create("Rijndael"))
{
algo.Padding = PaddingMode.PKCS7;
algo.BlockSize = 256; // 32 bytes;
Console.WriteLine("Block size:"+algo.BlockSize);
KeySizes[] blockSizes = algo.LegalBlockSizes;
foreach(KeySizes keysize in blockSizes)
{
Console.WriteLine("Max size:"+keysize.MaxSize);
Console.WriteLine("Min size:"+keysize.MinSize);
}
Encrypt(algo);
Decrypt2(algo);
}
}
public void Encrypt(SymmetricAlgorithm algo)
{
using( Stream cipherText = GetWriteableFileStream(s_ciphertext) )
using( ICryptoTransform enc = algo.CreateEncryptor() )
using( CryptoStream crypt = GetWriteCryptoStream(cipherText, enc) )
using( Stream input = GetReadOnlyFileStream(s_plaintext) )
{
Pump(input, crypt);
crypt.Close(); //have to call, not called by Dispose
}
}
public void Decrypt(SymmetricAlgorithm algo)
{
using( Stream cipherText = GetReadOnlyFileStream(s_ciphertext) )
using( ICryptoTransform enc = algo.CreateDecryptor() )
using( CryptoStream decrypt = GetReadCryptoStream(cipherText, enc) )
using( Stream output = GetWriteableFileStream(s_decrypted) )
{
Pump(decrypt, output);
Console.WriteLine("In File Stream len:"+cipherText.Length);
Console.WriteLine("In Stream Blocks:"+
((double)((double)cipherText.Length / 32)));
decrypt.Close(); // have to call, not called by Dispose
}
}
public void Decrypt2(SymmetricAlgorithm algo)
{
ICryptoTransform dec = algo.CreateDecryptor();
Stream inStream = GetReadOnlyFileStream(s_ciphertext);
Stream outStream = GetWriteableFileStream(s_decrypted);
try
{
byte[] inBlock = new byte[32];
byte[] outBlock = new byte[32];
// Read input stream in blocks (32 bytes) until end, and transform the
blocks
// and write to outStream.
int count = 0;
int outCount = 0;
while ( (count = inStream.Read(inBlock, 0, inBlock.Length)) != 0 )
{
outCount = dec.TransformBlock(inBlock, 0, count, outBlock, 0);
outStream.Write(outBlock, 0, outCount);
Console.WriteLine("OutCount:"+outCount);
}
outStream.Flush();
}
finally
{
outStream.Close();
inStream.Close();
}
}
private static void Pump(Stream input, Stream output)
{
byte[] buffer = new byte[10];
int count = 0;
while( (count = input.Read(buffer, 0, 10)) != 0 )
{
output.Write(buffer, 0, count);
}
}
private static FileStream GetReadOnlyFileStream(string path)
{
return new FileStream(path, FileMode.Open, FileAccess.Read);
}
private static FileStream GetWriteableFileStream(string path)
{
return new FileStream(path, FileMode.Create, FileAccess.Write);
}
private static CryptoStream GetWriteCryptoStream(Stream stream,
ICryptoTransform transform)
{
return new CryptoStream(stream, transform, CryptoStreamMode.Write);
}
private static CryptoStream GetReadCryptoStream(Stream stream,
ICryptoTransform transform)
{
return new CryptoStream(stream, transform, CryptoStreamMode.Read);
}
}
}
right thing. The first transform request returns 0 bytes. The first
Decypt() method works as we work on a stream instead of blocks. I would
like to know how to get the block method working. TIA.
using System;
using System.IO;
using System.Security.Cryptography;
namespace SocketServers.Crypto
{
/// <summary>
/// Summary description for MyCrypto.
/// </summary>
public class MyCrypto
{
const string s_plaintext = @"c:\mytext.txt";
const string s_ciphertext = @"c:\mytext.bin";
const string s_decrypted = @"c:\mytext2.txt";
public void RunTest()
{
using(SymmetricAlgorithm algo = SymmetricAlgorithm.Create("Rijndael"))
{
algo.Padding = PaddingMode.PKCS7;
algo.BlockSize = 256; // 32 bytes;
Console.WriteLine("Block size:"+algo.BlockSize);
KeySizes[] blockSizes = algo.LegalBlockSizes;
foreach(KeySizes keysize in blockSizes)
{
Console.WriteLine("Max size:"+keysize.MaxSize);
Console.WriteLine("Min size:"+keysize.MinSize);
}
Encrypt(algo);
Decrypt2(algo);
}
}
public void Encrypt(SymmetricAlgorithm algo)
{
using( Stream cipherText = GetWriteableFileStream(s_ciphertext) )
using( ICryptoTransform enc = algo.CreateEncryptor() )
using( CryptoStream crypt = GetWriteCryptoStream(cipherText, enc) )
using( Stream input = GetReadOnlyFileStream(s_plaintext) )
{
Pump(input, crypt);
crypt.Close(); //have to call, not called by Dispose
}
}
public void Decrypt(SymmetricAlgorithm algo)
{
using( Stream cipherText = GetReadOnlyFileStream(s_ciphertext) )
using( ICryptoTransform enc = algo.CreateDecryptor() )
using( CryptoStream decrypt = GetReadCryptoStream(cipherText, enc) )
using( Stream output = GetWriteableFileStream(s_decrypted) )
{
Pump(decrypt, output);
Console.WriteLine("In File Stream len:"+cipherText.Length);
Console.WriteLine("In Stream Blocks:"+
((double)((double)cipherText.Length / 32)));
decrypt.Close(); // have to call, not called by Dispose
}
}
public void Decrypt2(SymmetricAlgorithm algo)
{
ICryptoTransform dec = algo.CreateDecryptor();
Stream inStream = GetReadOnlyFileStream(s_ciphertext);
Stream outStream = GetWriteableFileStream(s_decrypted);
try
{
byte[] inBlock = new byte[32];
byte[] outBlock = new byte[32];
// Read input stream in blocks (32 bytes) until end, and transform the
blocks
// and write to outStream.
int count = 0;
int outCount = 0;
while ( (count = inStream.Read(inBlock, 0, inBlock.Length)) != 0 )
{
outCount = dec.TransformBlock(inBlock, 0, count, outBlock, 0);
outStream.Write(outBlock, 0, outCount);
Console.WriteLine("OutCount:"+outCount);
}
outStream.Flush();
}
finally
{
outStream.Close();
inStream.Close();
}
}
private static void Pump(Stream input, Stream output)
{
byte[] buffer = new byte[10];
int count = 0;
while( (count = input.Read(buffer, 0, 10)) != 0 )
{
output.Write(buffer, 0, count);
}
}
private static FileStream GetReadOnlyFileStream(string path)
{
return new FileStream(path, FileMode.Open, FileAccess.Read);
}
private static FileStream GetWriteableFileStream(string path)
{
return new FileStream(path, FileMode.Create, FileAccess.Write);
}
private static CryptoStream GetWriteCryptoStream(Stream stream,
ICryptoTransform transform)
{
return new CryptoStream(stream, transform, CryptoStreamMode.Write);
}
private static CryptoStream GetReadCryptoStream(Stream stream,
ICryptoTransform transform)
{
return new CryptoStream(stream, transform, CryptoStreamMode.Read);
}
}
}