我开发了一个使用加密的 WinForms 解决方案。
我遇到的问题之一是处理空密码(例如没有设置密码)。显然,空字符串会导致加密异常,所以我试图阻止加密/解密字符串,如果它是空的,并将它的值设置为空字符串。
但是,我得到了异常: CryptoGraphic Exception (Bad Data)。
这是堆栈跟踪:
在 System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr) 在 System.Security.Cryptography.Utils._DecryptData(SafeKeyHandle hKey, Byte[] data, Int32 ib, Int32 cb, Byte[]& outputBuffer, Int32 outputOffset, PaddingMode PaddingMode , Boolean fDone) 在 System.Security.Cryptography.CryptoAPITransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount) 在 xxx.Security.Cryptography.Decrypt(String cipherString, Boolean useHashing) 在 C:\xxxx\xxxx\xxxx \xxxx\xxxx\xxxx\Cryptography.cs:第 82 行
这是该类的源代码:
using System;
using System.Security.Cryptography;
using System.Text;
namespace xxx
{
public class Cryptography
{
private const string key = "xxxx";
public static string Encrypt(string toEncrypt, bool useHashing)
{
if (toEncrypt == "")
{
string result = System.Convert.ToBase64String(Encoding.UTF8.GetBytes(toEncrypt));
return result;
}
else
{
try
{
byte[] keyArray;
byte[] toEncryptArray = Encoding.UTF8.GetBytes(toEncrypt);
//If hashing use get hashcode regards to your key
if (useHashing)
{
MD5CryptoServiceProvider md5CryptoServiceProvider = new MD5CryptoServiceProvider();
keyArray = md5CryptoServiceProvider.ComputeHash(Encoding.UTF8.GetBytes(key));
md5CryptoServiceProvider.Clear();
}
else
keyArray = Encoding.UTF8.GetBytes(key);
TripleDESCryptoServiceProvider tripleDesCryptoServiceProvider = new TripleDESCryptoServiceProvider();
//set the secret key for the tripleDES algorithm
tripleDesCryptoServiceProvider.Key = keyArray;
//mode of operation. there are other 4 modes.
//We choose ECB(Electronic code Book)
tripleDesCryptoServiceProvider.Mode = CipherMode.ECB;
//padding mode(if any extra byte added)
tripleDesCryptoServiceProvider.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = tripleDesCryptoServiceProvider.CreateEncryptor();
//transform the specified region of bytes array to resultArray
byte[] resultArray =
cTransform.TransformFinalBlock(toEncryptArray, 0,
toEncryptArray.Length);
//Release resources held by TripleDes Encryptor
tripleDesCryptoServiceProvider.Clear();
//Return the encrypted data into unreadable string format
return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
catch (Exception)
{
string result = System.Convert.ToBase64String(Encoding.UTF8.GetBytes(toEncrypt));
return result;
}
}
}
public static string Decrypt(string cipherString, bool useHashing)
{
if (cipherString == "")
{
UTF8Encoding utf8 = new UTF8Encoding();
return Encoding.UTF8.GetString(utf8.GetBytes(""));
}
else
{
try
{
byte[] keyArray;
//get the byte code of the string
byte[] toEncryptArray = Convert.FromBase64String(cipherString);
if (useHashing)
{
//if hashing was used get the hash code with regards to your key
MD5CryptoServiceProvider md5CryptoServiceProvider = new MD5CryptoServiceProvider();
keyArray = md5CryptoServiceProvider.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
//release any resource held by the MD5CryptoServiceProvider
md5CryptoServiceProvider.Clear();
}
else
{
//if hashing was not implemented get the byte code of the key
keyArray = UTF8Encoding.UTF8.GetBytes(key);
}
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
//set the secret key for the tripleDES algorithm
tdes.Key = keyArray;
//mode of operation. there are other 4 modes.
//We choose ECB(Electronic code Book)
tdes.Mode = CipherMode.ECB;
//padding mode(if any extra byte added)
tdes.Padding = PaddingMode.PKCS7;
ICryptoTransform cTransform = tdes.CreateDecryptor();
byte[] resultArray = cTransform.TransformFinalBlock(
toEncryptArray, 0, toEncryptArray.Length);
//Release resources held by TripleDes Encryptor
tdes.Clear();
//return the Clear decrypted TEXT
return Encoding.UTF8.GetString(resultArray);
}
catch (Exception)
{
UTF8Encoding utf8 = new UTF8Encoding();
return Encoding.UTF8.GetString(utf8.GetBytes(""));
}
}
}
}
}
所以问题出在解密方法上。请问有什么线索吗?
PS 是的,我知道代码并不理想。这门课不是我写的,我只是想用它。感谢您提出改进建议,我一定会考虑它们。