C# 加密异常-错误数据
我开发了一个使用加密的WinForms解决方案 我遇到的问题之一是处理空密码(例如,没有设置密码)。 显然,空字符串会导致加密异常,所以我尝试阻止加密/解密空字符串,并将其值设置为空字符串 然而,我有一个例外: 加密异常(错误数据) 以下是堆栈跟踪: 在System.Security.Cryptographics.CryptographicException.ThrowCryptographicException(Int32 hr)中 在System.Security.Cryptography.Utils.\u解密数据(SafeKeyHandle hKey,字节[]数据,Int32 ib,Int32 cb,字节[]和输出缓冲区,Int32输出偏移,填充模式填充模式,布尔fDone) 位于System.Security.Cryptography.CryptoApitTransform.TransformFinalBlock(字节[]inputBuffer,Int32 inputOffset,Int32 inputCount) 在C:\xxxx\xxxx\xxxx\xxxx\xxxx\xxxx\xxxx\xxxx\xxxx\xxxx\Cryptography.cs:第82行 下面是该类的源代码:C# 加密异常-错误数据,c#,winforms,cryptography,C#,Winforms,Cryptography,我开发了一个使用加密的WinForms解决方案 我遇到的问题之一是处理空密码(例如,没有设置密码)。 显然,空字符串会导致加密异常,所以我尝试阻止加密/解密空字符串,并将其值设置为空字符串 然而,我有一个例外: 加密异常(错误数据) 以下是堆栈跟踪: 在System.Security.Cryptographics.CryptographicException.ThrowCryptographicException(Int32 hr)中 在System.Security.Cryptography.
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(""));
}
}
}
}
}
所以问题在于解密方法。有什么线索吗
是的,我知道代码不理想。这门课不是我写的,我只是想用它。谢谢你的改进建议,我一定会整理好的 如果您真的想允许空密码,请确保使用特殊大小写null以及空字符串 所以改变
if (toEncrypt == "")
到
如果toEncrypt
为null或空,则返回null
也改变
if (cipherString == "")
到
如果“cipherString”为null或空白,则返回空字符串
注:上面来自CodesInChaos的评论非常正确。这个代码有某种味道。他给出了很好的建议。如果
toEncrypt
为空怎么办?Decrypt返回一个字符串。如果cipherString==”
那么为什么不直接return“”代码>?旁白:为什么要使用ECB?如果这是一个新的实现,至少使用CBC。你所有的代码都很奇怪。表示散列与加密(为什么这么做?这是完全不同的操作)、ECB(弱)、3DES(比AES慢且弱)、缺少身份验证(hello padding oracle)、缺少IV、通过UTF8发送的密钥,。。。所有这些都是错误的选择。@rossum是的,我最初是这样做的。这个问题没有得到解决,所以我认为这可能是编码的问题。就我所知,.NET默认使用UTF-16,并且在编码中提供UTF8和Base64字符串。不知道可以传递null值。那是我的错,我应该试着用空字符串代替。是的System.String
是一种引用类型,因此可以为null,这不同于空(“”
)是的,我知道“”和null String之间的区别。尽管传递null字符串会引发NullReferenceException。显然,它已经被处理了=)
if (cipherString == "")
if (string.IsNullOrWhiteSpace(cipherString))