我开发了一个使用加密的WinForms解决方案。
我遇到的一个问题是处理空密码(例如没有设置密码)。 显然,空字符串会导致加密异常,所以我试图阻止加密/解密字符串(如果它为空)并将其值设置为空字符串。
然而,我得到例外: CryptoGraphic Exception(错误数据)。
这是堆栈跟踪:
at 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) at xxx.Security.Cryptography.Decrypt(String cipherString,Boolean useHashing)in 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(""));
}
}
}
}
}
所以问题在于Decrypt方法。有什么线索吗?
P.S。是的,我知道代码并不理想。这堂课不是我写的,我只是想用它。谢谢你的改进建议,我一定会让他们满意。
答案 0 :(得分:2)
如果你真的想要允许空密码,请确保你的特殊情况为null以及空字符串。
所以改变
if (toEncrypt == "")
到
if (string.IsNullOrEmpty(toEncrypt))
如果toEncrypt
为空或空,则返回null。
同时更改
if (cipherString == "")
到
if (string.IsNullOrWhiteSpace(cipherString))
如果'cipherString'为null或空格,则返回空字符串。
NB - 上面的CodesInChaos的评论非常正确。这段代码有一定的气味。他给出了很好的建议。