4

C# には、2 つの静的関数で構成されるトリプル DES ラッパーがEncryptありDecryptます。場合によっては、「Bad data」というエラーをスローしてDecrypt失敗します。TransformFinalBlock(..., ...)

  • なぜこうなった?
  • 解決策は何ですか?

前もって感謝します。

public static string Encrypt(string toencrypt, string key, bool usehashing = true)
{
    byte[] keyArray;
    byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toencrypt);
    byte[] resultArray;

    //If hashing use get hashcode regards to your key
    if (usehashing)
    {
        MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
        keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));

        //Always release the resources and flush data
        // of the Cryptographic service provide. Best Practice
        hashmd5.Clear();
    }
    else
        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.CreateEncryptor();

    try
    {
        //transform the specified region of bytes array to resultArray
        resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
    }
    catch (System.Exception ex)
    {
        //Release resources held by TripleDes Encryptor
        tdes.Clear();
        return "";
    }

    //Release resources held by TripleDes Encryptor
    tdes.Clear();

    //Return the encrypted data into unreadable string format
    return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}

public static string Decrypt(string todecrypt, string key, bool usehashing = true)
{
    byte[] keyArray;
    byte[] toEncryptArray;
    byte[] resultArray;
    //get the byte code of the string

    try
    {
        toEncryptArray = Convert.FromBase64String(todecrypt.Replace(" ", "+"));//The replace happens only when spaces exist in the string (hence not a Base64 string in the first place).
    }
    catch (System.Exception ex)
    {
        return "";
    }

    if (usehashing)
    {
        //if hashing was used get the hash code with regards to your key
        MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
        keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));

        //release any resource held by the MD5CryptoServiceProvider
        hashmd5.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();

    try
    {
        resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
    }
    catch (System.Exception ex)
    {
        //Release resources held by TripleDes Encryptor                
        tdes.Clear();
        return "";
    }

    //Release resources held by TripleDes Encryptor                
    tdes.Clear();

    //return the Clear decrypted TEXT
    return UTF8Encoding.UTF8.GetString(resultArray);
}

Decrypt暗号化すると失敗する文字列の例は次のとおりです。

AgAAAA* AQAAAA *aAAAAAA* jfgGTw *nY+shZ2PrBmdj6wVnY+sEZ2PrA2dj6wFk4GhCJOHoQqdj6x9nY+seQ*トリバア*AAMAAA**+L7PHiJ76M8OTV4BjXCkuDgDG2u7AcW87p1KU7KTSCKI3fYTnYAcGk1gyS62AvZO4g1FrsVbzoAnsX9Y0Ju+V9YjaYr9+Xr+pen4SEas0NjRvntv0gqU0QZOj9bjKXx1Izc9Dw1HCUqjUGBcwakQo6kBlvb2v2/pV9dM4B3RM6m7rmaW79CSc7CC3DQjnqA5HMHC5k65pOK0KT76MzTawYQotNOk0BabTO3HpVcI8BNNjSsIP7TvtxXBmbc6TfXahw1zLTvC4iTSPnsgz0jhxvHhHD+N0cblfQhAK/nt2IZQuWGL3jW0oPpPJnjhGMWQPDLXbNwp23WUv8GXIPKevXbushYKjutmsdqJT7C1mcB45XhbYCVUVbLIja1AV831YeHqqke2msSaisg37UM+urL9EFIueUHZgZryhQUSjAhZDiHXqosoQou92RqbTK5YTqYY+zyBBzRt2r7KS3v5u9smtWMNk8Xcn42a6pFFxd6g4u0/s/SVm7NFb2UbREvp75lBVxEQv5IIznPSHfDnLtuX8pLfrZ/AVQ+gM9AGvzBjHGNYDQJ6VhgkHOZMeuLISJXjfGX0ZPFYKd+CPObpbFlukOSlIB5epRDnuggTLnthpN06Kle+iDqz1Q96ty4mfzwuhRwxvQ7EMzTykHXxC8p9bLKMr86K/vart2D9w1g9RtyS+pekgW8lkutWWGdu1eZml/5abNmlW5VgSJiuA9Yyrd2UNjUl6/a0oMKHPk6b2gZkpmENpO7auC9HA2gO

ただし、ほとんどの文字列では失敗しません。これは、私が推測している特殊文字と関係があるに違いありません。

4

1 に答える 1

1

まず、最初の暗号化されていないキーと、失敗した暗号化ブロックを生成する文字列を提供してください。そうすることで、問題が発生した理由を解明できる可能性が高くなります。ただし、それが要求されているため、コードにいくつかの潜在的な落とし穴が見られます。主に、実装する型を破棄しないことに関連していますIDisposable。これを考慮したコードの小さなリファクタリングを次に示します (他のいくつかの小さな調整の中でも)。

    public static string Encrypt(string toencrypt, string key, bool usehashing = true)
    {
        byte[] keyArray;

        // If hashing use get hash code regards to your key
        if (usehashing)
        {
            using (var hashmd5 = new MD5CryptoServiceProvider())
            {
                keyArray = hashmd5.ComputeHash(Encoding.UTF8.GetBytes(key));
            }
        }
        else
        {
            keyArray = Encoding.UTF8.GetBytes(key);
        }

        // set the secret key for the tripleDES algorithm
        // mode of operation. there are other 4 modes.
        // We choose ECB(Electronic code Book)
        // padding mode(if any extra byte added)
        using (var tdes = new TripleDESCryptoServiceProvider
        {
            Key = keyArray,
            Mode = CipherMode.ECB,
            Padding = PaddingMode.PKCS7
        })
        using (var transform = tdes.CreateEncryptor())
        {
            try
            {
                var toEncryptArray = Encoding.UTF8.GetBytes(toencrypt);

                // transform the specified region of bytes array to resultArray
                var resultArray = transform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

                // Return the encrypted data into unreadable string format
                return Convert.ToBase64String(resultArray, 0, resultArray.Length);
            }
            catch (Exception)
            {
                return string.Empty;
            }
        }
    }

    public static string Decrypt(string todecrypt, string key, bool usehashing = true)
    {
        byte[] toEncryptArray;

        // get the byte code of the string
        try
        {
            toEncryptArray = Convert.FromBase64String(todecrypt.Replace(" ", "+")); // The replace happens only when spaces exist in the string (hence not a Base64 string in the first place).
        }
        catch (Exception)
        {
            return string.Empty;
        }

        byte[] keyArray;

        if (usehashing)
        {
            // if hashing was used get the hash code with regards to your key
            using (var hashmd5 = new MD5CryptoServiceProvider())
            {
                keyArray = hashmd5.ComputeHash(Encoding.UTF8.GetBytes(key));
            }
        }
        else
        {
            // if hashing was not implemented get the byte code of the key
            keyArray = Encoding.UTF8.GetBytes(key);
        }

        // set the secret key for the tripleDES algorithm
        // mode of operation. there are other 4 modes. 
        // We choose ECB(Electronic code Book)
        // padding mode(if any extra byte added)
        using (var tdes = new TripleDESCryptoServiceProvider
        {
            Key = keyArray,
            Mode = CipherMode.ECB,
            Padding = PaddingMode.PKCS7
        })
        using (var transform = tdes.CreateDecryptor())
        {
            try
            {
                var resultArray = transform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

                // return the Clear decrypted TEXT
                return Encoding.UTF8.GetString(resultArray);
            }
            catch (Exception)
            {
                return string.Empty;
            }
        }
    }
于 2012-07-27T14:59:59.760 に答える