猿问

TripleDES加密在java中工作正常,但在c中不起作用#

我在进行三重DES加密时面临弱密钥错误。代码在java中工作正常,但在C# .net中给出错误。


我有Java代码,其中TripleDES ecryption工作正常,我需要在c#中转换我的Java代码。我在转换过程中面临弱键错误。下面给出了java和c#代码。


1) Java 代码


public class TripleDES {

    private DESedeKeySpec desKeySpec;


    public TripleDES(String key) {

        try {

            byte[] keyBytes = { (byte) 0x02, (byte) 0x02, (byte) 0x02, (byte) 0x02,

                    (byte) 0x02, (byte) 0x02, (byte) 0x02, (byte) 0x02,

                    (byte) 0x02, (byte) 0x02, (byte) 0x02, (byte) 0x02,

                    (byte) 0x02, (byte) 0x02, (byte) 0x02, (byte) 0x02,

                    (byte) 0x02, (byte) 0x02, (byte) 0x02, (byte) 0x02,

                    (byte) 0x02, (byte) 0x02, (byte) 0x02, (byte) 0x02};




            this.desKeySpec = new DESedeKeySpec(keyBytes);


        } catch (Exception e) {

            e.printStackTrace();

        }

    }


    public byte[] encrypt(byte[] origData) {

        try {

            SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede");

            SecretKey key = factory.generateSecret(this.desKeySpec);

            Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding");

            cipher.init(Cipher.ENCRYPT_MODE, key);

            return cipher.doFinal(origData);

        }  catch (Exception e) {

            e.printStackTrace();

        }

        return null;

    }


    public byte[] decrypt(byte[] crypted) {

        try {

            SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede");

            SecretKey key = factory.generateSecret(this.desKeySpec);

            Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding");  //DESede/CBC/PKCS5Padding

            cipher.init(Cipher.DECRYPT_MODE, key);

            return cipher.doFinal(crypted);

        }  catch (Exception e) {

            e.printStackTrace();

        }

        return null;

    }

}


密钥:02020202020202020202020202020202


数据 : 041205FFFBA666CF


结果 : A334C92CEC163D9F


任何人都可以用c#编写代码,产生与java相同的结果。


蝴蝶不菲
浏览 122回答 2
2回答

牧羊人nacy

在我开始之前,我想说的是,我不建议或认可您遵循这种方式来强制TripleDES使用它认为较弱的密钥,但是,鉴于您仅将其用于解密,这里有一种使用反射的方法。首先,您必须“强制”类获取要使用的弱键。为此,我们使用反射来绕过对弱键的检查,当您尝试设置键 () 并直接设置成员变量时,将执行该检查:TripeDESalg.Key = key//alg.Key = key; - THIS IS REPLACED BY THE BELOWFieldInfo keyField = alg.GetType().GetField("KeyValue", BindingFlags.NonPublic | BindingFlags.Instance);keyField.SetValue(alg, key);现在的键值将设置为弱键 (TripleDESalg.Key);接下来,您有一个小错误,因为您忘记关闭填充:alg.Mode = CipherMode.ECB;alg.Padding = PaddingMode.None; // Add this, as the default padding is PKCS7最后,在创建解密器时,将进一步检查弱密钥,因此我们必须再次使用反射来绕过检查并创建ICryptoTransform:// Comment out the below line and use the code below// CryptoStream cs = new CryptoStream(ms, alg.CreateDecryptor(), CryptoStreamMode.Write);ICryptoTransform Decryptor;MethodInfo createMethod = alg.GetType().GetMethod("_NewEncryptor", BindingFlags.NonPublic | BindingFlags.Instance);Decryptor = createMethod.Invoke(alg, new object[] { alg.Key, alg.Mode, alg.IV, alg.FeedbackSize, 1 }) as ICryptoTransform;CryptoStream cs = new CryptoStream(ms, Decryptor, CryptoStreamMode.Write);代码现在将运行并接受弱密钥,并执行您要查找的解密。但是,在我看来,输出并不是您所期望的:?Data"4aU3DcHkiCTEywpiewWIow=="至少现在,尽管您可以对 .TripleDES

米琪卡哇伊

3DES 键是一个 24 字节值,它分为两个三个 8 字节值:、 、 .key0key1key2因为 3DES 是 DES_Encrypt(key2, DES_Decrypt(key1, DES_Encrypt(key0, data))) 任何时间都等于或算法简化为 DES。这就是.NET的TripleDES正在警告你。key1key2key0这里正确的测试应该考虑清除(或设置或修复)每个字节中的奇偶校验位,但手挥的版本是:SymmetricAlgorithm alg;IEnumerable<byte> key0 = key.Take(8);IEnumerable<byte> key1 = key.Skip(8).Take(8);IEnumerable<byte> key2 = key.Skip(16);if (key0.SequenceEquals(key1)){&nbsp; &nbsp; alg = DES.Create();&nbsp; &nbsp; alg.Key = key2.ToArray();}else if (key1.SequenceEquals(key2)){&nbsp; &nbsp; alg = DES.Create();&nbsp; &nbsp; alg.Key = key0.ToArray();}else{&nbsp; &nbsp; alg = TripleDES.Create();&nbsp; &nbsp; alg.Key = key;}要更换两个衬垫:TripleDES alg = TripleDES.Create();alg.Key = key;
随时随地看视频慕课网APP
我要回答