现在,我一直在寻找将字符串加密到URL的完美方法。这是我找到的方法
Best method I found and it's on stackoverflow
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();
}
}
现在,当我查看使用
生成的加密字符串时 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");
所有字符串(var a1至a13)以“%3d%3d”
结尾由于节省存储空间对于此应用程序非常重要,我想知道我是否可以删除“%3d%3d”并在解码之前添加它以返回到原始URL。
任何人都可以就此提出一些建议。
谢谢,
答案 0 :(得分:6)
正如安德鲁所说,这是在base64末尾的填充。但是,我不同意他的结论。
我们知道格式良好的base64字符串总是4个字符的倍数。因此,只要我们可以信任我们一次性获得所有数据(即我们相信我们的URL没有被截断),我们可以在编码之前从base64字符串中删除任何尾随的'='字符。 URL。但是,在我们稍后调用Convert.FromBase64String
之前,我们需要将这些字符放回。幸运的是,我们可以这样做,因为我们知道根据我们得到的字符串的长度将有多少。你可以这样做,即使原始长度不是不变,即使在你的情况下也是如此。
另一个小问题 - “普通”base64字母对于网址来说不是很好;您可能希望使用替代版本,如described in Wikipedia:
在URL中使用标准Base64需要将'+','/'和'='字符编码为特殊的百分比编码十六进制序列('+'='%2B','/'='%2F'和' ='='%3D'),这使得字符串不必要地更长。 出于这个原因,存在修改后的Base64 for URL变体,其中不使用填充'=',标准Base64的'+'和'/'字符分别被' - '和'_'替换,因此使用URL编码器/解码器不再是必需的,并且对编码值的长度没有影响,保留相同的编码形式,通常用于关系数据库,Web表单和对象标识符。
我知道 .NET中的任何内容,这使得这样做很容易。最简单的方法是执行正常的base64转换,将+替换为 - ,/替换为_,然后使用string.TrimEnd
从末尾删除=
符号,并使用相反的解码操作。这比手动编码版本效率低得多,但考虑到你将使用的数据大小,它可能无关紧要。
答案 1 :(得分:1)
加密字符串末尾的数据是padding的示例。您必须保持字符串不变。