编程语言
首页 > 编程语言> > java – 使用JCE进行3DES / DES加密 – 生成可接受的密钥

java – 使用JCE进行3DES / DES加密 – 生成可接受的密钥

作者:互联网

我正在开发一个需要Java中3DES加密的项目.问题是我已经(并将继续)提供128位十六进制密钥,如“0123456789ABCDEF0123456789ABCDEF”.转换为字节是没有问题的.然而,问题是Java Cryptographic Extensions API会阻塞此密钥,说它无效.我认为每个字节的MSB只是一个奇偶校验位,所以JCE希望我删除它们(或者我认为).但是,在.NET中,我可以指定所提供的密钥,并且它可以安静地处理加密/解密而不会抱怨.

有没有什么方法可以生成JCE期望从我提供的那种键中得到的那种键?

我发现JCE允许你为DES加密指定一个8字节的密钥,所以我尝试使用提供的密钥的一半来实现3DES作为DES EDE.但是,我仍然在使用.NET获得不一致的结果.

这是Java代码:

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.IvParameterSpec;

public class Main{
    public static void main(String[] args) throws Exception {
        byte [] plain = "I eat fish every day".getBytes("utf-8");

        byte [] keyBytes = new byte [] { (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00
            };

        byte [] key2Bytes = new byte [] { (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00,
            (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0  }; // actual keys replaced with dummies.

        SecretKey keySpec = new SecretKeySpec(keyBytes, "DES");
        SecretKey keySpec2 = new SecretKeySpec(key2Bytes, "DES");

        IvParameterSpec iv = new IvParameterSpec(new byte[8]);

        Cipher e_cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        Cipher cipher = Cipher.getInstance("DES/CBC/NoPadding");

        e_cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
        cipher.init(Cipher.DECRYPT_MODE, keySpec2, iv);

        byte [] cipherText = e_cipher.doFinal(plain);
        cipherText = cipher.doFinal(cipherText);
        cipherText = e_cipher.doFinal(cipherText);

        System.out.println("Ciphertext: " + new sun.misc.BASE64Encoder().encode(cipherText));
    }
}

这是.NET代码:

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace EncryptionDemo
{
    class Program
    {
    public static void Main(string[] args)
    {
        Console.WriteLine("Hello World!");

        // TODO: Implement Functionality Here
        var plainBytes = Encoding.UTF8.GetBytes("I eat fish every day");
        var keyBytes = new byte [] { 0x00, 0x00, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00,
         0x00,  0x00, 0x00, 0x00  };

        var tripleDES = TripleDESCryptoServiceProvider.Create();
        var transform = tripleDES.CreateEncryptor(keyBytes, new byte [8]);

        var memStream = new MemoryStream();
        var cStream = new CryptoStream(memStream, transform, CryptoStreamMode.Write);

        cStream.Write(plainBytes, 0, plainBytes.Length);
        cStream.FlushFinalBlock();

        //memStream.Position = 0;
        var cipherBytes = memStream.ToArray();

        Console.WriteLine("Ciphertext: " + Convert.ToBase64String(cipherBytes));

        Console.Write("Press any key to continue . . . ");
        Console.ReadKey(true);
    }
}

两者都产生不同的输出(Base64字符串中的某些字符是相同的)

解决方法:

3DES键长192位.

你是如何创建SecretKey实例的?你得到什么错误信息?

你问题中的Java代码是使用DES,而不是“Triple DES”.算法名称应为“DESede / CBC / PKCS5Padding”.您的答案中的代码可能有效,因为您的算法正确,而不是因为您切换了提供程序. Java 6中的SunJCE提供程序将接受128位密钥(并使用密钥选项2).我不确定旧版本.

标签:jce,java,net
来源: https://codeday.me/bug/20190827/1738171.html