1

暗号化を使用するWinFormsソリューションを開発しています。

私が抱えている問題の1つは、空のパスワードを処理することです(たとえば、パスワードが設定されていません)。明らかに、空の文字列は暗号化例外を引き起こすので、文字列が空の場合は暗号化/復号化を防ぎ、その値を空の文字列に設定しようとしました。

ただし、例外が発生します:CryptoGraphic Exception(Bad Data)。

スタックトレースは次のとおりです。

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.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:line 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メソッドにあります。手がかりはありますか?

PSはい、私はコードが理想的ではないことを知っています。このクラスは私が書いたものではなく、ただ使用しようとしているだけです。改善の提案をありがとう、私は間違いなくそれらを考慮します。

4

1 に答える 1

2

本当に空のパスワードを許可したい場合は、空の文字列だけでなく、特殊な大文字小文字の区別も忘れないでください。

だから変更

if (toEncrypt == "")

if (string.IsNullOrEmpty(toEncrypt))

toEncryptnullまたは空の場合はnullを返します。

また、変更します

if (cipherString == "")

if (string.IsNullOrWhiteSpace(cipherString))

'cipherString'がnullまたは空白の場合は、空の文字列を返します。

注意-上記のCodesInChaosからのコメントは非常に正しいです。このコードには、ある種の匂いがあります。彼は良いアドバイスをします。

于 2012-11-12T12:32:04.220 に答える