The following classes implement file encryption and decryption, and there are no problems with the test of several file types. Please share with us now.
Namespace mycryptohelp
{
/// <Summary>
/// Exception handling class
/// </Summary>
Public class cryptohelpexception: applicationexception
{
Public cryptohelpexception (string MSG): Base (MSG)
{
}
}
/// <Summary>
/// Crypthelp
/// </Summary>
Public class cryptohelp
{
Private const ulong fc_tag = 0xfc010203040506cf;
Private const
Int buffer_size = 128*1024;
/// <Summary>
/// Check whether the two byte arrays are the same
/// </Summary>
/// <Param name = "B1"> byte array </param>
/// <Param name = "B2"> byte array </param>
/// <Returns> true-equal </returns>
Private Static bool checkbytearrays (byte [] B1, byte [] B2)
{
If (b1.length = b2.length)
{
For (INT I = 0;
I <b1.length;
++ I)
{
If (b1 [I]! = B2 [I])
Return false;
}
Return true;
}
Return false;
}
/// <Summary>
/// Create Rijndael into ricalgorithm
/// </Summary>
/// <Param name = "password"> password </param>
/// <Param name = "salt"> </param>
/// <Returns> encrypted object </returns>
Private Static response ricalgorithm createrijndael (string password, byte [] salt)
{
Passwordderivebytes PDB = new passwordderivebytes (password, salt, "sha256", 1000 );
Repeated ricalgorithm SMA = Rijndael. Create ();
SMA. Key size = 256;
SMA. Key = PDB. getbytes (32 );
SMA. Padding = paddingmode. pkcs7;
Return SMA;
}
/// <Summary>
/// Generate random number of encrypted files
/// </Summary>
Private Static randomnumbergenerator Rand = new rngcryptoserviceprovider ();
/// <Summary>
/// Generate a random byte array of the specified length
/// </Summary>
/// <Param name = "count"> byte array length </param>
/// <Returns> random byte array </returns>
Private Static byte [] generaterandombytes (INT count)
{
Byte [] bytes = new byte [count];
Rand. getbytes (bytes );
Return bytes;
}
/// <Summary>
/// Encrypt the file
/// </Summary>
/// <Param name = "infile"> file to be encrypted </param>
/// <Param name = "OUTFILE"> encrypted input file </param>
/// <Param name = "password"> encrypt the password </param>
Public static void encryptfile (string infile,
String OUTFILE,
String password)
{
Using (filestream fin = file. openread (infile ),
Fout = file. openwrite (OUTFILE ))
{
Long lsize = fin. length;
// Input file length
Int size = (INT) lsize;
Byte [] bytes = new byte [buffer_size];
// Cache
Int READ =-1;
// Number of input files read
Int value = 0;
// Obtain IV and salt
Byte [] IV = generaterandombytes (16 );
Byte [] salt = generaterandombytes (16 );
// Create an encrypted object
Using ricalgorithm SMA = cryptohelp. createrijndael (password, salt );
SMA. IV = IV;
// Write IV and salt at the beginning of the output file
Fout. Write (IV, 0, IV. Length );
Fout. Write (salt, 0, Salt. Length );
// Create hash Encryption
Hashalgorithm hasher = sha256.create ();
Using (cryptostream cout = new cryptostream (fout, SMA. createencryptor (), cryptostreammode. Write ),
Chash = new cryptostream (stream. null, hasher, cryptostreammode. Write ))
{
Binarywriter BW = new binarywriter (cout );
Bw. Write (lsize );
Bw. Write (fc_tag );
// Read/write bytes to the encrypted Stream Buffer
While (read = fin. Read (bytes, 0, bytes. Length ))! = 0)
{
Cout. Write (bytes, 0, read );
Chash. Write (bytes, 0, read );
Value + = read;
}
// Disable the encrypted stream
Chash. Flush ();
Chash. Close ();
// Read the hash
Byte [] hash = hasher. Hash;
// Input file write hash
Cout. Write (hash, 0, hash. Length );
// Close the file stream
Cout. Flush ();
Cout. Close ();
}
}
}
/// <Summary>
/// Decrypt the file
/// </Summary>
/// <Param name = "infile"> files to be decrypted </param>
/// <Param name = "OUTFILE"> decrypted output file </param>
/// <Param name = "password"> decrypt the password </param>
Public static void decryptfile (string infile,
String OUTFILE,
String password)
{
// Create an open file stream
Using (filestream fin = file. openread (infile ),
Fout = file. openwrite (OUTFILE ))
{
Int size = (INT) Fin. length;
Byte [] bytes = new byte [buffer_size];
Int READ =-1;
Int value = 0;
Int outvalue = 0;
Byte [] IV = new byte [16];
Fin. Read (IV, 0, 16 );
Byte [] salt = new byte [16];
Fin. Read (salt, 0, 16 );
Using ricalgorithm SMA = cryptohelp. createrijndael (password, salt );
SMA. IV = IV;
Value = 32;
Long lsize =-1;
// Create a hash object and verify the file
Hashalgorithm hasher = sha256.create ();
Using (cryptostream CIN = new cryptostream (FIN, SMA. createdecryptor (), cryptostreammode. Read ),
Chash = new cryptostream (stream. null, hasher, cryptostreammode. Write ))
{
// Read the object Length
Binaryreader BR = new binaryreader (CIN );
Lsize = Br. readint64 ();
Ulong tag = Br. readuint64 ();
If (fc_tag! = Tag)
Throw new cryptohelpexception ("file damaged ");
Long numreads = lsize/buffer_size;
Long slack = (long) lsize % buffer_size;
For (INT I = 0;
I <numreads;
++ I)
{
Read = cin. Read (bytes, 0, bytes. Length );
Fout. Write (bytes, 0, read );
Chash. Write (bytes, 0, read );
Value + = read;
Outvalue + = read;
}
If (Slack> 0)
{
Read = cin. Read (bytes, 0, (INT) Slack );
Fout. Write (bytes, 0, read );
Chash. Write (bytes, 0, read );
Value + = read;
Outvalue + = read;
}
Chash. Flush ();
Chash. Close ();
Fout. Flush ();
Fout. Close ();
Byte [] curhash = hasher. Hash;
// Obtain the comparison and old hash objects
Byte [] oldhash = new byte [hasher. hashsize/8];
Read = cin. Read (oldhash, 0, oldhash. Length );
If (oldhash. length! = Read) | (! Checkbytearrays (oldhash, curhash )))
Throw new cryptohelpexception ("file damaged ");
}
If (outvalue! = Lsize)
Throw new cryptohelpexception ("file size mismatch ");
}
}
}
}
// Call
Public class testclass
{
String mypassword = "test_password _~! @#";
String myplainfile = "test.txt ";
String myencryptedfile = "test. encrypted ";
String mydecryptedfile = "test. decrypted ";
[Stathread]
Static void main ()
{
Cryptohelp. encryptfile (myplainfile, myencryptedfile, mypassword );
Cryptohelp. decryptfile (myencryptedfile, mydecryptedfile, mypassword );
}
}