在Java中生成和使用两个密钥进行加密和解密 [英] Generating and using two keys for encryption and decryption in Java

查看:158
本文介绍了在Java中生成和使用两个密钥进行加密和解密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个Java应用程序,它需要我使用两个键
从不同的字符串生成的加密和解密。一个
字符串来自用户,其他是主键。我在net
上查找了几个关于它的引用。我真的想要一些
帮助知道如何实现这一点。我将显示我现在的情况。

I am working on a Java application which requires I use two keys generated from different Strings for encrypting and decrypting. One String is coming from user and other is master key. I looked on net and found a few references regarding it. I would really like some help in knowing how to implement this. I will show what I have now.

从代码中可以看到,我使用了一些来自其他stackoverflow post的代码,并修改了一点。我只是不知道如何从2个字符串生成2个密钥,从那里我可以得到用于解密的SecretKey desKey。

So as you can see from code, I used some code from other stackoverflow post and modified it a bit. I just don't know how to generate the 2 keys from 2 Strings and from where I can get the SecretKey desKey used for decryption.

代码:

public class Encryption {

public void doStuff() {

    String plaintext = "abc";

    SecretKey k1 = generateDESkey();
    SecretKey k2 = generateDESkey();


    String firstEncryption = desEncryption(plaintext, k1);
    String decryption = desDecryption(firstEncryption, k2);
    String secondEncryption = desEncryption(decryption, k1);

    System.out.println(firstEncryption);
    System.out.println(decryption);
    System.out.println(secondEncryption);
}

public static SecretKey generateDESkey() {
    KeyGenerator keyGen = null;
    try {
        keyGen = KeyGenerator.getInstance("DESede");
    } catch (NoSuchAlgorithmException ex) {
        Logger.getLogger(Test.class
                .getName()).log(Level.SEVERE, null, ex);
    }
    try {
        assert keyGen != null;
        keyGen.init(112); // key length 56
        return keyGen.generateKey();
    } catch (NullPointerException ex){
        return null;
    }
}


public static String desEncryption(String strToEncrypt, SecretKey desKey) {
    try {
        Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, desKey);
        return Base64.encode(cipher.doFinal(strToEncrypt.getBytes()));
    } catch (NoSuchAlgorithmException | NoSuchPaddingException |
            IllegalBlockSizeException | BadPaddingException |
            InvalidKeyException ex) {
        Logger.getLogger(Test.class
                .getName()).log(Level.SEVERE, null, ex);
    }
    return null;
}


public static String desDecryption(String strToDecrypt, SecretKey desKey) {
    try {
        Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, desKey);
        return new String(cipher.doFinal(Base64.decode(strToDecrypt)));

    } catch (NoSuchAlgorithmException |  BadPaddingException | IllegalBlockSizeException
            | InvalidKeyException | NoSuchPaddingException ex) {
        Logger.getLogger(Test.class
                .getName()).log(Level.SEVERE, null, ex);
    }
    return null;
}

}

如果有任何混淆或怀疑关于它。

If there is any confusion or doubts about it. Kindly let me know.

推荐答案

在更改之前回答代码。

您尝试只使用两个键而不是三个键来执行DESede。

You're trying to do DESede with only two keys instead of three.

这通常可以工作,写的。问题是填充。在第二个步骤中,您尝试使用其他密钥而不是其加密的密钥来解密密文,因此解密将在256次中失败超过255次,因为填充将是错误的(也因为您使用Base64编码是不必要的)。

That might generally work, but not as you've written. The problem is the padding. In the second step, you try to decrypt the ciphertext with an other key than with what it was encrypted, so the decryption will fail more than 255 out of 256 times, because the padding will be wrong (also because you use Base64 encoding where it is not necessary).

如果你真的想做,你将不需要填充和没有Base64编码。好的是,未编码的密文已经是块大小的倍数,所以你不必停止使用DES / ECB / NoPadding

If you really want to do it, you will have to decrypt without padding and without Base64 encoding. The good thing is that the unencoded ciphertext is already a multiple of the blocksize, so there is no stopping you to use "DES/ECB/NoPadding".

public static void main(String[] args) {
    // First I would like to create keys by giving Strings
    SecretKey k1 = generateDESkey();
    SecretKey k2 = generateDESkey();

    // encryption
    byte[] firstEncryption = desEncryption("plaintext".getBytes("UTF-8"), k1, false);
    byte[] decryption = desDecryption(firstEncryption, k2, true);
    byte[] secondEncryption = desEncryption(decryption, k1, true);

    // decryption
    byte[] firstDecryption = desDecryption(secondEncryption, k1, true);
    byte[] encryption = desEncryption(firstDecryption, k2, true);
    byte[] secondDecryption = desDecryption(encryption, k1, false);

    System.out.println(new String(secondDecryption)); // plaintext
}

public static byte[] desEncryption(byte[] strToEncrypt, SecretKey desKey, boolean noPadding) {
    try {
        Cipher cipher = Cipher.getInstance(noPadding ? "DES/ECB/NoPadding" : "DES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, desKey);
        return cipher.doFinal(strToEncrypt);
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    return null;
}

public static byte[] desDecryption(byte[] strToDecrypt, SecretKey desKey, boolean noPadding) {
    try {
        Cipher cipher = Cipher.getInstance(noPadding ? "DES/ECB/NoPadding" : "DES/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, desKey);
        return cipher.doFinal(strToDecrypt);
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    return null;
}

这实际上是一个等价的DESede实现,构造如下:

This is actually an equivalent implementation of DESede with two keys when the general key is constructed in this way:

SecretKey k1 = generateDESkey();
SecretKey k2 = generateDESkey();

byte[] edeKeyBytes = new byte[24];
System.arraycopy(k1.getEncoded(), 0, edeKeyBytes, 0, 8);
System.arraycopy(k2.getEncoded(), 0, edeKeyBytes, 8, 8);
System.arraycopy(k1.getEncoded(), 0, edeKeyBytes, 16, 8);

edeKey = new SecretKeySpec(edeKeyBytes, "DESede");

Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, edeKey);

System.out.println(Base64.encode(cipher.doFinal("plaintext".getBytes("UTF-8"))));

DESede使用三个键,我们称为k1,k2和k3。所有这些都被连接成一个单字节数组。在你的情况下,k1用第二次代替k3。

DESede uses three keys which we will call k1, k2 and k3. All of them are concatenated into a single byte array. In your case k1 is used a second time in place of k3.

这篇关于在Java中生成和使用两个密钥进行加密和解密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆