Question

Sudip_inn on Fri, 30 Dec 2016 15:31:47


when i am passing normal alphabet to my encrypt and decrypt function then it is working as expected but when i am passing alphanumeric text to encrypt and decrypt function then it is not working.

say when i pass encrypt("test1") or decrypt("test1") then it is not working. specially decrypt not working with alphanumeric case.

i want to restructure my encrypt and decrypt function as a result whatever value i pass the function can work. suppose i may pass alpha numeric data with special character. so plerase see the code and come with rectified version.

a small wrapper around encrypt/decrypt

       private string encrypt(string message)
        {
            EncryptClass.EncryptClass ec = new EncryptClass.EncryptClass();
            string encryStr = ec.custEncrypt(message);
            return encryStr;
        }

        private string decrypt(string message)
        {
            EncryptClass.EncryptClass ec = new EncryptClass.EncryptClass();
            string decryptStr = message;
            return ec.custDecrypt(decryptStr);
        }

full code for encrypt ans decrypt

    public class EncryptClass
    {
        DESCryptoServiceProvider rj;
        byte[] key = new byte[] { 11, 9, 3, 4, 1, 8, 12, 7 };
        byte[] IV = new byte[] { 1, 8, 7, 16, 1, 9, 0, 3 };
        public EncryptClass()
        {
            //
            // TODO: Add constructor logic here
            //
            rj = new DESCryptoServiceProvider();
        }

        // for encryption
        public string custEncrypt(string message)
        {
            //create a memory stream
            MemoryStream ciphertextmem = new MemoryStream();
            //create a crypto stream in write mode
            CryptoStream crystm = new CryptoStream(ciphertextmem, rj.CreateEncryptor(key, IV), CryptoStreamMode.Write);
            //Encode the passed plain text string into Unicode byte stream
            Byte[] plaintextbyte = new UnicodeEncoding().GetBytes(message);
            //Write the plaintext byte stream to CryptoStream
            crystm.Write(plaintextbyte, 0, plaintextbyte.Length);
            //don't forget to close the stream
            crystm.Close();
            //Extract the ciphertext byte stream and close the MemoryStream
            Byte[] ciphertextbyte = ciphertextmem.ToArray();
            ciphertextmem.Close();
            //Encode the ciphertext byte into Unicode string
            string ciphertext = new UnicodeEncoding().GetString(ciphertextbyte);
            return ciphertext;
            //return "encry " + message;


        }

        // for decryption
        public string custDecrypt(string message)
        {
            //Create a memory stream from which CryptoStream will read the cipher text
            MemoryStream ciphertextmem = new MemoryStream(new UnicodeEncoding().GetBytes(message));

            //Create a CryptoStream in Read Mode; initialise with the Rijndael's Decryptor ICryptoTransform
            CryptoStream crystm = new CryptoStream(ciphertextmem, rj.CreateDecryptor(key, IV), CryptoStreamMode.Read);

            //Create a temporary memory stream to which we will copy the 
            //plaintext byte array from CryptoStream

            MemoryStream plaintextmem = new MemoryStream();
            do
            {
                //Create a byte array into which we will read the plaintext 
                //from CryptoStream
                Byte[] buf = new Byte[100];

                //read the plaintext from CryptoStream
                int actualbytesread = crystm.Read(buf, 0, 100);

                //if we have reached the end of stream quit the loop
                if (0 == actualbytesread)
                    break;

                //copy the plaintext byte array to MemoryStream
                plaintextmem.Write(buf, 0, actualbytesread);

            } while (true);

            //don't forget to close the streams
            crystm.Close();
            ciphertextmem.Close();

            //Extract the plaintext byte stream and close the MemoryStream
            Byte[] plaintextbyte = plaintextmem.ToArray();
            plaintextmem.Close();

            //Encode the plaintext byte into Unicode string
            string plaintext = new UnicodeEncoding().GetString(plaintextbyte);

            return plaintext;

            //return "decry "+ message;
        }
    }

please see my code and rectified area as a result it should work if i pass only text or if i pass text with numeric data or alphanumeric with special character.

looking for help.


Sponsored



Replies

Alberto Poblacion on Sat, 31 Dec 2016 12:56:11


I can see a problem when you do things like this:

string ciphertext = new UnicodeEncoding().GetString(ciphertextbyte);
           

The ciphertextbyte is an array of bytes that contains binary values for the encrypted text. Those binary values can have any possible value, and many of these values will not be equivalent to any legal Unicode Encoding. Therefore, the GetString will return an unpredictabe string that you will not be able to then convert back into bytes when you wan to decode your ciphered text. It may work for SOME strings when you are lucky enough that the ciphered values happen to all be legitimate Unicode encodings, and it will fail for other strings. It's not a matter of containing "alphanumeric text" like you mentioned, but a matter of random luck depending on how the plaintext encodes into the cyphertext.

If you need to handle your encoded content as strings instead of byte arrays, then it is better to convert the byte array by means of a mechanism that is valid for all possible byte values. For instance, you can use Convert.ToBase64 instead of UnicodeEncoding.GetString. And, obviously, Convert.FromBase64 when you want to perform decoding.

Christopher84 on Sun, 01 Jan 2017 06:37:03


And with Unicode you also have to consider stuff like normalisation when reading/writing them from binary sources:
https://msdn.microsoft.com/en-us/library/8eaxk1x2.aspx

Converting strings to bytes and vice versa is one of the areas where a lot of stuff can go wrong, without even getting close to to the right stuff.
Normalizing and then handing it off to a covert function is usually adviseable.

Sudip_inn on Tue, 10 Jan 2017 09:12:52


another person gave this solution for encrypt and decrypt

public class EncryptClass
{
	const int hashCount = 21569;

	public static string EncryptString(string message, string pass)
	{
	using (RijndaelManaged rij = new RijndaelManaged())
	{
	    rij.GenerateIV();
	    rij.Key = HashPassword(pass);

	    using (ICryptoTransform cryptor = rij.CreateEncryptor())
	    {
		var data = Encoding.Unicode.GetBytes(message);
		var buff = cryptor.TransformFinalBlock(data, 0, data.Length);
		// concat to the IV for the other side
		// crypto data is binary - use Base64 for text encoding
		return Convert.ToBase64String(rij.IV.Concat(buff).ToArray());
	    }
	}
	}

	private static byte[] HashPassword(string thePW)
	{
	// originally from RNGCryptoServiceProvider.GetRandomBytes
	byte[] salt = new byte[] { 96, 248, 204, 72, 177, 214, 251, 82, 174, 
			90, 82, 90, 111, 76, 146, 172 };

	using (var hasher = new Rfc2898DeriveBytes(thePW, salt, hashCount))
	{
	    return hasher.GetBytes(32);
	}
	}

	public static string DecryptString(string crypted, string pass)
	{
	    byte[] data = Convert.FromBase64String(crypted);
	    using (RijndaelManaged rij = new RijndaelManaged())
	    {
		int size = (int)(rij.BlockSize / 8);
		byte[] iv = new byte[size];

		// copy the iv to the array
		Array.Copy(data, 0, iv, 0, size);

		rij.IV = iv;
		rij.Key = HashPassword(pass);

		using (ICryptoTransform cryptor = rij.CreateDecryptor())
		{
		    var buff = cryptor.TransformFinalBlock(data, size, data.Length - size);
		    return Encoding.Unicode.GetString(buff);
		}
	    }
	}    
}

string msg = "This is some text 123 1 87  45";

string crypto = EncryptClass.EncryptString(msg, "I Like Pi");
Console.WriteLine(crypto);
string retVal = EncryptClass.DecryptString(crypto, "I Like Pi");
Console.WriteLine(retVal);

what is the meaning of IV and what it is ?

please see the code and share your thoughts. thanks