将字符串加密到C#中的URL
本文关键字:中的 URL 字符串 加密 | 更新日期: 2023-09-27 17:59:17
几个小时以来,我一直在寻找将字符串加密到URL的完美方法。这是我找到的方法
我找到的最好的方法,它在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");
所有字符串(变量a1到a13)都以"%3d%3d"结束
由于节省存储空间对这个应用程序非常重要,我想知道我是否可以删除"%3d%3d",然后在解码之前添加它,以返回到原始URL。
有人能给我一些建议吗。
谢谢,
正如Andrew所说,这是base64末尾的填充。然而,我不同意他的结论。
我们知道,一个格式良好的base64字符串的长度总是4个字符的倍数。因此,只要我们能够相信我们一次性获得了所有数据(即,我们相信我们的URL没有被截断),我们就可以在为URL编码之前从base64字符串中去掉任何尾随的"="字符。但是,在稍后调用Convert.FromBase64String
之前,我们需要将这些字符放回。幸运的是,我们可以做到这一点,因为我们知道根据字符串的长度会有多少。即使原始长度不是常量,也可以这样做,即使在您的情况下是。
另一个小问题是,"正常"的base64字母表对URL来说不太好;你可能想使用一个替代版本,如维基百科所述:
在URL中使用标准Base64需要将"+"、"/"answers"="字符编码为特殊百分比编码的十六进制序列("+"="%2B"、"/'="%2F"answers"='="%3D"),这会使字符串不必要地变长。因此,存在针对URL变体的修改后的Base64,其中不会使用填充"=",标准Base64的"+"answers"/"字符分别替换为"-"answers"_",因此不再需要使用URL编码器/解码器,也不会对编码值的长度产生影响,使相同的编码形式保持不变,可用于关系数据库、web表单,以及一般的对象标识符。
我不知道.NET中有什么东西让这件事变得容易高效。最简单的方法是执行普通的base64转换,将+替换为-,/替换为_,然后使用string.TrimEnd
从末尾移除=
符号,并使用相反的操作进行解码。这比手工编码的版本效率低得多,但考虑到您将要处理的数据的大小,这可能无关紧要。
加密字符串末尾的数据就是填充的示例。您必须保持字符串原样。