加密和解密密码

我使用以下代码加密和解密asp.net中的密码。 加密工作完美,但解密时抛出此错误Invalid length for a Base-64 char array.

我的密码是123,我使用它如下加密: HttpUtility.UrlEncode(CryptorEngine.Encrypt(strpassword, true)); 并解密我使用它如下:

 CryptorEngine.Decrypt(HttpUtility.UrlDecode(strpassword), true)); 

这是代码:

  public class CryptorEngine { ///  /// Encrypt a string using dual encryption method. Return a encrypted cipher Text ///  /// string to be encrypted /// use hashing? send to for extra secirity ///  public static string Encrypt(string toEncrypt, bool useHashing) { byte[] keyArray; byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt); System.Configuration.AppSettingsReader settingsReader = new AppSettingsReader(); // Get the key from config file string key = (string)settingsReader.GetValue("SecurityKey", typeof(String)); //System.Windows.Forms.MessageBox.Show(key); if (useHashing) { MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider(); keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key)); hashmd5.Clear(); } else keyArray = UTF8Encoding.UTF8.GetBytes(key); TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider(); tdes.Key = keyArray; tdes.Mode = CipherMode.ECB; tdes.Padding = PaddingMode.PKCS7; ICryptoTransform cTransform = tdes.CreateEncryptor(); byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); tdes.Clear(); return Convert.ToBase64String(resultArray, 0, resultArray.Length); } ///  /// DeCrypt a string using dual encryption method. Return a DeCrypted clear string ///  /// encrypted string /// Did you use hashing to encrypt this data? pass true is yes ///  public static string Decrypt(string cipherString, bool useHashing) { byte[] keyArray; byte[] toEncryptArray = Convert.FromBase64String(cipherString); System.Configuration.AppSettingsReader settingsReader = new AppSettingsReader(); //Get your key from config file to open the lock! string key = (string)settingsReader.GetValue("SecurityKey", typeof(String)); if (useHashing) { MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider(); keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key)); hashmd5.Clear(); } else keyArray = UTF8Encoding.UTF8.GetBytes(key); TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider(); tdes.Key = keyArray; tdes.Mode = CipherMode.ECB; tdes.Padding = PaddingMode.PKCS7; ICryptoTransform cTransform = tdes.CreateDecryptor(); byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); tdes.Clear(); return UTF8Encoding.UTF8.GetString(resultArray); } } 

在URL中出现与加密输出冲突的字符,至少在我的代码中,这就是导致问题的原因。 所以我使用这两个函数来改变这个角色并避免这种情况。

 public static string ChangeSPChart(string sTheInput) { StringBuilder sRetMe = new StringBuilder(sTheInput); sRetMe.Replace('+', '-'); sRetMe.Replace('/', '*'); sRetMe.Replace('=', '!'); return sRetMe.ToString(); } public static string FixSPChart(string sTheInput) { StringBuilder sRetMe = new StringBuilder(sTheInput); sRetMe.Replace('-', '+'); sRetMe.Replace('*', '/'); sRetMe.Replace('!', '='); return sRetMe.ToString(); } 

加密/解密代码将是:

 public static string Encrypt(string toEncrypt, bool useHashing) { byte[] keyArray; byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt); System.Configuration.AppSettingsReader settingsReader = new AppSettingsReader(); // Get the key from config file string key = (string)settingsReader.GetValue("SecurityKey", typeof(String)); //System.Windows.Forms.MessageBox.Show(key); if (useHashing) { MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider(); keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key)); hashmd5.Clear(); } else keyArray = UTF8Encoding.UTF8.GetBytes(key); TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider(); tdes.Key = keyArray; tdes.Mode = CipherMode.ECB; tdes.Padding = PaddingMode.PKCS7; ICryptoTransform cTransform = tdes.CreateEncryptor(); byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); tdes.Clear(); var encrypted = Convert.ToBase64String(resultArray, 0, resultArray.Length); // here I change it return ChangeSPChart(encrypted); } ///  /// DeCrypt a string using dual encryption method. Return a DeCrypted clear string ///  /// encrypted string /// Did you use hashing to encrypt this data? pass true is yes ///  public static string Decrypt(string cipherString, bool useHashing) { cipherString = FixSPChart(cipherString); byte[] keyArray; byte[] toEncryptArray = Convert.FromBase64String(cipherString); System.Configuration.AppSettingsReader settingsReader = new AppSettingsReader(); //Get your key from config file to open the lock! string key = (string)settingsReader.GetValue("SecurityKey", typeof(String)); if (useHashing) { MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider(); keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key)); hashmd5.Clear(); } else keyArray = UTF8Encoding.UTF8.GetBytes(key); TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider(); tdes.Key = keyArray; tdes.Mode = CipherMode.ECB; tdes.Padding = PaddingMode.PKCS7; ICryptoTransform cTransform = tdes.CreateDecryptor(); byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length); tdes.Clear(); return UTF8Encoding.UTF8.GetString(resultArray); } 

hiii请使用此代码,这很好用

//信用卡的加密方法

 public string EncryptTripleDES(string Plaintext, string Key) { System.Security.Cryptography.TripleDESCryptoServiceProvider DES = new System.Security.Cryptography.TripleDESCryptoServiceProvider(); System.Security.Cryptography.MD5CryptoServiceProvider hashMD5 = new System.Security.Cryptography.MD5CryptoServiceProvider(); DES.Key = hashMD5.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(Key)); DES.Mode = System.Security.Cryptography.CipherMode.ECB; System.Security.Cryptography.ICryptoTransform DESEncrypt = DES.CreateEncryptor(); Buffer = System.Text.ASCIIEncoding.ASCII.GetBytes(Plaintext); string TripleDES = Convert.ToBase64String(DESEncrypt.TransformFinalBlock(Buffer, 0, Buffer.Length)); return TripleDES; } //Decryption Method public string DecryptTripleDES(string base64Text, string Key) { System.Security.Cryptography.TripleDESCryptoServiceProvider DES = new System.Security.Cryptography.TripleDESCryptoServiceProvider(); System.Security.Cryptography.MD5CryptoServiceProvider hashMD5 = new System.Security.Cryptography.MD5CryptoServiceProvider(); DES.Key = hashMD5.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(Key)); DES.Mode = System.Security.Cryptography.CipherMode.ECB; System.Security.Cryptography.ICryptoTransform DESDecrypt = DES.CreateDecryptor(); Buffer = Convert.FromBase64String(base64Text); string DecTripleDES = System.Text.ASCIIEncoding.ASCII.GetString(DESDecrypt.TransformFinalBlock(Buffer, 0, Buffer.Length)); return DecTripleDES; } 

您提供的代码工作正常。 我用这个小程序测试了它:

 void Main() { var cryptB64 =CryptorEngine.Encrypt("123", true); var encoded = HttpUtility.UrlEncode(cryptB64); var decoded = HttpUtility.UrlDecode(encoded); var decrypted = CryptorEngine.Decrypt(decoded, true); bool matches = (decrypted=="123"); Console.WriteLine(matches); } 

它按预期返回true。

问题可能是您在某个时刻破坏了加密值。 我猜它是通过HTTP传输的,我猜这是问题发生的地方。

附加说明:

当调用CryptorEngine.Decrypt(HttpUtility.UrlDecode(strpassword), true)); 那么你需要确保strpassword是密码的加密forms,而不是你要比较的明文密码。

这里有点晚了,但问题可能是别的(这对我而言)。

Request.Querystring已经进行了一些解码。 在我的情况下,我基本上解码了两次。 添加第二个“HttpUtility.UrlEncode”就可以了(至少在20次不同的测试之后)。

我没有找到微软关于这种行为的确切文档,并且旧书被存储起来(我尽量不要离开我的椅子),但这些链接很有用:

Request.Querystring自动url解码一个字符串?

http://forums.asp.net/t/1354726.aspx?Request+Querystring+without+decoding+possible+