如何在C#中加密/解密URL

4
我有一个URL:www.site-address/site-page/page1.aspx?username=deepu&password=deepu。我想把它改成www.site-address/site-page/page1.aspx?username=232322323232&password=2323232322323,也就是说,我想加密通过URL传递的字段。请帮我使用.NET在C#中加密和解密URL。目前我正在使用response.redirect并将这些值作为查询字符串传递。请帮忙。

11
深呼吸……标点符号是你的朋友。 - David Neale
1
我也想知道。虽然我不会像这样做,但“session”究竟是如何工作的? - Daren Thomas
3
如果你是一个用户,看到你的用户名和密码出现在URL中,就算它们被所谓的“加密”了,你会感到舒适吗?有人愿意举手吗? - Anthony Pegram
1
可能是重复的问题 https://dev59.com/oEnSa4cB1Zd3GeqPPJBR#1492927 和 https://dev59.com/o0XRa4cB1Zd3GeqPtJ7W - Sani Huttunen
4个回答

9

您希望的方式可能行不通,但是以下方法可以实现加密。

加密页面:

string id1 = "id1";

Response.Redirect("decryptionPage.aspx?id1=" + HttpUtility.UrlEncode(Encrypt(id1)));

private string Encrypt(string stringToEncrypt)
{
        byte[] inputByteArray = Encoding.UTF8.GetBytes(stringToEncrypt);
        byte[] rgbIV = { 0x21, 0x43, 0x56, 0x87, 0x10, 0xfd, 0xea, 0x1c };
        byte[] key = { };
        try
        {
            key = System.Text.Encoding.UTF8.GetBytes("A0D1nX0Q");
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            MemoryStream ms = new MemoryStream();
            CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(key, rgbIV), CryptoStreamMode.Write);
            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.FlushFinalBlock();
            return Convert.ToBase64String(ms.ToArray());
        }
        catch (Exception e)
        {
            return e.Message;
        }
}

解密页面:

string getId1 = Convert.ToString(Request.QueryString["id1"]);
var qs = Decrypt(HttpUtility.UrlDecode(getId1));
private string Decrypt(string EncryptedText)
{
        byte[] inputByteArray = new byte[EncryptedText.Length + 1];
        byte[] rgbIV = { 0x21, 0x43, 0x56, 0x87, 0x10, 0xfd, 0xea, 0x1c };
        byte[] key = { };

        try
        {
            key = System.Text.Encoding.UTF8.GetBytes("A0D1nX0Q");
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            inputByteArray = Convert.FromBase64String(EncryptedText);
            MemoryStream ms = new MemoryStream();
            CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(key, rgbIV), CryptoStreamMode.Write);
            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.FlushFinalBlock();
            System.Text.Encoding encoding = System.Text.Encoding.UTF8;
            return encoding.GetString(ms.ToArray());
        }
        catch (Exception e)
        {
            return e.Message;
        }
}

1
我在寻找一个类似的问题时发现了你的代码。它完美地运行,但是“Encrypt”方法生成的字符在添加到URL时会被替换为空格(例如+)。因此,“Decrypt”方法将无法按照我的期望工作。有什么解决办法吗? - Yalda

5
你的方法有缺陷,加密并不能真正解决根本问题。如果你在互联网上搜索,很少(甚至不应该)看到像你描述的模式,即使它是加密的。
相反,你应该尽可能安全地在服务器上存储用户凭据,并在查询字符串中传递一个唯一的、短暂的会话令牌,你可以使用它来查找凭据。
至于在服务器上安全存储,一旦你第一次收到用户的密码,你应该使用单向哈希,如SHA256,带有盐。你可以将这个值传递到任何地方,存储它,并验证一个潜在密码的哈希与你存储的哈希进行比较。把用户的密码视为有毒废物——尽快丢掉它。你不想成为密码存储业务或有毒废物存储业务的从业者。
(从我的iPhone回答,链接即将推出,或者如果有人想帮我! :))

谢谢回答,我需要将一些数据传递到另一个页面。如果我通过URL传递,我不希望客户端看到字段值。是否有可能以加密形式传递?我并不是说我想要这种形式... - deepu
1
@deepu 答案是“不要那样做”。这非常危险。 - Rex M
好的,那么我如何将一些值传递给另一个页面呢?除了使用server.transfer方法之外还有其他方法吗? - deepu
@deepu,正如我在回答中所说的 - 将凭据信息存储在数据库、会话或服务器上的其他位置,并通过查询字符串传递令牌ID - 在目标页面使用令牌再次查找信息。 - Rex M
2
“你想要从事密码存储业务的渴望程度,就像你想要从事有毒废物存储业务的渴望程度一样低。” - Daniel Pryden

3

您真的想这样做吗?如果您关注用户名和密码,那么您提供的信息或功能显然具有一定的价值。使用URL参数传递,您会留下许多攻击面(尤其是重放攻击,任何人都可以冒充您的用户)。

您真正想做什么,为什么不能使用ASP.NET中提供的内容


我同意。即使加密了,将凭据存储在查询字符串中也是非常不好的做法。很容易被某人截获查询字符串并冒充用户。 - J.Hendrix
嗯...我需要将一些数据传递到另一个页面..如果我通过URL传递,我不希望客户端看到字段的值..这就是我考虑加密值并传递的全部内容,这是否可行...有没有简单的方法... - deepu
1
你不需要传递用户名/密码!听说过会话吗?如果你只是看一下微软推荐的内容,这些都会自动处理。请务必查看标准的ASP.NET认证机制,我强烈建议你这么做! - Pontus Gagge

2
为什么不直接发布值而是使用查询字符串呢?至少通过SSL加密后,没有人能看到密码。在URL中添加密码并不能提供任何安全性。这就像把你家的钥匙撒在整个社区里,希望没有人会试着用它们打开你的房子一样。
基本上这是一个错误的前提。URL可以以多种方式缓存,因此最好不要在其中放置密码。
然而,在URL中放置密码并不是你一个人这样做。请看这个例子。

http://support.microsoft.com/kb/135975


当您需要从一个页面发送密码到另一个页面时,当然应该使用POST方法。如果您在页面上基于查询字符串使用某些值,则可以在此情况下使用它。 - Ankur Bhutani

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接