1

让我解释一下情况。在我的代码中,我将用户标识加密为注册完成后生成的字符串。加密后的字符串作为 url 参数传递,如下所示。

 string ConfirmCode = string.Empty;
Common.Secure.Security mySec = new Common.Secure.Security();
ConfirmCode  = mySec.Encrypt(myMember.MemberID.ToString());

string EmailValidationLink = "<a  href=\'" + pageScheme + "://" + CurrentDomain.HostName + "/Contents/Common/" + "EN" + "/" + CurrentDomain.EmailValidationPage + "?ConfirmCode=" + **UrlEncode(ConfirmCode)** + "\'>Click here to validate your account.</a>";

和:

protected String UrlEncode(String text) 
{ 
  return HttpContext.Current.Server.UrlEncode(text); 
}

我正在使用 UrlEncode 传递加密字符串,但问题是加密文本是否有一个 '+' 符号,而解密时我得到一个 Format Exception ,因为这个 '+' 符号被视为一个 ' ' 空间。

例如,如果加密文本在获取时类似于“S7+5tZzTm0k=”,则 + 符号被视为“S7 5tZzTm0k=”,这会导致格式异常。

我的加密和解密代码如下

public string Decrypt(string Text)
{
    if (!ENABLED) return Text;
    des.Key = hashmd5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(myKey));
    des.Mode = CipherMode.ECB;
    ICryptoTransform desdencrypt = des.CreateDecryptor();
    Byte[] buff = Convert.FromBase64String(Text);
    return ASCIIEncoding.ASCII.GetString(desdencrypt.TransformFinalBlock(buff, 0, buff.Length));
}

public string Encrypt(string Text)
{
    if (!ENABLED) return Text;
    des.Key = hashmd5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(myKey));
    des.Mode = CipherMode.ECB;
    ICryptoTransform desdencrypt = des.CreateEncryptor();
    ASCIIEncoding MyASCIIEncoding = new ASCIIEncoding();
    Byte[] buff = ASCIIEncoding.ASCII.GetBytes(Text);
    return Convert.ToBase64String(desdencrypt.TransformFinalBlock(buff, 0, buff.Length));
}

我一直在谷歌上搜索这个,每个人都建议使用 UrlEncode 可以解决问题,但在我的情况下,即使使用它也没有解决问题。

请让我知道该怎么做?

if (Request.QueryString["ConfirmCode"] != null)
            { 
                bool isAccountSuspended;
                isAccountSuspended = AccountManagement.AcountManager.EmailValidationNote(HttpContext.Current.Server.UrlDecode(Request.QueryString["ConfirmCode"]));

                if (!isAccountSuspended)
                {
                    lblMessage.Text = "Your account is already suspended. Please contact customer service.";
                    lblMessage.ForeColor = System.Drawing.Color.Red;
                }
                else
                {
                    lblMessage.Text = "Thank you for verifying your email address. We hope you’ll enjoy playing with us.";
                }
            }

问候斯里维迪亚

4

5 回答 5

1

需要使用指令:使用 System.Security.Cryptography;

Way to encrypt: HttpUtility.UrlEncode(Encrypt(Value));

示例:字符串值=HttpUtility.UrlEncode(Encrypt(Value));

Way to decrypt: Decrypt(HttpUtility.UrlDecode(value);

private string Encrypt(string clearText)
{
    string EncryptionKey = "MAKV2SPBNsdsI99212";
    byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
    using (Aes encryptor = Aes.Create())
    {
        Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
        encryptor.Key = pdb.GetBytes(32);
        encryptor.IV = pdb.GetBytes(16);
        using (MemoryStream ms = new MemoryStream())
        {
            using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
            {
                cs.Write(clearBytes, 0, clearBytes.Length);
                cs.Close();
            }
            clearText = Convert.ToBase64String(ms.ToArray());
        }
    }
    return clearText;
}
private string Decrypt(string cipherText)
{
    string EncryptionKey = "MAKV2SPBNsdsI99212";
    cipherText = cipherText.Replace(" ", "+");
    byte[] cipherBytes = Convert.FromBase64String(cipherText);
    using (Aes encryptor = Aes.Create())
    {
        Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
        encryptor.Key = pdb.GetBytes(32);
        encryptor.IV = pdb.GetBytes(16);
        using (MemoryStream ms = new MemoryStream())
        {
            using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
            {
                cs.Write(cipherBytes, 0, cipherBytes.Length);
                cs.Close();
            }
            cipherText = Encoding.Unicode.GetString(ms.ToArray());
        }
    }
    return cipherText;
}
于 2014-10-29T12:21:09.663 回答
0

+您可以简单地用百分比编码替换所有出现的- %2B

UrlEncode(ConfirmCode).Replace("+", "%2B")
于 2012-04-05T09:19:49.467 回答
0

稍微看一下,我相信这Request.QueryString将为您提供查询字符串中内容的解码版本,从而为您提供带有 + 的版本,然后您再次有效地对其进行解码,这就是错误发生的地方。

将行更改为以下内容

isAccountSuspended = AccountManagement.AcountManager.EmailValidationNote(Request.QueryString["ConfirmCode"]);

(即删除解码),它应该工作。

于 2012-04-05T10:30:43.327 回答
0

这是推测性的,但我怀疑您可能会UrlDecode两次调用同一字符串。

您指出 URL 中的值为ConfirmCode=S7%2b5tZzTm0k%3d,这是正确的(%2b 是 '+' 的正确编码)。

如果你解码这个字符串一次,你会得到S7+b5tZTm0k=,如预期的那样。

如果你解码那个字符串,你会得到S7 b5tZTm0k=,因为 '+' 被解码为 ' '。这就是你所看到的。

您可能需要查看您的解码逻辑以确保生成的字符串仅被解码一次。

于 2012-04-05T10:55:40.663 回答
0

好的,根据您提供的所有数据以及其他评论和答案,我得出的只有一个可能的逻辑结论:您的 url 编码字符串被解码两次。第一次解码S7%2B5tZzTm0k%3D给你S7+5tZzTm0k=,第二次解码给你S7 5tZzTm0k=。只需仔细调试即可检测字符串被 url 解码两次的位置。

PS 作为验证的一种方式,对值进行两次编码,然后它将被正确解码。两次编码的 url 值应该是S7%252B5tZzTm0k%253D.

于 2012-04-05T09:27:57.923 回答