加密字符串在结果中有斜杠(/),这会导致URL出现问题

时间:2017-02-18 16:48:12

标签: c# asp.net-mvc encryption url-encoding

我在网上找到了一个简单的小加密方法,它会接受一个字符串,对其进行加密,然后对其进行解密。我的想法是,我需要一个不能在计划文本中的URL。

我发现的课程大部分时间都很有用,但有时候,我最终会得到一个带有/的加密字符串:

OSprnGR/0os4DQpQsa0gIg==

您可以想象,在URL中使用时会导致问题。所以我想如果我只是对字符串进行UrlEncode,它就可以解决问题。

没有。

即使网址如下所示,我仍然会收到同样的错误:

http://localhost:54471/BrokerDashboard/BuyingLeads/LeadView/OSprnGR%2f0os4DQpQsa0gIg%3d%3d

而不是:

http://localhost:54471/BrokerDashboard/BuyingLeads/LeadView/OSprnGR/0os4DQpQsa0gIg==
  

HTTP错误404.0 - 未找到   您要查找的资源已被删除,名称已更改或暂时不可用。

这是我正在使用的课程:

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}"
);

2 个答案:

答案 0 :(得分:6)

/字符是保留的,不能在路径部分中使用。如果这是您网址的最后一段,您可以使用以下路由使其正常工作(请注意{*id}段):

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{*id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

另一种方法是在加密/解密时用其他方法替换这个字符,但一般来说,你应该避免网址路径部分中的特殊字符,只需将它们作为查询字符串,你可以正确地对所有内容进行编码。

答案 1 :(得分:2)

也许这不是解决问题的最好方法,但它应该有效。

这一行之后:

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。但是应该选择字符串,因此在解码之后它不应该包含/