private static void TestDESTransformDirectKey( CipherMode cipherMode, PaddingMode paddingMode, byte[] key, byte[] iv, byte[] plainBytes, byte[] cipherBytes, int?feedbackSize = default) { byte[] liveEncryptBytes; byte[] liveDecryptBytes; using (DES des = DESFactory.Create()) { des.Mode = cipherMode; des.Padding = paddingMode; if (feedbackSize.HasValue) { des.FeedbackSize = feedbackSize.Value; } liveEncryptBytes = DESEncryptDirectKey(des, key, iv, plainBytes); liveDecryptBytes = DESDecryptDirectKey(des, key, iv, cipherBytes); } Assert.Equal(cipherBytes, liveEncryptBytes); Assert.Equal(plainBytes, liveDecryptBytes); }
public static void DecryptorReuse_LeadsToSameResults(CipherMode cipherMode, int feedbackSize) { // AppleCCCryptor does not allow calling Reset on CFB cipher. // this test validates that the behavior is taken into consideration. var input = "4e6f77206973207468652074696d6520666f7220616c6c20".HexToByteArray(); var key = "4a575d02515d40b0".HexToByteArray(); var iv = "ab27e9f02affa532".HexToByteArray(); using (DES des = DESFactory.Create()) { des.Mode = cipherMode; des.Key = key; des.IV = iv; des.Padding = PaddingMode.None; if (feedbackSize > 0) { des.FeedbackSize = feedbackSize; } using (ICryptoTransform transform = des.CreateDecryptor()) { byte[] output1 = transform.TransformFinalBlock(input, 0, input.Length); byte[] output2 = transform.TransformFinalBlock(input, 0, input.Length); Assert.Equal(output1, output2); } } }
public static void InvalidCFBFeedbackSizes(int feedbackSize, bool discoverableInSetter) { using (DES des = DESFactory.Create()) { des.GenerateKey(); des.Mode = CipherMode.CFB; if (discoverableInSetter) { // there are some key sizes that are invalid for any of the modes, // so the exception is thrown in the setter Assert.Throws <CryptographicException>(() => { des.FeedbackSize = feedbackSize; }); } else { des.FeedbackSize = feedbackSize; // however, for CFB only few sizes are valid. Those should throw in the // actual DES instantiation. Assert.Throws <CryptographicException>(() => des.CreateDecryptor()); Assert.Throws <CryptographicException>(() => des.CreateEncryptor()); } } }
public static void MultipleBlockDecryptTransform(bool blockAlignedOutput) { const string ExpectedOutput = "This is a test"; int outputPadding = blockAlignedOutput ? 0 : 3; byte[] key = "87FF0737F868378F".HexToByteArray(); byte[] iv = "0123456789ABCDEF".HexToByteArray(); byte[] outputBytes = new byte[iv.Length * 2 + outputPadding]; byte[] input = "CB67F70BA8B50EED2C0691298988865F".HexToByteArray(); int outputOffset = 0; using (DES alg = DESFactory.Create()) using (ICryptoTransform xform = alg.CreateDecryptor(key, iv)) { Assert.Equal(2 * alg.BlockSize, (outputBytes.Length - outputPadding) * 8); outputOffset += xform.TransformBlock(input, 0, input.Length, outputBytes, outputOffset); byte[] overflow = xform.TransformFinalBlock(Array.Empty <byte>(), 0, 0); Buffer.BlockCopy(overflow, 0, outputBytes, outputOffset, overflow.Length); outputOffset += overflow.Length; } string decrypted = Encoding.ASCII.GetString(outputBytes, 0, outputOffset); Assert.Equal(ExpectedOutput, decrypted); }
public static void DesDefaultCtor() { using (DES des = DESFactory.Create()) { Assert.Equal(64, des.KeySize); Assert.Equal(64, des.BlockSize); Assert.Equal(CipherMode.CBC, des.Mode); Assert.Equal(PaddingMode.PKCS7, des.Padding); } }
private static void TestDESTransformDirectKey( CipherMode cipherMode, PaddingMode paddingMode, byte[] key, byte[] iv, byte[] plainBytes, byte[] cipherBytes, int?feedbackSize = default) { byte[] liveEncryptBytes; byte[] liveDecryptBytes; byte[] liveOneShotDecryptBytes = null; byte[] liveOneShotEncryptBytes = null; using (DES des = DESFactory.Create()) { des.Mode = cipherMode; des.Padding = paddingMode; if (feedbackSize.HasValue) { des.FeedbackSize = feedbackSize.Value; } liveEncryptBytes = DESEncryptDirectKey(des, key, iv, plainBytes); liveDecryptBytes = DESDecryptDirectKey(des, key, iv, cipherBytes); if (cipherMode == CipherMode.ECB) { des.Key = key; liveOneShotDecryptBytes = des.DecryptEcb(cipherBytes, paddingMode); liveOneShotEncryptBytes = des.EncryptEcb(plainBytes, paddingMode); } else if (cipherMode == CipherMode.CBC) { des.Key = key; liveOneShotDecryptBytes = des.DecryptCbc(cipherBytes, iv, paddingMode); liveOneShotEncryptBytes = des.EncryptCbc(plainBytes, iv, paddingMode); } } Assert.Equal(cipherBytes, liveEncryptBytes); Assert.Equal(plainBytes, liveDecryptBytes); if (liveOneShotDecryptBytes is not null) { Assert.Equal(plainBytes, liveOneShotDecryptBytes); } if (liveOneShotEncryptBytes is not null) { Assert.Equal(cipherBytes, liveOneShotEncryptBytes); } }
public static void DESBlockSizeValidation() { using (DES des = DESFactory.Create()) { des.BlockSize = 64; Assert.Equal(64, des.BlockSize); Assert.Throws <CryptographicException>(() => des.BlockSize = 63); Assert.Throws <CryptographicException>(() => des.BlockSize = 65); } }
public static void EcbRoundtrip(byte[] plaintext, byte[] ciphertext, PaddingMode padding) { using (DES des = DESFactory.Create()) { des.Key = s_desOneShotKey; byte[] encrypted = des.EncryptEcb(plaintext, padding); byte[] decrypted = des.DecryptEcb(encrypted, padding); if (padding == PaddingMode.Zeros) { Assert.Equal(plaintext, decrypted[..plaintext.Length]);
public static void ValidCFBFeedbackSizes(int feedbackSize) { using (DES des = DESFactory.Create()) { des.GenerateKey(); des.Mode = CipherMode.CFB; des.FeedbackSize = feedbackSize; using var decryptor = des.CreateDecryptor(); using var encryptor = des.CreateEncryptor(); Assert.NotNull(decryptor); Assert.NotNull(encryptor); } }
public static void DesTransformBlockValidation() { using (DES des = DESFactory.Create()) { AssertExtensions.Throws <ArgumentException>("rgbKey", () => des.CreateDecryptor(KnownShortKey, des.IV)); AssertExtensions.Throws <ArgumentNullException>("rgbKey", () => des.CreateDecryptor(null, des.IV)); Assert.Throws <CryptographicException>(() => des.CreateDecryptor(KnownWeakKey, des.IV)); Assert.Throws <CryptographicException>(() => des.CreateDecryptor(KnownSemiWeakKey, des.IV)); AssertExtensions.Throws <ArgumentException>("rgbKey", () => des.CreateEncryptor(KnownShortKey, des.IV)); AssertExtensions.Throws <ArgumentNullException>("rgbKey", () => des.CreateEncryptor(null, des.IV)); Assert.Throws <CryptographicException>(() => des.CreateEncryptor(KnownWeakKey, des.IV)); Assert.Throws <CryptographicException>(() => des.CreateEncryptor(KnownSemiWeakKey, des.IV)); } }
public static void TransformWithTooShortOutputBuffer(bool encrypt, bool blockAlignedOutput) { using (DES alg = DESFactory.Create()) using (ICryptoTransform xform = encrypt ? alg.CreateEncryptor() : alg.CreateDecryptor()) { // 1 block, plus maybe three bytes int outputPadding = blockAlignedOutput ? 0 : 3; byte[] output = new byte[alg.BlockSize / 8 + outputPadding]; // 3 blocks of 0x00 byte[] input = new byte[3 * (alg.BlockSize / 8)]; Assert.Throws <ArgumentOutOfRangeException>( () => xform.TransformBlock(input, 0, input.Length, output, 0)); Assert.Equal(new byte[output.Length], output); } }
public static void DesExplicitEncryptorDecryptor_NoIV() { using (DES alg = DESFactory.Create()) { alg.Padding = PaddingMode.PKCS7; alg.Mode = CipherMode.ECB; using (ICryptoTransform encryptor = alg.CreateEncryptor(s_randomKey_64.HexToByteArray(), null)) { byte[] plainText1 = s_multiBlockString.HexToByteArray(); byte[] cipher1 = encryptor.Transform(plainText1); byte[] expectedCipher1 = ( "4E42A439ED50C7998CD626B8BE1ECC0A82B985EA772030E87C96BFAE1B97A7666505B8AE96745DE249C1EC3338BBAD41" + "93A9B792205F345E22D45A9A996F21CE24697E5A45F600E8C6E71FC7114A3E96EC4EACC9F652DEBC679D22DE7141F67F").HexToByteArray(); Assert.Equal <byte>(expectedCipher1, cipher1); } } }
public static void DesExplicitEncryptorDecryptor_WithIV() { using (DES alg = DESFactory.Create()) { alg.Padding = PaddingMode.PKCS7; alg.Mode = CipherMode.CBC; using (ICryptoTransform encryptor = alg.CreateEncryptor(s_randomKey_64.HexToByteArray(), s_randomIv_64.HexToByteArray())) { byte[] plainText1 = s_multiBlockString.HexToByteArray(); byte[] cipher1 = encryptor.Transform(plainText1); byte[] expectedCipher1 = ( "7264319AE3C504148CD4A19B4FDC7D2ACCCB0A08D60CBE2B885DCB2C1A86ED9CA51006E33859B03E00F5B57801EFF745" + "F7A577842461CF39AC143505EC326233E66343A46FEADE9E8456D8AC6A84A1C32E6792857F062400EA9053D17AD3C35D").HexToByteArray(); Assert.Equal <byte>(expectedCipher1, cipher1); } } }
public static void DesKeysValidation() { Assert.True(DES.IsWeakKey(KnownWeakKey)); Assert.False(DES.IsWeakKey(KnownGoodKey)); Assert.Throws <CryptographicException>(() => DES.IsWeakKey(null)); Assert.Throws <CryptographicException>(() => DES.IsWeakKey(KnownShortKey)); Assert.True(DES.IsSemiWeakKey(KnownSemiWeakKey)); Assert.False(DES.IsSemiWeakKey(KnownGoodKey)); Assert.Throws <CryptographicException>(() => DES.IsSemiWeakKey(null)); Assert.Throws <CryptographicException>(() => DES.IsSemiWeakKey(KnownShortKey)); using (DES des = DESFactory.Create()) { AssertExtensions.Throws <ArgumentException>(null, () => des.Key = KnownShortKey); Assert.Throws <CryptographicException>(() => des.Key = KnownSemiWeakKey); AssertExtensions.Throws <ArgumentNullException>("value", () => des.Key = null); des.Key = KnownGoodKey; Assert.Equal(KnownGoodKey, des.Key); } }
public static void DesReuseEncryptorDecryptor() { using (DES alg = DESFactory.Create()) { alg.Key = s_randomKey_64.HexToByteArray(); alg.IV = s_randomIv_64.HexToByteArray(); alg.Padding = PaddingMode.PKCS7; alg.Mode = CipherMode.CBC; using (ICryptoTransform encryptor = alg.CreateEncryptor()) using (ICryptoTransform decryptor = alg.CreateDecryptor()) { for (int i = 0; i < 2; i++) { byte[] plainText1 = s_multiBlockString.HexToByteArray(); byte[] cipher1 = encryptor.Transform(plainText1); byte[] expectedCipher1 = ( "7264319AE3C504148CD4A19B4FDC7D2ACCCB0A08D60CBE2B885DCB2C1A86ED9CA51006E33859B03E00F5B57801EFF745" + "F7A577842461CF39AC143505EC326233E66343A46FEADE9E8456D8AC6A84A1C32E6792857F062400EA9053D17AD3C35D").HexToByteArray(); Assert.Equal <byte>(expectedCipher1, cipher1); byte[] decrypted1 = decryptor.Transform(cipher1); byte[] expectedDecrypted1 = s_multiBlockString.HexToByteArray(); Assert.Equal <byte>(expectedDecrypted1, decrypted1); byte[] plainText2 = s_multiBlockString_8.HexToByteArray(); byte[] cipher2 = encryptor.Transform(plainText2); byte[] expectedCipher2 = ( "7264319AE3C504148CD4A19B4FDC7D2ACCCB0A08D60CBE2B885DCB2C1A86ED9CA51006E33859B03EEB61CF5219D769C1" + "ABF1A1FDE0EF87D3B3C4D567D9C8960DDA55DBE13341928FEF38B938E1F62FAD1D05E355E440E012A0FFAB00B7AEE64D").HexToByteArray(); Assert.Equal <byte>(expectedCipher2, cipher2); byte[] decrypted2 = decryptor.Transform(cipher2); byte[] expectedDecrypted2 = s_multiBlockString_8.HexToByteArray(); Assert.Equal <byte>(expectedDecrypted2, decrypted2); } } } }
public static void EncryptWithLargeOutputBuffer(bool blockAlignedOutput) { using (DES alg = DESFactory.Create()) using (ICryptoTransform xform = alg.CreateEncryptor()) { // 8 blocks, plus maybe three bytes int outputPadding = blockAlignedOutput ? 0 : 3; byte[] output = new byte[alg.BlockSize + outputPadding]; // 2 blocks of 0x00 byte[] input = new byte[alg.BlockSize / 4]; int outputOffset = 0; outputOffset += xform.TransformBlock(input, 0, input.Length, output, outputOffset); byte[] overflow = xform.TransformFinalBlock(Array.Empty <byte>(), 0, 0); Buffer.BlockCopy(overflow, 0, output, outputOffset, overflow.Length); outputOffset += overflow.Length; Assert.Equal(3 * (alg.BlockSize / 8), outputOffset); string outputAsHex = output.ByteArrayToHex(); Assert.NotEqual(new string('0', outputOffset * 2), outputAsHex.Substring(0, outputOffset * 2)); Assert.Equal(new string('0', (output.Length - outputOffset) * 2), outputAsHex.Substring(outputOffset * 2)); } }
public static void DesRoundTrip(CipherMode cipherMode, PaddingMode paddingMode, string key, string iv, string textHex, string expectedDecrypted, string expectedEncrypted) { byte[] expectedDecryptedBytes = expectedDecrypted == null?textHex.HexToByteArray() : expectedDecrypted.HexToByteArray(); byte[] expectedEncryptedBytes = expectedEncrypted.HexToByteArray(); byte[] keyBytes = key.HexToByteArray(); using (DES alg = DESFactory.Create()) { alg.Key = keyBytes; alg.Padding = paddingMode; alg.Mode = cipherMode; if (iv != null) { alg.IV = iv.HexToByteArray(); } byte[] cipher = alg.Encrypt(textHex.HexToByteArray()); Assert.Equal <byte>(expectedEncryptedBytes, cipher); byte[] decrypted = alg.Decrypt(cipher); Assert.Equal <byte>(expectedDecryptedBytes, decrypted); } }
public static void EncryptorReuse_LeadsToSameResults(CipherMode cipherMode, int feedbackSize) { // AppleCCCryptor does not allow calling Reset on CFB cipher. // this test validates that the behavior is taken into consideration. var input = "b72606c98d8e4fabf08839abf7a0ac61".HexToByteArray(); using (DES des = DESFactory.Create()) { des.Mode = cipherMode; if (feedbackSize > 0) { des.FeedbackSize = feedbackSize; } using (ICryptoTransform transform = des.CreateEncryptor()) { byte[] output1 = transform.TransformFinalBlock(input, 0, input.Length); byte[] output2 = transform.TransformFinalBlock(input, 0, input.Length); Assert.Equal(output1, output2); } } }
protected override SymmetricAlgorithm CreateAlgorithm() => DESFactory.Create();