String Encryption for URL in C #

For hours, I have been searching for the perfect way to encrypt strings for URLs. Here is the method I found

stack overflow

using System; using System.IO; using System.Security.Cryptography; using System.Text; using System.Web; public class SimplerAES { private static byte[] key = { 123, 217, 19, 11, 24, 26, 85, 45, 114, 184, 27, 162, 37, 112, 222, 209, 241, 24, 175, 144, 173, 53, 196, 29, 24, 26, 17, 218, 131, 236, 53, 209 }; private static byte[] vector = { 146, 64, 191, 111, 23, 3, 113, 119, 231, 121, 221, 112, 79, 32, 114, 156 }; private ICryptoTransform encryptor, decryptor; private UTF8Encoding encoder; public SimplerAES() { RijndaelManaged rm = new RijndaelManaged(); encryptor = rm.CreateEncryptor(key, vector); decryptor = rm.CreateDecryptor(key, vector); encoder = new UTF8Encoding(); } public string Encrypt(string unencrypted) { return Convert.ToBase64String(Encrypt(encoder.GetBytes(unencrypted))); } public string Decrypt(string encrypted) { return encoder.GetString(Decrypt(Convert.FromBase64String(encrypted))); } public string EncryptToUrl(string unencrypted) { return HttpUtility.UrlEncode(Encrypt(unencrypted)); } public string DecryptFromUrl(string encrypted) { return Decrypt(HttpUtility.UrlDecode(encrypted)); } public byte[] Encrypt(byte[] buffer) { MemoryStream encryptStream = new MemoryStream(); using (CryptoStream cs = new CryptoStream(encryptStream, encryptor, CryptoStreamMode.Write)) { cs.Write(buffer, 0, buffer.Length); } return encryptStream.ToArray(); } public byte[] Decrypt(byte[] buffer) { MemoryStream decryptStream = new MemoryStream(); using (CryptoStream cs = new CryptoStream(decryptStream, decryptor, CryptoStreamMode.Write)) { cs.Write(buffer, 0, buffer.Length); } return decryptStream.ToArray(); } } 

Now when I look at the encrypted strings created with

  var a1 = _aes.EncryptToUrl("aaa"); var a2 = _aes.EncryptToUrl("aaaa"); var a3 = _aes.EncryptToUrl("aaaaa"); var a4 = _aes.EncryptToUrl("aaaaaa"); var a5 = _aes.EncryptToUrl("aaaaaaa"); var a6 = _aes.EncryptToUrl("aaaaaaaa"); var a7 = _aes.EncryptToUrl("aaaaaaaaa"); var a8 = _aes.EncryptToUrl("aaaaaaaaaa"); var a9 = _aes.EncryptToUrl("aaaaaaaaaaa"); var a10 = _aes.EncryptToUrl("aaaaaaaaaaa"); var a11 = _aes.EncryptToUrl("aaaaaaaaaaaa"); var a12 = _aes.EncryptToUrl("aaaaaaaaaaaaa"); var a13 = _aes.EncryptToUrl("aaaaaaaaaaaaaa"); 

All lines (var a1 - a13) end with "% 3d% 3d"

Since preserving the storage space is very important for this application, I wonder if I can just delete "% 3d% 3d" and add it later before decoding to return to the original URL.

Can anyone give me some advice on this.

Thanks,

+6
source share
2 answers

As Andrew says, this is an add-on at the end of base64. However, I do not agree with his conclusion.

We know that a well-formed base64 string is always a multiple of 4 characters in length. Therefore, while we can believe that we have all the data in one go (i.e., we trust that our URL is not truncated), we can remove any trailing "=" characters from the base64 string before we encoded for URL. However, we need to return these characters before we call Convert.FromBase64String . Fortunately, we can do this because we know how much will be based on the length of the string we received. You can do this even if the original length is not constant, although in your case it is.

Another minor point is that the "normal" base64 alphabet is not suitable for URLs; you can use an alternative version, for example, described on Wikipedia :

Using the standard Base64 in the URL requires encoding the characters "+", "/" and "=" in special hexadecimal sequences with hexadecimal encoding ("+" = "% 2B", "/" = "% 2F" and "= '=' % 3D '), which makes the line unnecessarily long. For this reason, there is a modified Base64 version for the URL in which padding' = 'will not be used, and the characters "+" and "/" of the standard Base64 are replaced with "-" and " _ ", therefore the use of URL encoders / decoders is no longer needed and does not affect the length of the encoded value, leaving the same encoders unchanged nnuyu form for use in relational databases, web forms, and object identifiers in general.

I don't know anything in .NET, which makes it easy to do this efficiently. The easiest approach is to perform a normal base64 conversion, replace + with -, / s _, and then use string.TrimEnd to remove the = signs from the end, with reverse operations for decoding. This is significantly less efficient than the manual version, but given the size of the data you will be working with, this may not matter.

+6
source

The data at the end of your encrypted string is an example of padding . You must leave the line as is.

+1
source

Source: https://habr.com/ru/post/890621/


All Articles