首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CryptographicException -错误数据

CryptographicException -错误数据
EN

Stack Overflow用户
提问于 2012-11-12 20:29:32
回答 1查看 11.1K关注 0票数 1

我开发了一个使用加密的WinForms解决方案。

我遇到的一个问题是处理空密码(例如,没有设置密码)。显然,空字符串会导致加密异常,所以我试图阻止加密/解密字符串,如果它是空的,并将其值设置为空字符串。

然而,我得到了异常: CryptoGraphic异常(错误数据)。

下面是堆栈跟踪:

at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr) at System.Security.Cryptography.Utils._DecryptData(SafeKeyHandle hKey,Byte[] data,Int32 ib,Int32 cb,Byte[]& outputBuffer,Int32 outputOffset,PaddingMode PaddingMode,Boolean fDone) at System.Security.Cryptography.Utils._DecryptData(SafeKeyHandle inputBuffer,Int32 inputOffset,Int32 inputCount) at (字符串,Boolean ) in 82

下面是这个类的源代码:

代码语言:javascript
复制
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(""));
            }
        }
        }
    }
}

所以问题出在解密方法上。有什么线索吗?

附言:是的,我知道代码并不理想。这个类不是我写的,我只是想用它。谢谢你的改进建议,我一定会考虑的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-11-12 20:32:04

如果您确实希望允许空密码,请确保在特殊情况下使用null和空字符串。

所以改变吧

代码语言:javascript
复制
if (toEncrypt == "")

代码语言:javascript
复制
if (string.IsNullOrEmpty(toEncrypt))

如果toEncrypt为null或为空,则返回null。

也会改变

代码语言:javascript
复制
if (cipherString == "")

代码语言:javascript
复制
if (string.IsNullOrWhiteSpace(cipherString))

如果'cipherString‘为null或空格,则返回空字符串。

注意-上面来自CodesInChaos的评论是非常正确的。这段代码有一种特殊的味道。他给出了很好的建议。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13343725

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档