【问题标题】:Encrypted string has a slash (/) in the result, which causes problems in a URL加密字符串在结果中有斜杠 (/),这会导致 URL 出现问题
【发布时间】:2017-02-19 01:43:07
【问题描述】:

我在网上四处寻找一种简单的小加密方法,它可以接收一个字符串,加密它,然后解密它。我的想法是我在一个不能在计划文本中的 URL 中有我需要的 ID。

我发现的类大部分时间都很好用,但有时我会得到一个包含 / 的加密字符串:

OSprnGR/0os4DQpQsa0gIg==

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

它没有。

即使 URL 如下所示,我仍然会收到相同的错误:

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

【问题讨论】:

  • 你试过用HttpServerUtility.UrlTokenEncode代替HttpUtility.UrlEncode吗?
  • 只是确认您已经阅读了有关 bade64 的维基百科文章并放弃了使用它的 url 安全版本的可能性。我建议在帖子中澄清这一点。
  • @AlexeiLevenkov - .NET 有能力使用 URL Safe Base64 编码吗?
  • 没有。但是有很多答案显示了如何做到这一点......
  • 我已经回滚了您添加问题答案的无效编辑。如果您觉得需要单独的答案,请将其添加为答案。

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


【解决方案1】:

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

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

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

【讨论】:

  • 查看对我的 OP 的编辑,其中包括路线。那么,将 {id} 替换为 {*id} 会解决问题吗?
  • 不。现在我得到“匹配的路由不包含'控制器'路由值,这是必需的。”
  • 你的路由模式是不是像这样"{controller}/{action}/{*id}"
  • @Evk,他没有替换它,他只是将/ 编码为%2f,在这种情况下效果为零。为此,他需要将其实际替换为 URL 路径部分中允许的字符,例如 -_。但就我个人而言,我不会推荐这种方法,因为现在是/,明天它会是别的东西。如果您无法控制属于此路径段的字符,那么您最好将它们作为查询字符串参数发送。
  • 不,这根本不是错误。这是完全正常的。有些字符在 url 中使用时具有特殊含义,/ 就是其中之一。这就是原因,我再重复一遍,应该使用查询字符串。
【解决方案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。但是应该顺便选择字符串,所以解码后它不应该包含/

【讨论】:

  • 是的,我也有同样的想法,但想知道用它来替换我知道在任何情况下都可以使用的 /。意思...我需要一些“替换”中的字符串,这些字符串不会自然地出现在 Base64 编码的字符串中。
  • @CaseyCrookston,你可以选择一些replacement,也可以编码成base64,但是编码替换应该没有/,然后替换/。在这种情况下,您将一个 base64 插入另一个。
猜你喜欢
  • 1970-01-01
  • 2013-02-08
  • 1970-01-01
  • 2020-12-25
  • 1970-01-01
  • 2015-10-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多