如何在 OFB 模式下在 C# 中使用 3DES 解密?

发布于 2024-10-15 20:17:03 字数 4528 浏览 0 评论 0原文

我昨晚发布了同样的问题,但我给出了一个非常糟糕的代码示例。希望这会让大家更容易理解我的情况。

我需要解密在 OFB 模式下使用 3DES 使用空填充加密的消息。

这是我尝试使用从网上获取的代码进行解密。

加密的消息、密钥和 IV 均被验证正确。

它会产生以下错误:

发生加密错误:指定的密钥不是该算法的有效大小。

假设代码的其他所有内容都很好,我如何更改密码模式,使其为 null 的 OFB填充?

使用系统; 使用 System.Collections.Generic; 使用系统文本;

命名空间_DESapp { 使用系统; 使用系统.安全.密码学; 使用系统文本; 使用系统.IO;

class TrippleDESCSPSample
{

    static void Main()
    {
        try
        {
            int discarded;
            byte[] encrypteddata = Convert.FromBase64String( "zbv67qbzN6pD2Uaog62u8WgZOcOz");
            byte[] key = Convert.FromBase64String( "wSQ90YI+lAauwVVSySAi8u0P");
            byte[] IV = HexEncoding.GetBytes("ac3834bfbda8eb07", out discarded);

            string decrypteddata = DecryptTextFromMemory( encrypteddata, key, IV);

            Console.ReadLine();

        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }

    }

    public static string DecryptTextFromMemory(byte[] Data, byte[] Key, byte[] IV)
    {
        try
        {
            // Create a new MemoryStream using the passed 
            // array of encrypted data.
            MemoryStream msDecrypt = new MemoryStream(Data);

            // Create a CryptoStream using the MemoryStream 
            // and the passed key and initialization vector (IV).

            ICryptoTransform des = new TripleDESCryptoServiceProvider().CreateDecryptor(Key, IV);

            CryptoStream csDecrypt = new CryptoStream(msDecrypt, des, CryptoStreamMode.Read);
            //CryptoStream csDecrypt = new CryptoStream(msDecrypt,
            //    new TripleDESCryptoServiceProvider().CreateDecryptor(Key, IV),
            //    CryptoStreamMode.Read);

            // Create buffer to hold the decrypted data.
            byte[] fromEncrypt = new byte[Data.Length];

            // Read the decrypted data out of the crypto stream
            // and place it into the temporary buffer.
            csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);

            //Convert the buffer into a string and return it.
            return new ASCIIEncoding().GetString(fromEncrypt);
        }
        catch (CryptographicException e)
        {
            Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
            return null;
        }
    }


    public class HexEncoding
    {
        public HexEncoding()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        public static byte[] GetBytes(string hexString, out int discarded)
        {
            discarded = 0;
            string newString = "";
            char c;
            // remove all none A-F, 0-9, characters
            for (int i = 0; i < hexString.Length; i++)
            {
                c = hexString[i];
                if (IsHexDigit(c))
                    newString += c;
                else
                    discarded++;
            }
            // if odd number of characters, discard last character
            if (newString.Length % 2 != 0)
            {
                discarded++;
                newString = newString.Substring(0, newString.Length - 1);
            }

            int byteLength = newString.Length / 2;
            byte[] bytes = new byte[byteLength];
            string hex;
            int j = 0;
            for (int i = 0; i < bytes.Length; i++)
            {
                hex = new String(new Char[] { newString[j], newString[j + 1] });
                bytes[i] = HexToByte(hex);
                j = j + 2;
            }
            return bytes;
        }

        public static bool IsHexDigit(Char c)
        {
            int numChar;
            int numA = Convert.ToInt32('A');
            int num1 = Convert.ToInt32('0');
            c = Char.ToUpper(c);
            numChar = Convert.ToInt32(c);
            if (numChar >= numA && numChar < (numA + 6))
                return true;
            if (numChar >= num1 && numChar < (num1 + 10))
                return true;
            return false;
        }

        private static byte HexToByte(string hex)
        {
            if (hex.Length > 2 || hex.Length <= 0)
                throw new ArgumentException("hex must be 1 or 2 characters in length");
            byte newByte = byte.Parse(hex, System.Globalization.NumberStyles.HexNumber);
            return newByte;
        }

    }

}

}

I posted this same question last night but I gave a very poor example of code. Hopefully this will make it easier to understand my situation.

I need to decrypt messages that have been encrypted using 3DES in OFB mode with null padding.

Here's my attempt to do the decryption using code I grabbed from the web.

The encrypted message, key and IV are all verified as correct.

It produces the following error:

A Cryptographic error occurred: Specified key is not a valid size for this algorithm.

Assuming all else is well with the code, how do I change the cipher mode so it's OFB with null padding?

using System;
using System.Collections.Generic;
using System.Text;

namespace _DESapp
{
using System;
using System.Security.Cryptography;
using System.Text;
using System.IO;

class TrippleDESCSPSample
{

    static void Main()
    {
        try
        {
            int discarded;
            byte[] encrypteddata = Convert.FromBase64String( "zbv67qbzN6pD2Uaog62u8WgZOcOz");
            byte[] key = Convert.FromBase64String( "wSQ90YI+lAauwVVSySAi8u0P");
            byte[] IV = HexEncoding.GetBytes("ac3834bfbda8eb07", out discarded);

            string decrypteddata = DecryptTextFromMemory( encrypteddata, key, IV);

            Console.ReadLine();

        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }

    }

    public static string DecryptTextFromMemory(byte[] Data, byte[] Key, byte[] IV)
    {
        try
        {
            // Create a new MemoryStream using the passed 
            // array of encrypted data.
            MemoryStream msDecrypt = new MemoryStream(Data);

            // Create a CryptoStream using the MemoryStream 
            // and the passed key and initialization vector (IV).

            ICryptoTransform des = new TripleDESCryptoServiceProvider().CreateDecryptor(Key, IV);

            CryptoStream csDecrypt = new CryptoStream(msDecrypt, des, CryptoStreamMode.Read);
            //CryptoStream csDecrypt = new CryptoStream(msDecrypt,
            //    new TripleDESCryptoServiceProvider().CreateDecryptor(Key, IV),
            //    CryptoStreamMode.Read);

            // Create buffer to hold the decrypted data.
            byte[] fromEncrypt = new byte[Data.Length];

            // Read the decrypted data out of the crypto stream
            // and place it into the temporary buffer.
            csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);

            //Convert the buffer into a string and return it.
            return new ASCIIEncoding().GetString(fromEncrypt);
        }
        catch (CryptographicException e)
        {
            Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
            return null;
        }
    }


    public class HexEncoding
    {
        public HexEncoding()
        {
            //
            // TODO: Add constructor logic here
            //
        }

        public static byte[] GetBytes(string hexString, out int discarded)
        {
            discarded = 0;
            string newString = "";
            char c;
            // remove all none A-F, 0-9, characters
            for (int i = 0; i < hexString.Length; i++)
            {
                c = hexString[i];
                if (IsHexDigit(c))
                    newString += c;
                else
                    discarded++;
            }
            // if odd number of characters, discard last character
            if (newString.Length % 2 != 0)
            {
                discarded++;
                newString = newString.Substring(0, newString.Length - 1);
            }

            int byteLength = newString.Length / 2;
            byte[] bytes = new byte[byteLength];
            string hex;
            int j = 0;
            for (int i = 0; i < bytes.Length; i++)
            {
                hex = new String(new Char[] { newString[j], newString[j + 1] });
                bytes[i] = HexToByte(hex);
                j = j + 2;
            }
            return bytes;
        }

        public static bool IsHexDigit(Char c)
        {
            int numChar;
            int numA = Convert.ToInt32('A');
            int num1 = Convert.ToInt32('0');
            c = Char.ToUpper(c);
            numChar = Convert.ToInt32(c);
            if (numChar >= numA && numChar < (numA + 6))
                return true;
            if (numChar >= num1 && numChar < (num1 + 10))
                return true;
            return false;
        }

        private static byte HexToByte(string hex)
        {
            if (hex.Length > 2 || hex.Length <= 0)
                throw new ArgumentException("hex must be 1 or 2 characters in length");
            byte newByte = byte.Parse(hex, System.Globalization.NumberStyles.HexNumber);
            return newByte;
        }

    }

}

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文