{
Assert.Equal(128, aes.BlockSize);
Assert.Equal(256, aes.KeySize);
+ Assert.Equal(8, aes.FeedbackSize);
Assert.Equal(CipherMode.CBC, aes.Mode);
Assert.Equal(PaddingMode.PKCS7, aes.Padding);
}
string decrypted = Encoding.ASCII.GetString(outputBytes, 0, outputOffset);
Assert.Equal(ExpectedOutput, decrypted);
}
+
+ [Fact]
+ public static void VerifyNetFxCompat_CFB8_PKCS7Padding()
+ {
+ // .NET Framework would always pad to the nearest block
+ // with CFB8 and PKCS7 padding even though the shortest possible
+ // padding is always 1 byte. This ensures we can continue to decrypt
+ // .NET Framework encrypted data with the excessive padding.
+
+ byte[] key = "531bd715cbf785c10169b6e4926562b8e1e5c4c8884ed791".HexToByteArray();
+ byte[] iv = "dbeba40532a5304a".HexToByteArray();
+ byte[] plaintext = "70656e6e79".HexToByteArray();
+ byte[] ciphertext = "8798c2da055c9ea0".HexToByteArray();
+
+ using TripleDES tdes = TripleDESFactory.Create();
+ tdes.Mode = CipherMode.CFB;
+ tdes.Padding = PaddingMode.PKCS7;
+ tdes.FeedbackSize = 8;
+
+ byte[] decrypted = TripleDESDecryptDirectKey(tdes, key, iv, ciphertext);
+ Assert.Equal(plaintext, decrypted);
+ }
}
}
{
private const int BitsPerByte = 8;
+ public TripleDesImplementation()
+ {
+ // Default CFB to CFB8 to match .NET Framework's default for TripleDES.Create()
+ // and TripleDESCryptoServiceProvider.
+ FeedbackSizeValue = 8;
+ }
+
public override ICryptoTransform CreateDecryptor()
{
return CreateTransform(Key, IV, encrypting: false);
{
Assert.Equal(256, aes.KeySize);
Assert.Equal(128, aes.BlockSize);
+ Assert.Equal(8, aes.FeedbackSize);
Assert.Equal(CipherMode.CBC, aes.Mode);
Assert.Equal(PaddingMode.PKCS7, aes.Padding);
}
{
Assert.Equal(192, tdes.KeySize);
Assert.Equal(64, tdes.BlockSize);
+ Assert.Equal(64, tdes.FeedbackSize);
+ Assert.Equal(CipherMode.CBC, tdes.Mode);
+ Assert.Equal(PaddingMode.PKCS7, tdes.Padding);
+ }
+ }
+
+ [Fact]
+ public static void TripleDesInternalDefault()
+ {
+ using (TripleDES tdes = TripleDES.Create())
+ {
+ Assert.Equal(192, tdes.KeySize);
+ Assert.Equal(64, tdes.BlockSize);
+ Assert.Equal(8, tdes.FeedbackSize);
Assert.Equal(CipherMode.CBC, tdes.Mode);
Assert.Equal(PaddingMode.PKCS7, tdes.Padding);
}
private static readonly CngAlgorithm s_cngAlgorithm = new CngAlgorithm("3DES");
+ [Fact]
+ public static void VerifyDefaults()
+ {
+ using TripleDES tdes = new TripleDESCng();
+ Assert.Equal(64, tdes.BlockSize);
+ Assert.Equal(192, tdes.KeySize);
+ Assert.Equal(CipherMode.CBC, tdes.Mode);
+ Assert.Equal(PaddingMode.PKCS7, tdes.Padding);
+
+ // .NET Framework Compat: The default feedback size of TripleDESCng
+ // is 64 while TripleDESCryptoServiceProvider defaults to 8.
+ Assert.Equal(64, tdes.FeedbackSize);
+ }
+
[OuterLoop(/* Creates/Deletes a persisted key, limit exposure to key leaking */)]
[ConditionalTheory(nameof(SupportsPersistedSymmetricKeys))]
// 3DES192-ECB-NoPadding 2 blocks.
{
// This class wraps TripleDES
_impl = TripleDES.Create();
- _impl.FeedbackSize = 8;
}
public override int FeedbackSize
{
Assert.Equal(64, alg.BlockSize);
Assert.Equal(192, alg.KeySize);
+ Assert.Equal(8, alg.FeedbackSize);
Assert.Equal(CipherMode.CBC, alg.Mode);
Assert.Equal(PaddingMode.PKCS7, alg.Padding);
}