2

I came across to this old C# code and I was wondering if with .NET Framework 4.5 is there something more elegant and compact to do the same thing: encrypt a text avoiding '=' chars in the result.

Thanks.

EDIT: in addition where the number 40 comes from and why longer text does not need to be processed?

    public static string BuildAutoLoginUrl(string username)
    {
        // build a plain text string as username#AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
        if (username.Length < 40)
        {
            //cycle to avoid '=' character at the end of the encrypted string
            int len = username.Length;

            do
            {
                if (len == username.Length)
                {
                    username += "#";
                }
                username += "A";
                len++;

            } while (len < 41);
        }

        return @"http://www.domain.com/Account/AutoLogin?key=" + EncryptStringAES(username, sharedKey);
    }

    public static string EncryptStringAES(string plainText, string sharedSecret)
    {
        if (string.IsNullOrEmpty(plainText))
            throw new ArgumentNullException("plainText");
        if (string.IsNullOrEmpty(sharedSecret))
            throw new ArgumentNullException("sharedSecret");

        string outStr = null; // Encrypted string to return
        RijndaelManaged aesAlg = null; // RijndaelManaged object used to encrypt the data.

        try
        {
            // generate the key from the shared secret and the salt
            Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(sharedSecret, _salt);

            // Create a RijndaelManaged object
            // with the specified key and IV.
            aesAlg = new RijndaelManaged();
            aesAlg.Key = key.GetBytes(aesAlg.KeySize/8);
            aesAlg.IV = key.GetBytes(aesAlg.BlockSize/8);

            // Create a decrytor to perform the stream transform.
            ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

            // Create the streams used for encryption.
            using (MemoryStream msEncrypt = new MemoryStream())
            {
                using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                    {
                        //Write all data to the stream.
                        swEncrypt.Write(plainText);
                    }
                }
                outStr = Convert.ToBase64String(msEncrypt.ToArray());
            }
        }
        finally
        {
            // Clear the RijndaelManaged object.
            if (aesAlg != null)
                aesAlg.Clear();
        }

        // Return the encrypted bytes from the memory stream.
        return outStr;
    }

Thanks.

abenci
  • 8,422
  • 19
  • 69
  • 134
  • 2
    Why do you need to avoid `=` in the output? – Lasse V. Karlsen Sep 13 '16 at 13:50
  • Don't strip the equals. Encode them into the URL. https://msdn.microsoft.com/en-us/library/zttxte6w(v=vs.110).aspx – Rob Sep 13 '16 at 13:51
  • That is padding to make the encrypted data the correct number of bytes. – Crowcoder Sep 13 '16 at 13:51
  • 1
    Is there an actual problem to be solved here? The code that appends to the string is ten lines long and easy to understand. – Eric Lippert Sep 13 '16 at 13:52
  • I mean, I could come up with code golf solutions all day. Say, take the string, concat with "#AAAAA,..." and take the 40 leftmost characters of the result. But if the code is working and debugged and tested then spend your time adding value some other way. – Eric Lippert Sep 13 '16 at 13:54
  • @Lasse: `=` is a problem when using the encrypted string in URLs – abenci Sep 13 '16 at 14:28
  • @Crowcoder: _the correct number of bytes_: correct for what? – abenci Sep 13 '16 at 14:30
  • @Eric: It looks so strange to me... Why should it build a 40 char string from a shorter username string? – abenci Sep 13 '16 at 14:32
  • 1
    @Alberto [read this about padding](https://en.wikipedia.org/wiki/Base64#Padding). The encoding has to be decodable so padding with "=" is how base 64 is implemented. – Crowcoder Sep 13 '16 at 14:46
  • 2
    Your update is: "in addition where the number 40 comes from and why longer text does not need to be processed?" So what you are saying is that you don't understand what this code is, or why it was implemented, but you are considering changing it. **Don't do that**. Understand the purpose of the code first, and then attempt to change it *if there is a good reason to do so*, such as fixing a correctness or performance problem. I don't understand it either, but I'm not planning on changing the code. – Eric Lippert Sep 13 '16 at 18:51

2 Answers2

2

The equal sign is there because that's part of it being a Base64 encoded string. It's Base64 encoded, because the encryption process results in a byte-array where not all of the items representable as readable text. I suppose you could try to encode as something other than Base64, but using Base32 or something is only going to make the resulting string far longer, and perhaps too long for the URL.

Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
0

I've solved using the "Catto" user answer for this StackOverflow question: Encrypt and decrypt a string

Community
  • 1
  • 1
abenci
  • 8,422
  • 19
  • 69
  • 134