// // Crypt.cs: Encrypt/Decrypt sample - for educational use only // // Author: // Sebastien Pouliot (spouliot@motus.com) // // (C) 2003 Motus Technologies Inc. (http://www.motus.com) // // MIT X.11 LICENSE // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.IO; using System.Security.Cryptography; using System.Text; namespace Motus.Samples { class Crypt { static byte[] ReadFile (string filename) { if (!File.Exists (filename)) { Console.WriteLine ("Couldn't find file {0}", filename); return null; } byte[] content; using (FileStream fs = File.OpenRead (filename)) { content = new byte [fs.Length]; fs.Read (content, 0, content.Length); fs.Close (); } return content; } static string ReadTextFile (string filename) { return Encoding.UTF8.GetString (ReadFile (filename)); } static RSA ReadKeypair (string filename) { // find the keyfile string keyname = filename; if (!File.Exists (keyname)) { keyname = filename + ".key"; if (!File.Exists (keyname)) { keyname = filename + ".pub"; } } if (!File.Exists (keyname)) { Console.WriteLine ("Couldn't find key: {0}, {0}.pub or {0}.key", filename); return null; } string key = ReadTextFile (keyname); RSA rsa = RSA.Create (); rsa.FromXmlString (key); return rsa; } static void WriteFile (string filename, byte[] content) { if (File.Exists (filename)) File.Delete (filename); using (FileStream fs = File.OpenWrite (filename)) { fs.Write (content, 0, content.Length); fs.Close (); } } static void WriteFile (string filename, string content) { WriteFile (filename, Encoding.UTF8.GetBytes (content)); } static byte[] Encrypt (RSA rsa, byte[] input) { // by default this will create a 128 bits AES (Rijndael) object SymmetricAlgorithm sa = SymmetricAlgorithm.Create (); ICryptoTransform ct = sa.CreateEncryptor (); byte[] encrypt = ct.TransformFinalBlock (input, 0, input.Length); RSAPKCS1KeyExchangeFormatter fmt = new RSAPKCS1KeyExchangeFormatter (rsa); byte[] keyex = fmt.CreateKeyExchange (sa.Key); // return the key exchange, the IV (public) and encrypted data byte[] result = new byte [keyex.Length + sa.IV.Length + encrypt.Length]; Buffer.BlockCopy (keyex, 0, result, 0, keyex.Length); Buffer.BlockCopy (sa.IV, 0, result, keyex.Length, sa.IV.Length); Buffer.BlockCopy (encrypt, 0, result, keyex.Length + sa.IV.Length, encrypt.Length); return result; } static byte[] Decrypt (RSA rsa, byte[] input) { // by default this will create a 128 bits AES (Rijndael) object SymmetricAlgorithm sa = SymmetricAlgorithm.Create (); byte[] keyex = new byte [rsa.KeySize >> 3]; Buffer.BlockCopy (input, 0, keyex, 0, keyex.Length); RSAPKCS1KeyExchangeDeformatter def = new RSAPKCS1KeyExchangeDeformatter (rsa); byte[] key = def.DecryptKeyExchange (keyex); byte[] iv = new byte [sa.IV.Length]; Buffer.BlockCopy (input, keyex.Length, iv, 0, iv.Length); ICryptoTransform ct = sa.CreateDecryptor (key, iv); byte[] decrypt = ct.TransformFinalBlock (input, keyex.Length + iv.Length, input.Length - (keyex.Length + iv.Length)); return decrypt; } static void Header () { Console.WriteLine ("CRYPT sample for educational use only"); Console.WriteLine ("Copyright 2003 Motus Technologies. All rights reserved. Released under MIT X.11{0}", Environment.NewLine); } static void Help () { Console.WriteLine ("Usage:"); Console.WriteLine ("crypt /k 'keypair'"); Console.WriteLine ("\tCreate a new keypair. The file 'keypair'.key contains both the private"); Console.WriteLine ("\tand public keys and you should it really private (it's not encrypted)."); Console.WriteLine ("\tThe file 'keypair'.pub only contains the public key and can be shared"); Console.WriteLine ("\twith your friends."); Console.WriteLine ("crypt /e 'file' 'keypair'"); Console.WriteLine ("\tThis will encrypt the file 'file' using the public key contained in the"); Console.WriteLine ("\tfile keypair."); Console.WriteLine ("crypt /d 'file' 'keypair'"); Console.WriteLine ("\tThis will decrypt the file 'file' using the private key contained in"); Console.WriteLine ("\tthe file 'keypair'"); Console.WriteLine ("{0}WARNING: Existing files will be OVERWRITTEN without confirmation!", Environment.NewLine); } static void Error (string error) { Help (); Console.WriteLine ("{0}ERROR: {1}{0}", Environment.NewLine, error); } static void CreateKeypair (string filename) { RSA rsa = RSA.Create (); WriteFile (filename + ".key", rsa.ToXmlString (true)); Console.WriteLine ("Created private file {0}.key", filename); WriteFile (filename + ".pub", rsa.ToXmlString (false)); Console.WriteLine ("Created public file {0}.pub", filename); } static void EncryptFile (string filename, string keyfile) { RSA rsa = ReadKeypair (keyfile); if (rsa != null) { byte[] input = ReadFile (filename); if (input != null) { byte[] encrypted = Encrypt (rsa, input); WriteFile (filename + ".enc", encrypted); } } } static void DecryptFile (string filename, string keyfile) { RSA rsa = ReadKeypair (keyfile); if (rsa != null) { byte[] input = ReadFile (filename); if (input != null) { byte[] decrypted = Decrypt (rsa, input); if (filename.EndsWith (".enc")) filename = filename.Substring (0, filename.Length - 4); else filename += ".dec"; WriteFile (filename, decrypted); } } } [STAThread] static void Main (string[] args) { Header (); if (args.Length < 1) { Help (); return; } switch (args [0]) { case "/k": if (args.Length < 2) Error ("Missing parameter 'keypair'"); CreateKeypair (args [1]); break; case "/e": if (args.Length < 2) Error ("Missing parameter 'file'"); if (args.Length < 3) Error ("Missing parameter 'keypair'"); EncryptFile (args [1], args [2]); break; case "/d": if (args.Length < 2) Error ("Missing parameter 'file'"); if (args.Length < 3) Error ("Missing parameter 'keypair'"); DecryptFile (args [1], args [2]); break; default: Header (); Help (); Console.WriteLine ("Unknown option {0}", args [0]); break; } } } }