0

In few post in stackoverflow I found a basic Encryption and Decryption with C#. I build one of the post as win form and it worked correctly.

I use a special key as: ZWT451+Route!Ydgp$8524*Aksdsvgh+

I use a string as: My name is overflow.

And this is what I get in return: MEPtmZFj3YaToiTT5V3xO/LwYo1U9YAt

I use this code and buil my Web API 2. Than I after run my web api 2 I use below link to send Encrypt data to web api 2 as shown below.

http://localhost:49407/api/MyCntRDS/MyCntRoute?fromacreli= MEPtmZFj3YaToiTT5V3xO/LwYo1U9YAt

Here is the error I get:

{"Message":"An error has occurred.","ExceptionMessage":"Invalid length for a Base-64 char array or string.","ExceptionType":"System.FormatException","StackTrace":"   at System.Convert.FromBase64_Decode(Char* startInputPtr, Int32 inputLength, Byte* startDestPtr, Int32 destLength)\r\n   at System.Convert.FromBase64CharPtr(Char* inputPtr, Int32 inputLength)\r\n   at System.Convert.FromBase64String(String s)\r\n   at ELITACR890LTKB.Controllers.Acr89Ltkb1939Controller.DecryptionACR890String

Later I remove my Encryption and Decryption in web api and send basic data as:

My#name#is#overflow

and worked perfectly.

Here is the code that it worked in C# WinForm and not in Web API 2.

Any help please.

public Form1()
{
    InitializeComponent();

}

    // BTN ENCRYPT +++++++++++++++++++++++++++++++++++++++++++++++
    private void Encrypt_Click(object sender, EventArgs e)
    {
        // Text String to be Encrypt    
        byte[] buffer = Encryption(textBox1.Text, txtKey.Text);
        string b = Convert.ToBase64String(buffer);

        // Password
        textBox2.Text = b;
    }

    // BTN DECRYPT +++++++++++++++++++++++++++++++++++++++++++++++
    private void Decrypt_Click(object sender, EventArgs e)
    {
        // Decrypt Text String
        textBox3.Text = Decryption(textBox2.Text, txtKey.Text);
    }


    // ENCRYPTION 
    public static byte[] Encryption(string PlainText, string key)
    {
        TripleDES des = CreateDES(key);
        ICryptoTransform ct = des.CreateEncryptor();
        byte[] input = Encoding.UTF8.GetBytes(PlainText);
        return ct.TransformFinalBlock(input, 0, input.Length);
    }


    // DECRYPTION
    public static string Decryption(string CypherText, string key)
    {
        byte[] b = Convert.FromBase64String(CypherText);
        TripleDES des = CreateDES(key);
        ICryptoTransform ct = des.CreateDecryptor();
        byte[] output = ct.TransformFinalBlock(b, 0, b.Length);
        return Encoding.UTF8.GetString(output);
    }

    // TRIPLEDES / 3DES
    static TripleDES CreateDES(string key)
    {
        MD5 md5 = new MD5CryptoServiceProvider();
        TripleDES des = new TripleDESCryptoServiceProvider();
        des.Key = md5.ComputeHash(Encoding.UTF8.GetBytes(key));
        des.IV = new byte[des.BlockSize / 8];
        return des;
    }
}

And this is the web api code that I get an error.

   [RoutePrefix("api/MyCntRoute")]
public class MyCntRDS: ApiController
{
        string _SpecialKey = "ZWT451+Route!Ydgp$8524*Aksdsvgh+// 32 Character

        [Route("MyCntRoute")]
        [HttpGet]
        public List<ACR1939ELITE> Get(string fromterminal)
        {

            getDataFromACR890 = DecryptionACR890String(fromterminal, _SpecialKey);

            ..............
         ..............
         ..............
        }
}


        // DECRYPTION
        private static string DecryptionACR890String (string fromterminal, string _SpecialKey)
        {
            byte[] b = Convert.FromBase64String(fromterminal);
            TripleDES des = CreateDes(_SpecialKey);
            ICryptoTransform ct = des.CreateDecryptor();
            byte[] output = ct.TransformFinalBlock(b, 0, b.Length);
            return Encoding.UTF8.GetString(output);
        }
NTMS
  • 816
  • 7
  • 22
  • 1
    that looks like the code that worked, you should post the one that DIDNT work. but regardless, looks like "fromacreli= MEPtmZFj3YaToiTT5V3xO/LwYo1U9YAt" should be "fromacreli=MEPtmZFj3YaToiTT5V3xO/LwYo1U9YAt" – Yuval Perelman Mar 07 '16 at 11:24
  • @NTMS Put a breakpoint in your decryption method to see what it is attempting to decrypt.BASE64 should be multiples of 4 in length. As user2033402 said, you have a space at the start. – CathalMF Mar 07 '16 at 11:37
  • I did the brak point but didnt work. I try to use Enable System.Diagnostics Tracing in Web API and that didnt worked either. (h**p://w*w.asp.net/web-api/overview/testing-and-debugging/tracing-in-aspnet-web-api) – NTMS Mar 07 '16 at 11:44
  • 2
    `MEPtmZFj3YaToiTT5V3xO/LwYo1U9YAt` *is* a valid base 64 string & would decode, so its not what is passed in `fromterminal`, set a breakpoint and see. This is likely because of improper url encoding see [How to achieve Base64 URL safe encoding in C#?](http://stackoverflow.com/questions/26353710/how-to-achieve-base64-url-safe-encoding-in-c) – Alex K. Mar 07 '16 at 11:44
  • @Alex in your link they use ASCII and my encoded string is Encoding.UTF8.GetBytes. Should I have to change this from both end? – NTMS Mar 07 '16 at 12:00
  • For encoding a Base64 string? Doesn't matter, all the characters that can appear in a base64 string will be the same in ascii/utf8 – Alex K. Mar 07 '16 at 12:02
  • ok. this time I get "Invalid length for a Base-64 char array or string." error – NTMS Mar 07 '16 at 12:04
  • @Alex my original encoded string is: lvi3sLGm2jivQycU9dO+w/YNk3olpLraxDAsk3BtdbgYsxtJ7PAgObnxycT4JxgSZmOmShqIGgM= and after I follow the link that you provided my string become like this lvi3sLGm2jivQycU9dO w/YNk3olpLraxDAsk3BtdbgYsxtJ7PAgObnxycT4JxgSZmOmShqIGgM= – NTMS Mar 07 '16 at 12:22
  • this part U9dO+w/YNk become U9dO w/YNk. It removes + sign with white spaces. What's wrong? – NTMS Mar 07 '16 at 12:24
  • This is not a secure way to use 3DES. By setting the IV to `new byte[des.BlockSize / 8]`, you are always using the same IV. It should be random; a fixed IV is effectively [ECB](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Electronic_Codebook_.28ECB.29). Also, why use 3DES if it has long been replaced by AES? – Wim Coenen Mar 07 '16 at 12:48
  • @Wim my embedded linux terminal use open ssl with 3DES. Do you have example for both end so I can use AES? – NTMS Mar 07 '16 at 14:41
  • @NTMS See the example on MSDN for [AESCryptoServiceProvider](https://msdn.microsoft.com/en-us/library/system.security.cryptography.aescryptoserviceprovider%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396). You will also need to concatenate the IV+ciphertext bytes, convert to base64, convert back to bytes on the other end, and split IV from ciphertext again. – Wim Coenen Mar 07 '16 at 14:58

1 Answers1

0

@Alex it worked with this:

string incoming = returnValue.Replace('_', '/').Replace('-', '+').Replace(' ', '+');

I added .Replace(' ', '+'); part to replace original + code with empty space.

You provided a link and partialy it worked.

How to achieve Base64 URL safe encoding in C#?

Community
  • 1
  • 1
NTMS
  • 816
  • 7
  • 22