Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
VFPEncryption.fll implementation
Message
 
 
À
15/10/2014 05:43:14
Information générale
Forum:
ASP.NET
Catégorie:
Code, syntaxe and commandes
Versions des environnements
Environment:
VB 9.0
OS:
Windows Server 2008
Network:
Windows 2003 Server
Database:
MS SQL Server
Application:
Desktop
Divers
Thread ID:
01609313
Message ID:
01609445
Vues:
51
>>>>>>In a VFP application I use VFPEncryption.fll to encrypt a password string.
>>>>>>Now I need to be able to use the password from a .NET application (C#), so I need to decrypt the string that is saved in the table using C#. I wonder if there is an equivalent code for the decryption when the string was encrypted with VFPEncryption?
>>>>>>
>>>>>>The only workaround would be to create a com object from VFP, but if there is an easier solution I would be glad.
>>>>>
>>>>>
>>>>>Depending on what you're using you may be able to use RijndaelManaged http://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndaelmanaged(v=vs.110).aspx
>>>>
>>>>Thanks, that seems to be the right way. However I do not understand how to deal with the "Salt" variable, since in the VFPEncryption we don't use that. We only have the string and the password, however the class in .NET requires the salt to be 8 bytes.
>>>>
>>>>var algorithm = new RijndaelManaged { KeySize = 256, BlockSize = 128 };
>>>>var key = new Rfc2898DeriveBytes(password, Encoding.ASCII.GetBytes(""));
>>>>
>>>>In the second line it says "Salt is not at least eight bytes". When I put in 8 spaces or 8 zeros it does not throw an error, but the resulting string is completely incorrect. Do you have any idea what could be the "Default" salt?
>>>
>>>
>>>I'll have a look at it in the morning
>>>
>>>But first, before I can say anything useful - I have to see the vfp code used to both encrypt and decrypt
>>>
>>>UPDATE
>>>
>>>And an example - with hex output
>>
>>The code is just using the defaults (the security requirements are very low):
>>AES256
>>ECB
>>
>>LOCAL lcString, lcKey, lcEncryptedString
>>lcString = "Hello World"
>>lcKey = "abcdefghijasdflkgdfkisluguslijon"
>>lcEncryptedString = Encrypt (lcString, lcKey) && Result: ÕÖì/ŸŒ@‘PŒ{'VûGuï…‰È*RÞÖ¸‚þ.÷}
>>lcString = Decrypt(lcEncryptedString, lcKey) && Result: Hello World
>>
>
>(1) you don't need Rfc2898DeriveBytes()
>(2) I've changed the vfp code - added the defaults - reads better for me
>
>function EncryptionTest_Christian2()
>
>	set library to D:\tmp\In\vfpencryption90\vfpencryption.fll additive
>	
>	
>	local nEncryptionType, nEncryptionMode, nPaddingType, nKeySize, nBlockSize, cIV
>	
>	nEncryptionType = 2 &&  = Rijndael\AES 256 (requires a 32 character Key) *Default
>	nEncryptionMode = 0 &&	= ECB *Default
>	nPaddingType	= 0 &&	= Zeroes (NULLs) *Default
>	nKeySize		= 32	&& 
>	nBlockSize		= 32
>	cIV 			= replicate(chr(0), nBlockSize)
>	
>	LOCAL lcString, lcKey, lcEncryptedString
>	lcString = "Hello World"
>	lcKey = "abcdefghijasdflkgdfkisluguslijon"
>	lcEncryptedString = Encrypt (lcString, lcKey, ;
>				nEncryptionType, nEncryptionMode, nPaddingType, nKeySize, nBlockSize, cIV) && Result: ÕÖì/ŸŒ@‘PŒ{'VûGuï…‰È*RÞÖ¸‚þ.÷}
>	lcString = Decrypt(lcEncryptedString, lcKey, ;
>					nEncryptionType, nEncryptionMode, nPaddingType, nKeySize, nBlockSize, cIV	) && Result: Hello World
>		
>	?strconv(lcEncryptedString,15)
>	_cliptext = strconv(lcEncryptedString,15)
>	?lcString 
>
>
>
>(3) The code in C#
>(a) The padding with zeroes is not the best of ideas. The decryption leaves the trailing zeroes which have to be trimmed - and what if the original had trailing zeroes ?
>Better use PKCS7
>
>(b) You have to store the encryped value in a byte[] array - not a string
>
>
>	static class Encryption_Christian_Test
>	{
>
>		internal static void Go()
>		{
>			string original = @"Hello World";
>			string key = @"abcdefghijasdflkgdfkisluguslijon";
>
>			byte[] encrypted = Encryption_Christian.Encrypt(original, key);
>			string encryptedHex = HexBits.ToHex(encrypted);
>			string expected = @"D5D6EC2F9F8C4091508C7B2756FB4775EF168589C80B2A52DED6B882FE2EF77D";
>			Console.WriteLine("Encrypt >> OK: {0} Value: {1}", expected == encryptedHex, encryptedHex);
>
>			string decrypted = Encryption_Christian.Decrypt(encrypted, key);
>			// decrypted = padded with hex zeroes
>			// better use PaddingMode.PKCS7
>
>			decrypted = decrypted.TrimEnd(new char[1]); // to get the hex zeroes off at the end
>			Console.WriteLine("Decrypt >> OK: {0} Value: {1}", original == decrypted, decrypted);
>
>
>		}
>	}
>	internal static class Encryption_Christian
>	{
>
>		static RijndaelManaged Cryptor;
>
>
>		static int BitsPerByte = 8;
>
>		static int BlockSizeBytes = 32;
>
>		static byte[] IV = new byte[BlockSizeBytes];
>
>		static int KeySizeBytes = 32;
>
>		static Encryption_Christian()
>		{
>			Cryptor = new RijndaelManaged();
>			Cryptor.BlockSize = BlockSizeBytes * BitsPerByte;
>			Cryptor.KeySize = KeySizeBytes * BitsPerByte;
>			Cryptor.Mode = CipherMode.ECB;
>			Cryptor.Padding = PaddingMode.Zeros;
>
>		}
>
>		static internal byte[] Encrypt(string s, string key)
>		{
>			byte[] keyBytes = ToBytes(key);
>			byte[] encrypted;
>
>			using (MemoryStream output = new MemoryStream())
>			{
>				using (ICryptoTransform encryptor = Cryptor.CreateEncryptor(keyBytes, IV))
>				{
>					using (CryptoStream crypto = new CryptoStream(output, encryptor, CryptoStreamMode.Write))
>					{
>						using (StreamWriter input = new StreamWriter(crypto))
>						{
>							input.Write(s);
>							input.Flush(); // just in case
>
>						}
>
>					}
>
>				}
>				encrypted = output.ToArray();
>			}
>
>			return encrypted;
>		}
>		internal static string Decrypt(byte[] encrypted, string key)
>		{
>			byte[] keyBytes = ToBytes(key);
>
>			string decrypted;
>			using (MemoryStream input = new MemoryStream(encrypted))
>			{
>				using (ICryptoTransform decryptor = Cryptor.CreateDecryptor(keyBytes, IV))
>				{
>					using (CryptoStream crypto = new CryptoStream(input, decryptor, CryptoStreamMode.Read))
>					{
>						using (StreamReader output = new StreamReader(crypto))
>						{
>							decrypted = output.ReadToEnd();
>						}
>
>					}
>
>				}
>
>			}
>
>			return decrypted;
>		}
>		static byte[] ToBytes(string s)
>		{
>			
>			byte[] result = Encoding.Default.GetBytes(s);
>			if (s.Length != result.Length)
>				throw new ArgumentException("wrong resulting byte[] conversion length", "s");
>			return result;
>		}
>
>	}
>	internal static class HexBits
>	{
>
>		internal static string ToHex(byte[] bytes)
>		{
>			StringBuilder sb = new StringBuilder(bytes.Length << 1);
>			for (int i = 0; i < bytes.Length; i++)
>				sb.Append(bytes[i].ToString("X2"));
>			return sb.ToString();
>		}
>	}
>
Thank you so much, it took me a little time to implement, but it works perfectly!
Christian Isberner
Software Consultant
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform