加密的字符串在结果中有一个斜杠 (/),这会导致 URL 中的问题
Encrypted string has a slash (/) in the result, which causes problems in a URL
我在网上四处寻找一个简单的小加密方法,它可以接受一个字符串,对其进行加密,然后对其进行解密。我的想法是我在 URL 中有我需要的 ID,但不能在计划文本中。
我发现 class 大多数时候都很好用,但有时,我最终会得到一个包含 / 的加密字符串:
OSprnGR/0os4DQpQsa0gIg==
正如您所想象的那样,在 URL 中使用它会导致问题。所以我想,如果我只是对字符串进行 UrlEncode,就可以解决问题。
没有。
即使 URL 看起来像这样,我仍然会遇到同样的错误:
http://localhost:54471/BrokerDashboard/BuyingLeads/LeadView/OSprnGR%2f0os4DQpQsa0gIg%3d%3d
而不是这个:
http://localhost:54471/BrokerDashboard/BuyingLeads/LeadView/OSprnGR/0os4DQpQsa0gIg==
HTTP Error 404.0 - Not Found
The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.
这是我正在使用的class:
public static class Encryption
{
public static string keyString { get { return "6C3A231C-57B2-4BA0-AFD6-306098234B11"; } }
private static byte[] salt = Encoding.ASCII.GetBytes("somerandomstuff");
public static string Encrypt(string plainText)
{
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(keyString, salt);
MemoryStream ms = new MemoryStream();
StreamWriter sw = new StreamWriter(new CryptoStream(ms, new RijndaelManaged().CreateEncryptor(key.GetBytes(32), key.GetBytes(16)), CryptoStreamMode.Write));
sw.Write(plainText);
sw.Close();
ms.Close();
string beforeUrlEncoded = Convert.ToBase64String(ms.ToArray());
string afterUrlEndcoded = HttpUtility.UrlEncode(beforeUrlEncoded);
return afterUrlEndcoded;
}
public static string Decrypt(string encrypted)
{
//string urlDecoded = HttpUtility.UrlDecode(encrypted); // <--- Turns out you don't need this
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(keyString, salt);
ICryptoTransform d = new RijndaelManaged().CreateDecryptor(key.GetBytes(32), key.GetBytes(16));
byte[] bytes = Convert.FromBase64String(encrypted);
return new StreamReader(new CryptoStream(new MemoryStream(bytes), d, CryptoStreamMode.Read)).ReadToEnd();
}
}
编辑:
路线如下:
routes.MapRoute(
name: "BrokerLead",
url: "BrokerDashboard/BuyingLeads/LeadView/{id}"
);
/
字符是保留字符,不能在路径部分使用。如果这是您 url 的最后一段,您可以使用以下路由使其工作(注意 {*id}
段):
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{*id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
另一种方法是在 encrypting/decrypting 时将此字符替换为其他字符,但通常您应该避免在 url 的路径部分中使用特殊字符,而只需将它们作为查询字符串放在您需要的位置可以正确地 url 编码一切。
也许这不是解决问题的最佳方法,但应该可行。
这一行之后:
string beforeUrlEncoded = Convert.ToBase64String(ms.ToArray());
您可以用一些其他符号(几个符号)替换斜杠(/
):
string replacement = "ItIsSlashReplacement";
beforeUrlEncoded = beforeUrlEncoded.Replace("/", replacement);
现在你将得到没有冗余的字符串/
。即,您已编码字符串 "abc/dce"
。替换后你将有 "abcItIsSlashReplacementdce"
- 没有 /
.
然后当你需要解码字符串时你应该反转你的替换:
string replacement = "ItIsSlashReplacement";
string originalEncodedString = stringWithReplacement.Replace(replacement, "/");
你得到"abcItIsSlashReplacementdce"
,恢复原来的-"abc/dce"
然后解码。
注意: 您可以选择一些字符串作为替换并将其编码为 base64
。但是应该顺便选择字符串,所以在解码后它不应该包含 /
.
我在网上四处寻找一个简单的小加密方法,它可以接受一个字符串,对其进行加密,然后对其进行解密。我的想法是我在 URL 中有我需要的 ID,但不能在计划文本中。
我发现 class 大多数时候都很好用,但有时,我最终会得到一个包含 / 的加密字符串:
OSprnGR/0os4DQpQsa0gIg==
正如您所想象的那样,在 URL 中使用它会导致问题。所以我想,如果我只是对字符串进行 UrlEncode,就可以解决问题。
没有。
即使 URL 看起来像这样,我仍然会遇到同样的错误:
http://localhost:54471/BrokerDashboard/BuyingLeads/LeadView/OSprnGR%2f0os4DQpQsa0gIg%3d%3d
而不是这个:
http://localhost:54471/BrokerDashboard/BuyingLeads/LeadView/OSprnGR/0os4DQpQsa0gIg==
HTTP Error 404.0 - Not Found The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.
这是我正在使用的class:
public static class Encryption
{
public static string keyString { get { return "6C3A231C-57B2-4BA0-AFD6-306098234B11"; } }
private static byte[] salt = Encoding.ASCII.GetBytes("somerandomstuff");
public static string Encrypt(string plainText)
{
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(keyString, salt);
MemoryStream ms = new MemoryStream();
StreamWriter sw = new StreamWriter(new CryptoStream(ms, new RijndaelManaged().CreateEncryptor(key.GetBytes(32), key.GetBytes(16)), CryptoStreamMode.Write));
sw.Write(plainText);
sw.Close();
ms.Close();
string beforeUrlEncoded = Convert.ToBase64String(ms.ToArray());
string afterUrlEndcoded = HttpUtility.UrlEncode(beforeUrlEncoded);
return afterUrlEndcoded;
}
public static string Decrypt(string encrypted)
{
//string urlDecoded = HttpUtility.UrlDecode(encrypted); // <--- Turns out you don't need this
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(keyString, salt);
ICryptoTransform d = new RijndaelManaged().CreateDecryptor(key.GetBytes(32), key.GetBytes(16));
byte[] bytes = Convert.FromBase64String(encrypted);
return new StreamReader(new CryptoStream(new MemoryStream(bytes), d, CryptoStreamMode.Read)).ReadToEnd();
}
}
编辑:
路线如下:
routes.MapRoute(
name: "BrokerLead",
url: "BrokerDashboard/BuyingLeads/LeadView/{id}"
);
/
字符是保留字符,不能在路径部分使用。如果这是您 url 的最后一段,您可以使用以下路由使其工作(注意 {*id}
段):
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{*id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
另一种方法是在 encrypting/decrypting 时将此字符替换为其他字符,但通常您应该避免在 url 的路径部分中使用特殊字符,而只需将它们作为查询字符串放在您需要的位置可以正确地 url 编码一切。
也许这不是解决问题的最佳方法,但应该可行。
这一行之后:
string beforeUrlEncoded = Convert.ToBase64String(ms.ToArray());
您可以用一些其他符号(几个符号)替换斜杠(/
):
string replacement = "ItIsSlashReplacement";
beforeUrlEncoded = beforeUrlEncoded.Replace("/", replacement);
现在你将得到没有冗余的字符串/
。即,您已编码字符串 "abc/dce"
。替换后你将有 "abcItIsSlashReplacementdce"
- 没有 /
.
然后当你需要解码字符串时你应该反转你的替换:
string replacement = "ItIsSlashReplacement";
string originalEncodedString = stringWithReplacement.Replace(replacement, "/");
你得到"abcItIsSlashReplacementdce"
,恢复原来的-"abc/dce"
然后解码。
注意: 您可以选择一些字符串作为替换并将其编码为 base64
。但是应该顺便选择字符串,所以在解码后它不应该包含 /
.