[Mono-list] TripleDES differences between Mono 0.28 & .NET

Carlos Guzman Alvarez carlosga@telefonica.net
Fri, 03 Oct 2003 12:55:48 +0200


This is a multi-part message in MIME format.
--------------010902020401050107080404
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 8bit

Hello:

I have made a little test case for test TripleDES using mono & ms.net 
and there are differences in the results.

The test case is based on a piece of code from my TLS Library ( that as 
i said some time ago is working well under Windows with MS.NET but not 
with Mono on Linux ):

Output of the test case using MS.NET:

9c99568e753e02955b5c468bcff82721535f3dd81695823d889b9a47da979086500e48eee79b2541
1400000cb58608e6b94b1381658e76be
2a94e53ab9f99a839d4fb0a88f470076050a5f08


Output of the Test case using Mono 0.28 (Windows)

9c99568e753e02955b5c468bcff82721535f3dd81695823d889b9a47da9790868f3e78b6ef624695
1400000cb58608e6b94b1381
658e76be2a94e53ab9f99a839d4fb0a88f470076


Output of the Test case using Mono 0.28 (Linux Red Hat 8)

9c99568e753e02955b5c468bcff82721535f3dd81695823d889b9a47da9790868f3e78b6ef624695
1400000cb58608e6b94b1381
658e76be2a94e53ab9f99a839d4fb0a88f470076


Output of the case using the exe built with mono 0.28 and the MS .NET 
runtime ( runnig test.exe directly in the console seems to be using the 
MS.NET framework )

9c99568e753e02955b5c468bcff82721535f3dd81695823d889b9a47da979086500e48eee79b2541
1400000cb58608e6b94b1381658e76be
2a94e53ab9f99a839d4fb0a88f470076050a5f08


If anybody can confirm this i will fill a bug report in mono bugzilla.

The test case source code is attached to this email.




-- 
Best regards

Carlos Guzmán Álvarez
Vigo-Spain


"Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las 
mismas cosas."

Albert Einstein.

--------------010902020401050107080404
Content-Type: text/plain;
 name="TripleDESTest.cs"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="TripleDESTest.cs"

using System;
using System.IO;
using System.Security.Cryptography;

namespace TripleDESTest
{
	class TripleDES
	{
		[STAThread]
		static void Main(string[] args)
		{
			byte		blockSize		= 8;
			string		algName			= "3DES";
			byte		keyMaterialSize	= 24;
			byte		hashSize		= 20;
			CipherMode	cipherMode		= CipherMode.CBC;

			SymmetricAlgorithm encryptionAlgorithm = SymmetricAlgorithm.Create(algName);
            
			// Configure encrypt algorithm
			encryptionAlgorithm.Mode		= cipherMode;
			encryptionAlgorithm.Padding		= PaddingMode.PKCS7;
			encryptionAlgorithm.KeySize		= keyMaterialSize * 8;
			encryptionAlgorithm.BlockSize	= blockSize * 8;

			byte[] clientWriteKey	= new byte[]{161, 54, 179, 213, 89, 75, 130, 4, 186, 99, 158, 127, 19, 195, 175, 143, 79, 109, 25, 202, 237, 235, 62, 170};
			byte[] clientWriteIV	= new byte[]{193, 227, 54, 132, 68, 172, 55, 91};
				
			// Set the key and IV for the algorithm
			encryptionAlgorithm.Key = clientWriteKey;
			encryptionAlgorithm.IV	= clientWriteIV;
					
			// Create encryption cipher
			ICryptoTransform encryptionCipher = encryptionAlgorithm.CreateEncryptor();

			byte[] fragment = new byte[]{20, 0, 0, 12, 181, 134, 8, 230, 185, 75, 19, 129, 101, 142, 118, 190};
			byte[] mac		= new byte[]{42, 148, 229, 58, 185, 249, 154, 131, 157, 79, 176, 168, 143, 71, 0, 118, 5, 10, 95, 8};
																								  
			// Encryption ( fragment + mac [+ padding + padding_length] )
			MemoryStream ms = new MemoryStream();
			CryptoStream cs = new CryptoStream(ms, encryptionCipher, CryptoStreamMode.Write);

			cs.Write(fragment, 0, fragment.Length);
			cs.Write(mac, 0, mac.Length);
			if (cipherMode == CipherMode.CBC)
			{
				// Calculate padding_length
				int fragmentLength	= fragment.Length + mac.Length + 1;
				int padding			= (((fragmentLength/blockSize)*8) + blockSize) - fragmentLength;

				// Write padding length byte
				cs.WriteByte((byte)padding);
			}
			cs.Close();

			// Show result
			TripleDES.Print(ms.ToArray());
			
			// Now decrypt result

			// Create decryption cipher
			encryptionAlgorithm.Padding	 = PaddingMode.None;
			ICryptoTransform decryptionCipher = encryptionAlgorithm.CreateDecryptor();

			int	fragmentSize	= 0;
			int paddingLength	= 0;

			byte[] ecrFragment = ms.ToArray();

			// Decrypt message fragment ( fragment + mac [+ padding + padding_length] )
			byte[] buffer = new byte[ecrFragment.Length];
			decryptionCipher.TransformBlock(ecrFragment, 0, ecrFragment.Length, buffer, 0);

			// Calculate fragment size
			if (cipherMode == CipherMode.CBC)
			{
				// Calculate padding_length
				paddingLength = buffer[buffer.Length - 1];
				for (int i = (buffer.Length - 1); i > (buffer.Length - (paddingLength + 1)); i--)
				{
					if (buffer[i] != paddingLength)
					{
						paddingLength = 0;
						break;
					}
				}

				fragmentSize = (buffer.Length - (paddingLength + 1)) - hashSize;
			}
			else
			{
				fragmentSize = buffer.Length - hashSize;
			}

			byte[] dcrFragment	= new byte[fragmentSize];
			byte[] dcrMAC		= new byte[hashSize];

			Buffer.BlockCopy(buffer, 0, dcrFragment, 0, dcrFragment.Length);
			Buffer.BlockCopy(buffer, dcrFragment.Length, dcrMAC, 0, dcrMAC.Length);

			TripleDES.Print(dcrFragment);
			TripleDES.Print(dcrMAC);

			Console.WriteLine("Pulse una tecla para continuar....");
			Console.ReadLine();
		}

		public static void Print(byte[] content)
		{
			for (int i = 0; i < content.Length; i++)
			{
				Console.Write("{0}", content[i].ToString("x2"));
			}
			Console.WriteLine();
		}
	}
}

--------------010902020401050107080404--