c# - 3DES 无法对同一密文的多次迭代产生一致的解密

标签 c# encryption 3des tripledes

我在代码中实现了 3DES (TripleDES) 解密例程,并注意到当提供的密文与前一次迭代相同时,它永远不会生成相同的明文。这似乎是不确定的,我确信这是我做错的事情。

我尝试过 CBC(带有清零 IV)、ECB、处置和清算的多种组合。我似乎无法获得一致的输出。

(由于某种原因,下面的“代码”和“输出”上的代码格式不正确,抱歉)

代码

using System;
using System.Security.Cryptography;
using System.Threading;

namespace Test
{
    class Program
    {
        static void Main(string[] args)
        {
            while (true)
            {
                string key = "27F66D5244FF621EAA6F6120EDEB427F";
                string cipher = "C25C1D1197D31CAA87285D59A892047426D9182EC11353C051ADD6D0F072A6CB3436560B3071FC1FD11D9F7E74886742D9BEE0CFD1EA1064C213BB55278B2F12";

                Console.WriteLine("clear: " + byte_array_to_hex_string(
                    decrypt_3des(
                        hex_string_to_byte_array(cipher),
                        hex_string_to_byte_array(key)
                    ), true, true
                    ));

                Console.WriteLine("");
                Thread.Sleep(1000);
            }
        }

        static byte[] decrypt_3des(byte[] cipher, byte[] key)
        {
            if (cipher == null) return null;
            if (key == null) return null;
            int num_chunks = (cipher.Length) / 8;

            Console.WriteLine("Entering decrypt_3des");
            Console.WriteLine(" - cipher: " + byte_array_to_hex_string(cipher, true, true));
            Console.WriteLine(" - key: " + byte_array_to_hex_string(key, true, true));
            Console.WriteLine(" - cipher length: " + cipher.Length);
            Console.WriteLine(" - key length: " + key.Length);

            if ((cipher.Length % 8) != 0)
            {
                Console.WriteLine("cipher length not divisble by eight");
                return null;
            }

            if ((key.Length % 8) != 0)
            {
                Console.WriteLine("key length not divisible by eight");
                return null;
            }

            TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
            tdes.Key = key;
            tdes.Mode = CipherMode.ECB;
            tdes.IV = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
            tdes.Padding = PaddingMode.Zeros;
            tdes.KeySize = (key.Length * 8);
            ICryptoTransform ct = tdes.CreateDecryptor();

            Console.WriteLine(" - IV: " + byte_array_to_hex_string(tdes.IV, true, true));
            byte[] clear = new byte[(cipher.Length)];
            clear = ct.TransformFinalBlock(cipher, 0, cipher.Length);

            Console.WriteLine(" - clear: " + byte_array_to_hex_string(clear, true, true));
            tdes.Clear();
            tdes.Dispose();
            ct.Dispose();
            return clear;
        }

        public static byte[] hex_string_to_byte_array(string hex)
        {
            int number_chars = hex.Length;
            byte[] bytes = new byte[number_chars / 2];
            for (int i = 0; i < number_chars; i += 2)
            {
                bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
            }
            return bytes;
        }

        public static string byte_array_to_hex_string(byte[] ba, bool remove_dashes, bool include_spaces)
        {
            string hex = BitConverter.ToString(ba);
            string hex_dashes = "";
            string hex_spaces = "";

            if (remove_dashes)
            {
                hex_dashes = hex.Replace("-", "");
            }
            else
            {
                return hex;
            }

            int hex_char_count = 0;
            if (include_spaces)
            {
                for (int i = (hex_dashes.Length - 1); i >= 0; i--)
                {
                    if (hex_char_count == 0)
                    {
                        hex_spaces += hex_dashes[i];
                        hex_char_count++;
                        continue;
                    }

                    if (hex_char_count % 16 == 0)
                    {
                        hex_spaces = (hex_dashes[i] + " " + hex_spaces);
                        hex_char_count++;
                        continue;
                    }

                    hex_spaces = hex_dashes[i] + hex_spaces;
                    hex_char_count++;
                }

                return hex_spaces;
            }
            else
            {
                return hex_dashes;
            }
        }
    }
}

输出

Entering decrypt_3des
 - cipher: C25C1D1197D31CAA 87285D59A8920474 26D9182EC11353C0 51ADD6D0F072A6CB 3436560B3071FC1F D11D9F7E74886742 D9BEE0C
FD1EA1064 C213BB55278B2F12
 - key: 27F66D5244FF621E AA6F6120EDEB427F
 - cipher length: 64
 - key length: 16
 - IV: 10F99E2232BEC7F4
 - clear: BF3CBF923E6C0E19 DBBB64E0FCBBFBB9 4CA3D68F117BE51F 0C1294CEC85470B6 6A799CC5D914F427 30D0C47BC9E6340C BD8E4C2E
6E5819ED 23125066DBA83477
clear: BF3CBF923E6C0E19 DBBB64E0FCBBFBB9 4CA3D68F117BE51F 0C1294CEC85470B6 6A799CC5D914F427 30D0C47BC9E6340C BD8E4C2E6E5
819ED 23125066DBA83477

Entering decrypt_3des
 - cipher: C25C1D1197D31CAA 87285D59A8920474 26D9182EC11353C0 51ADD6D0F072A6CB 3436560B3071FC1F D11D9F7E74886742 D9BEE0C
FD1EA1064 C213BB55278B2F12
 - key: 27F66D5244FF621E AA6F6120EDEB427F
 - cipher length: 64
 - key length: 16
 - IV: 32B9C802333CFBB4
 - clear: A878F23C3AF5E724 2ACB3458F8D68E68 9BE4F6C007F24FD2 9AF4CE98239A4F2C 5710633D88266AFD 77EF88A7B09485D9 F07C33D7
08832E90 77382A7A51A532C1
clear: A878F23C3AF5E724 2ACB3458F8D68E68 9BE4F6C007F24FD2 9AF4CE98239A4F2C 5710633D88266AFD 77EF88A7B09485D9 F07C33D7088
32E90 77382A7A51A532C1

Entering decrypt_3des
 - cipher: C25C1D1197D31CAA 87285D59A8920474 26D9182EC11353C0 51ADD6D0F072A6CB 3436560B3071FC1F D11D9F7E74886742 D9BEE0C
FD1EA1064 C213BB55278B2F12
 - key: 27F66D5244FF621E AA6F6120EDEB427F
 - cipher length: 64
 - key length: 16
 - IV: 2FCB1A9F5B502E1B
 - clear: 80B7302520ACA111 223BF99421EFDA2C 60CABCB3C632A61C 3422552A07B582B7 E50E44E38DEDC300 DD9A6EB5CF3C0A63 E512FAC0
C04D3EC5 EEC551C3E845BF80
clear: 80B7302520ACA111 223BF99421EFDA2C 60CABCB3C632A61C 3422552A07B582B7 E50E44E38DEDC300 DD9A6EB5CF3C0A63 E512FAC0C04
D3EC5 EEC551C3E845BF80

Entering decrypt_3des
 - cipher: C25C1D1197D31CAA 87285D59A8920474 26D9182EC11353C0 51ADD6D0F072A6CB 3436560B3071FC1F D11D9F7E74886742 D9BEE0C
FD1EA1064 C213BB55278B2F12
 - key: 27F66D5244FF621E AA6F6120EDEB427F
 - cipher length: 64
 - key length: 16
 - IV: 355096FE3CA1E9A1
 - clear: E4EDCDC436745A51 42FE9D0C71933080 6DFCAACE07FBCC22 0F5C9AF9082C8264 870362982FF90CA4 665E312FC1A8D264 DDBB27B7
3B30840E 6030D791CD849A3D
clear: E4EDCDC436745A51 42FE9D0C71933080 6DFCAACE07FBCC22 0F5C9AF9082C8264 870362982FF90CA4 665E312FC1A8D264 DDBB27B73B3
0840E 6030D791CD849A3D

最佳答案

设置 key 大小会导致创建新的随 secret 钥。如果您在设置 key 和 IV 之前执行此操作,您将获得一致的结果。

关于c# - 3DES 无法对同一密文的多次迭代产生一致的解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13315301/

相关文章:

java - 使用 Java 中的双倍长度 3DES key 进行加密并生成 16 字节数组密码

java - 如何在java中使用3DES加密/解密文本字符串?

c# - java注释与C#属性相同吗? C++ 中的等价物是什么?

c# - 无法在 .zip 中导出模板 visual Studio 2010

Node.js 中 Java 的 RSA/ECB/OAEPWithSHA-256AndMGF1Padding 等效项

java - RSA 和 Base64 编码字节过多

c# - 替换是/否/取消 MessageBox (C#)

c# - Azure Active Directory 导致注销时出现 CORS 错误

c# - LINQ to Entities 无法识别方法 'System.String Decrypt(System.String, System.String)' 方法

java - ISO 9797填充方法2和java中的MAC生成