2012-04-05 183 views
1

讓我來解釋一下情況。在我的代碼中,我正在加密userid轉換爲註冊完成後生成的字符串。 ecrypted字符串作爲url參數傳遞,如下所示。UrlEncode未對+符號進行編碼,而解密格式異常即將到來

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

和:

我使用以UrlEncode通過加密的字符串,但問題是,如果加密的文本有一個「+」符號,而解密我得到一個格式異常,因爲這個'+'符號被視爲一個''空間。

例如,如果加密文本在獲取時與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可以解決這個問題,但對我來說,即使使用它並沒有解決問題後。

請讓我知道如何去做這件事? %2B -

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

問候 Srividhya

+0

你可以發佈'UrlEncode'的代碼嗎? – Oded 2012-04-05 09:33:34

+0

您的'UrlEncode'方法是否調用'HttpUtility.UrlEncode'? 'HttpUtility.Url * Decode *'方法用''代替'+',但'HttpUtility.UrlEncode'不應該。 – drf 2012-04-05 09:50:37

+1

的確,您是否使用.NET Framework庫的標準UrlEncode方法?因爲如果沒有,你應該。 – 2012-04-05 09:57:42

回答

0

你可以簡單地用percent encoding取代的+所有出現。

UrlEncode(ConfirmCode).Replace("+", "%2B") 
+0

UrlEncode *本身*應該這樣做,順便說一句。 :) – 2012-04-05 09:29:58

+0

@PetrAbdulin - 應該,是的。出於某種原因,OP正在使用的UrlEncode調用不會。 – Oded 2012-04-05 09:41:38

+0

這是我的問題..爲什麼UrlEncode不這樣做?如果它必須做? – Vidya 2012-04-05 10:02:16

0

OK,從你和其他的意見和答案給定的所有數據,我來只有一種可能合乎邏輯的結論:你的URL編碼字符串解碼兩次。第一次解碼S7%2B5tZzTm0k%3D給你S7+5tZzTm0k=,第二次解碼給你S7 5tZzTm0k=。這只是一個仔細調試的問題,以檢測地方有字符串被解碼兩次。

P.S.作爲驗證的一種方式,將值編碼兩次,然後它將被正確解碼。兩次編碼的url值應該是S7%252B5tZzTm0k%253D

+0

UrlDecode的代碼就像這樣 – Vidya 2012-04-05 10:00:39

+0

請參閱上面的UrlDecode的代碼 – Vidya 2012-04-05 10:03:12

+0

我已經發布了UrlDecode的代碼....上面請留言 – Vidya 2012-04-05 10:32:48

0

看了一下,我相信Request.QueryString會給你querystring中的內容的解碼版本,所以給你帶+的版本,然後你再次有效地解碼它,這是錯誤發生的地方。

行更改爲以下

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

(即去掉解碼),它應該工作。

+0

我試過這個,但..請看下面...字符串ConfirmCode = Request.QueryString [「ConfirmCode」]; isAccountSuspended = AccountManagement.AcountManager.EmailValidationNote(ConfirmCode);但即使如此,問題仍然存在 – Vidya 2012-04-05 10:39:38

+0

'ConfirmCode'包含什麼? – 2012-04-05 10:45:41

+0

你爲'Request.QueryString [「ConfirmCode」]'獲得什麼值?如果你傳遞'ConfirmCode = S7%2b5tZzTm0k%3d',那麼它應該是你想要的,我曾想過。你有可能從另一個地方得到例外嗎? – Chris 2012-04-05 10:46:51

0

這是推測性的,但我懷疑你可能會在同一個字符串上調用UrlDecode兩次。

您表示URL中的值爲ConfirmCode=S7%2b5tZzTm0k%3d,這是正確的(%2b是'+'的正確編碼)。

如果您解碼此字符串一次,您會得到S7+b5tZTm0k=,如預期。

如果您解碼字符串,您將得到S7 b5tZTm0k=,因爲'+'被解碼爲''。這就是你所看到的。

您可能希望查看解碼邏輯以確保結果字符串僅被解碼一次。

+0

當我將Request.QueryString [「ConfirmCode」]的值保存到字符串ConfirmCode,我得到值「S7 b5tZTm0k =」。請在URL中找到URL「Contents/Common/EN/EmailValidationPage.aspx?ConfirmCode = S7 + 5tZzTm0k =」... ConfirmCode已正確傳遞 – Vidya 2012-04-05 11:07:02

0

必需使用指令:using System.Security.Cryptography;

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

示例:字符串值= HttpUtility.UrlEncode(加密(值));

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