public void Twofish_Padding_Iso10126_ECB_128_DecryptAndEncrypt_16() { var key = ParseBytes("00000000000000000000000000000000"); var pt = "The quick brown fox jumps over the lazy dog once"; var ctA = ParseBytes("B0DD30E9AB1F1329C1BEE154DDBE88AF1194B36D8E0BDD5AC10842B549230BB36D66FC3AFE1F40216590079AF862AB5958A06DC5AD2D7C0550771D6E9D59D58B"); using (var algorithm = new TwofishManaged() { KeySize = 128, Mode = CipherMode.ECB, Padding = PaddingMode.ISO10126 }) { var ptA = Decrypt(algorithm, key, null, ctA); Assert.AreEqual(pt, Encoding.UTF8.GetString(ptA)); } var ptB = Encoding.UTF8.GetBytes(pt); using (var algorithm = new TwofishManaged() { KeySize = 128, Mode = CipherMode.ECB, Padding = PaddingMode.ISO10126 }) { var ctB = Encrypt(algorithm, key, null, ptB); var ptC = Decrypt(algorithm, key, null, ctB); Assert.AreEqual(pt, Encoding.UTF8.GetString(ptC)); Assert.AreNotEqual(BitConverter.ToString(ctA).Replace("-", ""), BitConverter.ToString(ctB).Replace("-", "")); //chances are good padding will be different (due to randomness involved) } }
private static byte[] EncryptKey(byte[] stretchedKey, byte[] buffer, int offset) { using var twofish = new TwofishManaged(); twofish.Mode = CipherMode.ECB; twofish.Padding = PaddingMode.None; twofish.KeySize = 256; twofish.Key = stretchedKey; using var transform = twofish.CreateEncryptor(); return(transform.TransformFinalBlock(buffer, offset, 32)); }
private static byte[] DecryptData(byte[] key, byte[] iv, byte[] buffer, int offset, int length) { using var twofish = new TwofishManaged(); twofish.Mode = CipherMode.CBC; twofish.Padding = PaddingMode.None; twofish.KeySize = 256; twofish.Key = key; twofish.IV = iv; using var dataDecryptor = twofish.CreateDecryptor(); return(dataDecryptor.TransformFinalBlock(buffer, offset, length)); }
public void Twofish_MultiBlock_ECB_192_Decrypt() { var key = ParseBytes("000000000000000000000000000000000000000000000000"); var ct = ParseBytes("EFA71F788965BD4453F860178FC19101EFA71F788965BD4453F860178FC19101EFA71F788965BD4453F860178FC19101"); using (var algorithm = new TwofishManaged() { KeySize = 192, Mode = CipherMode.ECB, Padding = PaddingMode.None }) { var pt = Decrypt(algorithm, key, null, ct); Assert.AreEqual("000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", BitConverter.ToString(pt).Replace("-", "")); } }
public void Twofish_MultiBlock_ECB_128_Decrypt() { var key = ParseBytes("00000000000000000000000000000000"); var ct = ParseBytes("9F589F5CF6122C32B6BFEC2F2AE8C35A9F589F5CF6122C32B6BFEC2F2AE8C35A9F589F5CF6122C32B6BFEC2F2AE8C35A"); using (var algorithm = new TwofishManaged() { KeySize = 128, Mode = CipherMode.ECB, Padding = PaddingMode.None }) { var pt = Decrypt(algorithm, key, null, ct); Assert.AreEqual("000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", BitConverter.ToString(pt).Replace("-", "")); } }
public void Twofish_Padding_Pkcs7_ECB_128_Decrypt() { var key = ParseBytes("00000000000000000000000000000000"); var ct = ParseBytes("B0DD30E9AB1F1329C1BEE154DDBE88AF1194B36D8E0BDD5AC10842B549230BB3235D2E6063F32DE35B8A62A384FC587E"); using (var algorithm = new TwofishManaged() { KeySize = 128, Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7 }) { var pt = Decrypt(algorithm, key, null, ct); Assert.AreEqual("The quick brown fox jumps over the lazy dog", Encoding.UTF8.GetString(pt)); } }
public void Twofish_Padding_Zeros_ECB_128_Encrypt_16() { var key = ParseBytes("00000000000000000000000000000000"); var pt = Encoding.UTF8.GetBytes("The quick brown fox jumps over the lazy dog once"); using (var algorithm = new TwofishManaged() { KeySize = 128, Mode = CipherMode.ECB, Padding = PaddingMode.Zeros }) { var ct = Encrypt(algorithm, key, null, pt); Assert.AreEqual("B0DD30E9AB1F1329C1BEE154DDBE88AF1194B36D8E0BDD5AC10842B549230BB36D66FC3AFE1F40216590079AF862AB59", BitConverter.ToString(ct).Replace("-", "")); } }
public void Twofish_Padding_Pkcs7_ECB_128_Decrypt_16() { var key = ParseBytes("00000000000000000000000000000000"); var ct = ParseBytes("B0DD30E9AB1F1329C1BEE154DDBE88AF1194B36D8E0BDD5AC10842B549230BB36D66FC3AFE1F40216590079AF862AB59771D591428AF301D69FA1E227D083527"); using (var algorithm = new TwofishManaged() { KeySize = 128, Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7 }) { var pt = Decrypt(algorithm, key, null, ct); Assert.AreEqual("The quick brown fox jumps over the lazy dog once", Encoding.UTF8.GetString(pt)); } }
public void Twofish_Padding_AnsiX923_ECB_128_Decrypt() { var key = ParseBytes("00000000000000000000000000000000"); var ct = ParseBytes("B0DD30E9AB1F1329C1BEE154DDBE88AF1194B36D8E0BDD5AC10842B549230BB3B696D40A5E12225D3E05E8A466F078C2"); using (var algorithm = new TwofishManaged() { KeySize = 128, Mode = CipherMode.ECB, Padding = PaddingMode.ANSIX923 }) { var pt = Decrypt(algorithm, key, null, ct); Assert.AreEqual("The quick brown fox jumps over the lazy dog", Encoding.UTF8.GetString(pt)); } }
public void Twofish_Padding_AnsiX923_ECB_128_Decrypt_16() { var key = ParseBytes("00000000000000000000000000000000"); var ct = ParseBytes("B0DD30E9AB1F1329C1BEE154DDBE88AF1194B36D8E0BDD5AC10842B549230BB36D66FC3AFE1F40216590079AF862AB5958A06DC5AD2D7C0550771D6E9D59D58B"); using (var algorithm = new TwofishManaged() { KeySize = 128, Mode = CipherMode.ECB, Padding = PaddingMode.ANSIX923 }) { var pt = Decrypt(algorithm, key, null, ct); Assert.AreEqual("The quick brown fox jumps over the lazy dog once", Encoding.UTF8.GetString(pt)); } }
public void Twofish_Padding_Zeros_ECB_128_Decrypt() { var key = ParseBytes("00000000000000000000000000000000"); var ct = ParseBytes("B0DD30E9AB1F1329C1BEE154DDBE88AF1194B36D8E0BDD5AC10842B549230BB33C25C273BF09B94A31DE3C27C28DFB5C"); using (var algorithm = new TwofishManaged() { KeySize = 128, Mode = CipherMode.ECB, Padding = PaddingMode.Zeros }) { var pt = Decrypt(algorithm, key, null, ct); Assert.AreEqual("The quick brown fox jumps over the lazy dog", Encoding.UTF8.GetString(pt)); } }
public void Twofish_MultiBlock_ECB_256_Decrypt() { var key = ParseBytes("0000000000000000000000000000000000000000000000000000000000000000"); var ct = ParseBytes("57FF739D4DC92C1BD7FC01700CC8216F57FF739D4DC92C1BD7FC01700CC8216F57FF739D4DC92C1BD7FC01700CC8216F"); using (var algorithm = new TwofishManaged() { KeySize = 256, Mode = CipherMode.ECB, Padding = PaddingMode.None }) { var pt = Decrypt(algorithm, key, null, ct); Assert.AreEqual("000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", BitConverter.ToString(pt).Replace("-", "")); } }
public void Twofish_MultiBlock_CBC_128_Decrypt() { var key = ParseBytes("00000000000000000000000000000000"); var iv = ParseBytes("00000000000000000000000000000000"); var ct = ParseBytes("9F589F5CF6122C32B6BFEC2F2AE8C35AD491DB16E7B1C39E86CB086B789F541905EF8C61A811582634BA5CB7106AA641"); using (var algorithm = new TwofishManaged() { KeySize = 128, Mode = CipherMode.CBC, Padding = PaddingMode.None }) { var pt = Decrypt(algorithm, key, iv, ct); Assert.AreEqual("000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", BitConverter.ToString(pt).Replace("-", "")); } }
public void Twofish_MultiBlock_CBC_192_Decrypt() { var key = ParseBytes("000000000000000000000000000000000000000000000000"); var iv = ParseBytes("00000000000000000000000000000000"); var ct = ParseBytes("EFA71F788965BD4453F860178FC1910188B2B2706B105E36B446BB6D731A1E88F2DD994D2C4E64517CC9DB9AED2D5909"); using (var algorithm = new TwofishManaged() { KeySize = 192, Mode = CipherMode.CBC, Padding = PaddingMode.None }) { var pt = Decrypt(algorithm, key, iv, ct); Assert.AreEqual("000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", BitConverter.ToString(pt).Replace("-", "")); } }
public void Twofish_MultiBlockFinal_ECB_256_Decrypt() { var key = ParseBytes("0000000000000000000000000000000000000000000000000000000000000000"); var ct = ParseBytes("57FF739D4DC92C1BD7FC01700CC8216F57FF739D4DC92C1BD7FC01700CC8216F57FF739D4DC92C1BD7FC01700CC8216F"); using (var algorithm = new TwofishManaged() { KeySize = 256, Mode = CipherMode.ECB, Padding = PaddingMode.None }) { algorithm.Key = key; var pt = algorithm.CreateDecryptor().TransformFinalBlock(ct, 0, ct.Length); Assert.AreEqual("000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", BitConverter.ToString(pt).Replace("-", "")); } }
public void Twofish_MultiBlock_CBC_256_Decrypt() { var key = ParseBytes("0000000000000000000000000000000000000000000000000000000000000000"); var iv = ParseBytes("00000000000000000000000000000000"); var ct = ParseBytes("57FF739D4DC92C1BD7FC01700CC8216FD43BB7556EA32E46F2A282B7D45B4E0D2804E32925D62BAE74487A06B3CD2D46"); using (var algorithm = new TwofishManaged() { KeySize = 256, Mode = CipherMode.CBC, Padding = PaddingMode.None }) { var pt = Decrypt(algorithm, key, iv, ct); Assert.AreEqual("000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", BitConverter.ToString(pt).Replace("-", "")); } }
public void Twofish_TransformBlock_Decrypt_UseSameArray() { var key = ParseBytes("00000000000000000000000000000000"); var iv = ParseBytes("00000000000000000000000000000000"); var ctpt = ParseBytes("B0DD30E9AB1F1329C1BEE154DDBE88AF8C47A4FE24D56DC027ED503652C9D164CE26E0C6E32BCA8756482B99988E8C79"); using (var twofish = new TwofishManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.None, KeySize = 128, Key = key, IV = iv }) { using (var transform = twofish.CreateDecryptor()) { transform.TransformBlock(ctpt, 0, 48, ctpt, 0); //no caching last block if Padding is none } } Assert.AreEqual("The quick brown fox jumps over the lazy dog once", Encoding.UTF8.GetString(ctpt)); }
public void Twofish_MultiBlockFinal_CBC_256_Decrypt() { var key = ParseBytes("0000000000000000000000000000000000000000000000000000000000000000"); var iv = ParseBytes("00000000000000000000000000000000"); var ct = ParseBytes("61B5BC459C4E9491DD9E6ACB7478813047BE7250D34F792C17F0C23583C0B040B95C9FAE11107EE9BAC3D79BBFE019EE"); using (var algorithm = new TwofishManaged() { KeySize = 256, Mode = CipherMode.CBC, Padding = PaddingMode.None }) { algorithm.Key = key; algorithm.IV = iv; var pt = algorithm.CreateDecryptor().TransformFinalBlock(ct, 0, ct.Length); Assert.AreEqual("9F589F5CF6122C32B6BFEC2F2AE8C35A9F589F5CF6122C32B6BFEC2F2AE8C35A9F589F5CF6122C32B6BFEC2F2AE8C35A", BitConverter.ToString(pt).Replace("-", "")); } }
public static void Main(string[] args) { Console.Title = "Twofish.Tests"; var bIn = Encoding.UTF8.GetBytes("It works!"); byte[] key = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; // 128bit key byte[] iv = { 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }; // initialization vector using (var algorithm = new TwofishManaged { KeySize = key.Length * 8, Mode = CipherMode.CBC }) { byte[] encrypted; using (var ms = new MemoryStream()) { using (var transform = algorithm.CreateEncryptor(key, iv)) { using (var cs = new CryptoStream(ms, transform, CryptoStreamMode.Write)) { cs.Write(bIn, 0, bIn.Length); } } encrypted = ms.ToArray(); Console.WriteLine($"Encrypted: {BitConverter.ToString(encrypted).Replace("-", string.Empty)}"); } using (var ms = new MemoryStream()) { using (var transform = algorithm.CreateDecryptor(key, iv)) { using (var cs = new CryptoStream(ms, transform, CryptoStreamMode.Write)) { cs.Write(encrypted, 0, encrypted.Length); } } Console.WriteLine($"Decrypted: {Encoding.UTF8.GetString(ms.ToArray())}"); } } Console.Read(); }
private static void MonteCarlo_ECB_D(TestBlock test) { using (var algorithm = new TwofishManaged() { KeySize = test.KeySize, Mode = CipherMode.ECB, Padding = PaddingMode.None }) { var key = test.Key; var ct = test.CipherText; byte[] pt = null; for (var j = 0; j < 10000; j++) { pt = Decrypt(algorithm, key, null, ct); ct = pt; } Assert.AreEqual(BitConverter.ToString(test.PlainText), BitConverter.ToString(pt), "Test " + test.Index.ToString() + " (" + test.KeySize.ToString() + ")"); } }
public void Twofish_MonteCarlo_ECB() { var tests = GetTestBlocks(Assembly.GetExecutingAssembly().GetManifestResourceStream("Test.Twofish.ECB_TBL.TXT")); foreach (var test in tests) { using (var algorithm = new TwofishManaged() { KeySize = test.KeySize, Mode = CipherMode.ECB, Padding = PaddingMode.None }) { var ct = Encrypt(algorithm, test.Key, null, test.PlainText); Assert.AreEqual(BitConverter.ToString(test.CipherText), BitConverter.ToString(ct), "Test Decrypt " + test.Index.ToString() + " (" + test.KeySize.ToString() + ")"); var pt = Decrypt(algorithm, test.Key, null, test.CipherText); Assert.AreEqual(BitConverter.ToString(test.PlainText), BitConverter.ToString(pt), "Test Decrypt " + test.Index.ToString() + " (" + test.KeySize.ToString() + ")"); } } }
public void Twofish_MultiBlockNonFinal_ECB_256_Encrypt() { var key = ParseBytes("0000000000000000000000000000000000000000000000000000000000000000"); var pt = ParseBytes("000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"); using (var algorithm = new TwofishManaged() { KeySize = 256, Mode = CipherMode.ECB, Padding = PaddingMode.None }) { algorithm.Key = key; var ct = new byte[pt.Length]; using (var transform = algorithm.CreateEncryptor()) { transform.TransformBlock(pt, 0, pt.Length, ct, 0); transform.TransformFinalBlock(new byte[] { }, 0, 0); } Assert.AreEqual("57FF739D4DC92C1BD7FC01700CC8216F57FF739D4DC92C1BD7FC01700CC8216F57FF739D4DC92C1BD7FC01700CC8216F", BitConverter.ToString(ct).Replace("-", "")); } }
public static bool TestTwofish() { TwofishManaged twofish = new TwofishManaged(); twofish.Padding = PaddingMode.None; twofish.Mode = CipherMode.ECB; byte[] key = new byte[] { 0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46, 0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D, 0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B, 0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F }; byte[] plaintext = new byte[] { 0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F, 0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6 }; byte[] ciphertext = new byte[] { 0x6C, 0xB4, 0x56, 0x1C, 0x40, 0xBF, 0x0A, 0x97, 0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA }; byte[] initializationVector = new byte[16]; ICryptoTransform encryptor = twofish.CreateEncryptor(key, initializationVector); ICryptoTransform decryptor = twofish.CreateDecryptor(key, initializationVector); byte[] result1 = new byte[16]; byte[] result2 = new byte[16]; encryptor.TransformBlock(plaintext, 0, 16, result1, 0); decryptor.TransformBlock(ciphertext, 0, 16, result2, 0); return(ByteUtils.AreByteArraysEqual(result1, ciphertext) && ByteUtils.AreByteArraysEqual(result2, plaintext)); }
private static void MonteCarlo_CBC_E(TestBlock test) { using (var algorithm = new TwofishManaged() { KeySize = test.KeySize, Mode = CipherMode.CBC, Padding = PaddingMode.None }) { var key = test.Key; var cv = test.IV; var pt = test.PlainText; byte[] ct = null; for (var j = 0; j < 10000; j++) { var ob = Encrypt(algorithm, key, cv, pt); pt = (j == 0) ? cv : ct; ct = ob; cv = ct; } Assert.AreEqual(BitConverter.ToString(test.CipherText), BitConverter.ToString(ct), "Test " + test.Index.ToString() + " (" + test.KeySize.ToString() + ")"); } }
public ISingleCipherTransform GetCipherTransformer() { if (m_SymAlgo == SymAlgoCode.AES256 || m_SymAlgo == SymAlgoCode.ThreeDES || m_SymAlgo == SymAlgoCode.Twofish) { SymmetricAlgorithm SymAlgo; if (m_SymAlgo == SymAlgoCode.ThreeDES) { SymAlgo = new TripleDESCryptoServiceProvider { BlockSize = 64, IV = m_IV, KeySize = 192, Key = m_Key, Mode = CipherMode.CBC, Padding = PaddingMode.None }; } else if (m_SymAlgo == SymAlgoCode.AES256) { SymAlgo = new RijndaelManaged { BlockSize = 128, IV = m_IV, KeySize = 256, Key = m_Key, Mode = CipherMode.CBC, Padding = PaddingMode.None } } ; else { SymAlgo = new TwofishManaged { BlockSize = 128, IV = m_IV, KeySize = 256, Key = m_Key, Mode = CipherMode.CBC, Padding = PaddingMode.None } }; return(new CryptoTransformer(SymAlgo)); } else if (m_SymAlgo == SymAlgoCode.ChaCha20 || m_SymAlgo == SymAlgoCode.Salsa20) { CtrBlockCipher c; if (m_SymAlgo == SymAlgoCode.ChaCha20) { c = new ChaCha20Cipher(m_Key, m_IV); } else { c = new Salsa20Cipher(m_Key, m_IV); } return(new CtrBlockCipherTransformer(c)); } throw new SecurityException("Invalid Algorithm"); }
public static List <KeyValuePairList <SymmetricAlgorithm, byte[]> > GetAlgorithms(byte[] key) { // AesCryptoServiceProvider will use AES-NI if availible, but Rijndael is almost 3 times faster if AES-NI is not available. Rijndael aes = Rijndael.Create(); aes.Padding = PaddingMode.None; aes.Mode = CipherMode.ECB; SerpentManaged serpent = new SerpentManaged(); serpent.Padding = PaddingMode.None; serpent.Mode = CipherMode.ECB; TwofishManaged twofish = new TwofishManaged(); twofish.Padding = PaddingMode.None; twofish.Mode = CipherMode.ECB; List <KeyValuePairList <SymmetricAlgorithm, byte[]> > algorithms = new List <KeyValuePairList <SymmetricAlgorithm, byte[]> >(); KeyValuePairList <SymmetricAlgorithm, byte[]> aes_only = new KeyValuePairList <SymmetricAlgorithm, byte[]>(); aes_only.Add(aes, new byte[64]); algorithms.Add(aes_only); KeyValuePairList <SymmetricAlgorithm, byte[]> serpent_only = new KeyValuePairList <SymmetricAlgorithm, byte[]>(); serpent_only.Add(serpent, new byte[64]); algorithms.Add(serpent_only); KeyValuePairList <SymmetricAlgorithm, byte[]> twofish_only = new KeyValuePairList <SymmetricAlgorithm, byte[]>(); twofish_only.Add(twofish, new byte[64]); algorithms.Add(twofish_only); KeyValuePairList <SymmetricAlgorithm, byte[]> twofish_aes = new KeyValuePairList <SymmetricAlgorithm, byte[]>(); twofish_aes.Add(twofish, new byte[64]); twofish_aes.Add(aes, new byte[64]); algorithms.Add(twofish_aes); KeyValuePairList <SymmetricAlgorithm, byte[]> serpent_twofish_aes = new KeyValuePairList <SymmetricAlgorithm, byte[]>(); serpent_twofish_aes.Add(serpent, new byte[64]); serpent_twofish_aes.Add(twofish, new byte[64]); serpent_twofish_aes.Add(aes, new byte[64]); algorithms.Add(serpent_twofish_aes); KeyValuePairList <SymmetricAlgorithm, byte[]> aes_serpent = new KeyValuePairList <SymmetricAlgorithm, byte[]>(); aes_serpent.Add(aes, new byte[64]); aes_serpent.Add(serpent, new byte[64]); algorithms.Add(aes_serpent); KeyValuePairList <SymmetricAlgorithm, byte[]> aes_twofish_serpent = new KeyValuePairList <SymmetricAlgorithm, byte[]>(); aes_twofish_serpent.Add(aes, new byte[64]); aes_twofish_serpent.Add(twofish, new byte[64]); aes_twofish_serpent.Add(serpent, new byte[64]); algorithms.Add(aes_twofish_serpent); KeyValuePairList <SymmetricAlgorithm, byte[]> serpent_twofish = new KeyValuePairList <SymmetricAlgorithm, byte[]>(); serpent_twofish.Add(serpent, new byte[64]); serpent_twofish.Add(twofish, new byte[64]); algorithms.Add(serpent_twofish); foreach (KeyValuePairList <SymmetricAlgorithm, byte[]> algorithm in algorithms) { AssignKey(algorithm, key); } return(algorithms); }
// Consume them private static void Main(string[] args) { var dir = TwofishManagedTransformMode.Encrypt; var mode = CipherMode.ECB; var keysize = 128; var key = ParseHex("00000000000000000000000000000000"); var iv = ParseHex("00000000000000000000000000000000"); var inputFilename = "input.txt"; var outputFilename = "output.txt"; var bufferSize = 1024; for (var i = 0; i < args.Length; i++) { if (args[i] == "--keysize") { keysize = Convert.ToInt16(args[++i]); } else if (args[i] == "--encrypt") { dir = TwofishManagedTransformMode.Encrypt; } else if (args[i] == "--decrypt") { dir = TwofishManagedTransformMode.Decrypt; } else if (args[i] == "--buffer") { bufferSize = Convert.ToInt32(args[++i]); } else if (args[i] == "--mode") { i++; if (args[i] == "ecb") { mode = CipherMode.ECB; } else if (args[i] == "cbc") { mode = CipherMode.CBC; } } else if (args[i] == "--input") { inputFilename = args[++i]; } else if (args[i] == "--output") { outputFilename = args[++i]; } else if (args[i] == "--key") { key = ParseHex(args[++i]); } else if (args[i] == "--iv") { iv = ParseHex(args[++i]); } } //if (dir == TwofishManagedTransformMode.Encrypt) Console.WriteLine("Encrypting..."); //if (dir == TwofishManagedTransformMode.Decrypt) Console.WriteLine("Decrypting..."); using (var twofish = new TwofishManaged { KeySize = keysize, Mode = mode, Padding = PaddingMode.None }) using (var transform = twofish.NewEncryptor(key, mode, iv, dir)) using (var reader = new BinaryReader(File.Open(inputFilename, FileMode.Open))) using (var writer = new BinaryWriter(File.Open(outputFilename, FileMode.Create))) { var t = DateTime.Now; long total = 0; for (var inputBuffer = reader.ReadBytes(bufferSize * 16); inputBuffer.Length > 0; inputBuffer = reader.ReadBytes(bufferSize * 16)) { Array.Resize(ref inputBuffer, (inputBuffer.Length + 15) & ~15); var outputBuffer = new byte[inputBuffer.Length]; if (mode == CipherMode.ECB) { Parallel.For(0, inputBuffer.Length / 16, i => { transform.TransformBlock(inputBuffer, 16 * i, 16, outputBuffer, 16 * i); }); } if (mode == CipherMode.CBC) { transform.TransformBlock(inputBuffer, 0, inputBuffer.Length, outputBuffer, 0); } writer.Write(outputBuffer); total += inputBuffer.Length; } var dt = DateTime.Now - t; Console.WriteLine("{0} {1}", bufferSize, (16 * dt.TotalMilliseconds / total).ToString(CultureInfo.InvariantCulture)); } }
public void Save(Stream stream, byte[] passphraseBuffer) { if (stream == null) { throw new ArgumentNullException(nameof(stream), "Stream cannot be null."); } if (passphraseBuffer == null) { throw new ArgumentNullException(nameof(passphraseBuffer), "Passphrase cannot be null."); } if (!this.IsReadOnly && this.TrackModify) { this.Headers[HeaderType.TimestampOfLastSave].Time = DateTime.UtcNow; var assemblyName = Assembly.GetExecutingAssembly().GetName(); this.Headers[HeaderType.WhatPerformedLastSave].Text = string.Format(CultureInfo.InvariantCulture, "{0} V{1}.{2:00}", assemblyName.Name, assemblyName.Version.Major, assemblyName.Version.Minor); this.Headers[HeaderType.LastSavedByUser].Text = Environment.UserName; this.Headers[HeaderType.LastSavedOnHost].Text = Environment.MachineName; } byte[] stretchedKey = null; byte[] keyK = null; byte[] keyL = null; //byte[] data = null; try { stream.Write(BitConverter.GetBytes(Tag), 0, 4); var salt = new byte[32]; Rnd.GetBytes(salt); stream.Write(salt, 0, salt.Length); this.Iterations = this.Iterations; //to force minimum iteration count var iter = (uint)this.Iterations; stream.Write(BitConverter.GetBytes(iter), 0, 4); stretchedKey = GetStretchedKey(passphraseBuffer, salt, iter); stream.Write(GetSha256Hash(stretchedKey), 0, 32); keyK = new byte[32]; Rnd.GetBytes(keyK); stream.Write(EncryptKey(stretchedKey, keyK, 0), 0, 32); keyL = new byte[32]; Rnd.GetBytes(keyL); stream.Write(EncryptKey(stretchedKey, keyL, 0), 0, 32); var iv = new byte[16]; Rnd.GetBytes(iv); stream.Write(iv, 0, iv.Length); using (var dataHash = new HMACSHA256(keyL)) using (var twofish = new TwofishManaged()) { twofish.Mode = CipherMode.CBC; twofish.Padding = PaddingMode.None; twofish.KeySize = 256; twofish.Key = keyK; twofish.IV = iv; using (var dataEncryptor = twofish.CreateEncryptor()) { foreach (var field in this.Headers) { WriteBlock(stream, dataHash, dataEncryptor, (byte)field.HeaderType, field.RawData); } WriteBlock(stream, dataHash, dataEncryptor, (byte)HeaderType.EndOfEntry, new byte[] { }); foreach (var entry in this.Entries) { foreach (var field in entry.Records) { WriteBlock(stream, dataHash, dataEncryptor, (byte)field.RecordType, field.RawData); } WriteBlock(stream, dataHash, dataEncryptor, (byte)RecordType.EndOfEntry, new byte[] { }); } } dataHash.TransformFinalBlock(new byte[] { }, 0, 0); stream.Write(BitConverter.GetBytes(Tag), 0, 4); stream.Write(BitConverter.GetBytes(TagEof), 0, 4); stream.Write(BitConverter.GetBytes(Tag), 0, 4); stream.Write(BitConverter.GetBytes(TagEof), 0, 4); stream.Write(dataHash.Hash, 0, dataHash.Hash.Length); this.HasChanged = false; } } finally { if (stretchedKey != null) { Array.Clear(stretchedKey, 0, stretchedKey.Length); } if (keyK != null) { Array.Clear(keyK, 0, keyK.Length); } if (keyL != null) { Array.Clear(keyL, 0, keyL.Length); } //if (data != null) { Array.Clear(data, 0, data.Length); } } }
/// <summary> /// Save document. /// If key buffer is given, keys won't be randomized. This will reduce security! /// If passphrase is null, attempt will be made to use passphrase that was used for load. /// </summary> /// <param name="stream">Stream.</param> /// <param name="passphraseBuffer">Password bytes. Caller has to avoid keeping bytes unencrypted in memory.</param> /// <param name="keyBuffer">Key bytes containing both key K and L. Must be 64 bytes. Caller has to avoid keeping bytes unencrypted in memory.</param> internal void InternalSave(Stream stream, byte[]?passphraseBuffer, byte[]?keyBuffer) { if (passphraseBuffer == null) { passphraseBuffer = GetPassphrase(); } //first try old passphrase if (passphraseBuffer == null) { throw new ArgumentNullException(nameof(passphraseBuffer), "Passphrase cannot be null."); } if ((keyBuffer != null) && (keyBuffer.Length != 64)) { throw new ArgumentOutOfRangeException(nameof(keyBuffer), "Keys must be 64 bytes long."); } if (!IsReadOnly && TrackModify) { Headers[HeaderType.TimestampOfLastSave].Time = DateTime.UtcNow; var assemblyName = Assembly.GetExecutingAssembly().GetName(); Headers[HeaderType.WhatPerformedLastSave].Text = string.Format(CultureInfo.InvariantCulture, "{0} V{1}.{2:00}", assemblyName.Name, assemblyName.Version?.Major ?? 0, assemblyName.Version?.Minor ?? 0); Headers[HeaderType.LastSavedByUser].Text = Environment.UserName; Headers[HeaderType.LastSavedOnHost].Text = Environment.MachineName; } byte[]? stretchedKey = null; byte[]? keyK = null; byte[]? keyL = null; try { stream.Write(BitConverter.GetBytes(Tag), 0, 4); var salt = new byte[32]; Rnd.GetBytes(salt); stream.Write(salt, 0, salt.Length); if (Iterations < 2048) { Iterations = 2048; } // to force minimum iteration count var iter = (uint)Iterations; stream.Write(BitConverter.GetBytes(iter), 0, 4); stretchedKey = GetStretchedKey(passphraseBuffer, salt, iter); stream.Write(GetSha256Hash(stretchedKey), 0, 32); keyK = new byte[32]; keyL = new byte[32]; if (keyBuffer == null) { Rnd.GetBytes(keyK); Rnd.GetBytes(keyL); } else { Buffer.BlockCopy(keyBuffer, 0, keyK, 0, keyK.Length); Buffer.BlockCopy(keyBuffer, 32, keyL, 0, keyL.Length); } stream.Write(EncryptKey(stretchedKey, keyK, 0), 0, 32); stream.Write(EncryptKey(stretchedKey, keyL, 0), 0, 32); var iv = new byte[16]; Rnd.GetBytes(iv); stream.Write(iv, 0, iv.Length); using var dataHash = new HMACSHA256(keyL); using var twofish = new TwofishManaged(); twofish.Mode = CipherMode.CBC; twofish.Padding = PaddingMode.None; twofish.KeySize = 256; twofish.Key = keyK; twofish.IV = iv; using (var dataEncryptor = twofish.CreateEncryptor()) { foreach (var field in Headers) { WriteBlock(stream, dataHash, dataEncryptor, (byte)field.HeaderType, field.RawData); } WriteBlock(stream, dataHash, dataEncryptor, (byte)HeaderType.EndOfEntry, Array.Empty <byte>()); foreach (var entry in Entries) { foreach (var field in entry.Records) { WriteBlock(stream, dataHash, dataEncryptor, (byte)field.RecordType, field.RawData); } WriteBlock(stream, dataHash, dataEncryptor, (byte)RecordType.EndOfEntry, Array.Empty <byte>()); } } dataHash.TransformFinalBlock(Array.Empty <byte>(), 0, 0); stream.Write(BitConverter.GetBytes(Tag), 0, 4); stream.Write(BitConverter.GetBytes(TagEof), 0, 4); stream.Write(BitConverter.GetBytes(Tag), 0, 4); stream.Write(BitConverter.GetBytes(TagEof), 0, 4); if (dataHash.Hash == null) { throw new InvalidOperationException("Cannot compute hash."); } // newer happens actually stream.Write(dataHash.Hash, 0, dataHash.Hash.Length); HasChanged = false; } finally { if (stretchedKey != null) { Array.Clear(stretchedKey, 0, stretchedKey.Length); } if (keyK != null) { Array.Clear(keyK, 0, keyK.Length); } if (keyL != null) { Array.Clear(keyL, 0, keyL.Length); } //if (data != null) { Array.Clear(data, 0, data.Length); } } }