具有Java中2个不同键的3des获得null。

import java.security.spec.*;
import javax.crypto.*;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class DESedeEncryption {
public static void main(String[] args) {

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

String firstEncryption = desEncryption("plaintext", k1);
System.out.println("firstEncryption Value : "+firstEncryption);
String decryption = desDecryption(firstEncryption, k2);
System.out.println("decryption Value : "+decryption);
String secondEncryption = desEncryption(decryption, k1);
System.out.println("secondEncryption Value : "+secondEncryption);

}

public static SecretKey generateDESkey() {
KeyGenerator keyGen = null;
try {
    keyGen = KeyGenerator.getInstance("DESede");
} catch (Exception ex) {
}
keyGen.init(112); // key length 56
SecretKey secretKey = keyGen.generateKey();
return secretKey;
}

public static String desEncryption(String strToEncrypt, SecretKey desKey) {
try {
    Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, desKey);
    BASE64Encoder base64encoder = new BASE64Encoder();
    byte[] encryptedText = cipher.doFinal(strToEncrypt.getBytes());
    String encryptedString =base64encoder.encode(encryptedText);
    return encryptedString;
} catch (Exception 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);
    BASE64Decoder base64decoder = new BASE64Decoder();
    byte[] encryptedText = base64decoder.decodeBuffer(strToDecrypt);
    byte[] plainText = cipher.doFinal(encryptedText);
    String decryptedString= bytes2String(plainText);
    return decryptedString;
} catch (Exception ex) {
}
return null;
}

 private static String bytes2String(byte[] bytes) {
    StringBuffer stringBuffer = new StringBuffer();
    for (int i = 0; i <bytes.length; i++) {
        stringBuffer.append((char) bytes[i]);
    }
    return stringBuffer.toString();
}
}


当我运行上面的代码时,我得到空值。请帮助。

输出:

firstEncryption值:jAihaGgiOzBSFwBWo3gpbw ==

解密值:null

secondEncryption值:null

getting error:

firstEncryption Value : ygGPwCllarWvSH8td55j/w==
javax.crypto.BadPaddingException: Given final block not properly padded
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:811)
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)
    at com.sun.crypto.provider.DESedeCipher.engineDoFinal(DESedeCipher.java:
294)
    at javax.crypto.Cipher.doFinal(Cipher.java:2087)
    at DESedeEncryption.desDecryption(DESedeEncryption.java:145)
    at DESedeEncryption.main(DESedeEncryption.java:107)
decryption Value : null
java.lang.NullPointerException
    at DESedeEncryption.desEncryption(DESedeEncryption.java:130)
    at DESedeEncryption.main(DESedeEncryption.java:109)
secondEncryption Value : null

最佳答案

对称密码通过使用同一密钥进行加密和解密来工作,因此名称是对称的。 (并且对于大多数模式,相同的IV,但是IV不必是秘密的。)您正在使用一个密钥进行加密,然后使用独立密钥进行解密,而独立密钥的概率却是千差万别的(即,一次加密后可能相同)万亿个永恒值)。那行不通。

也许您对Triple-DES(也称为3DES DESede或TDEA)的描述感到困惑。原始的DES(或DEA)密码使用56位密钥(8字节),该密钥在1960年代是安全的,但现在还不是。 Triple-DES是使用DES作为构建块定义的,但具有3个密钥(k1,k2,k3)的捆绑包,这些密钥也可以视为组合的168位密钥(24字节)。如果k3 = k1,尽管密钥仍存储为24个字节,但密钥描述为112位。您对KeyGenerator“ DESede” .init(112)的调用恰好做到了;它生成一个24字节的捆绑包,其中k3 = k1和k2不同。在过去,为方便起见,将Triple-DES定义为使用单DES进行k1加密,k2解密和k3加密,以及解密时的相反操作,因此使用名称DES-EDE或DESede。请参阅http://en.wikipedia.org/wiki/Triple_DES

如果确实需要,可以通过执行E,D,E(如果使用反向D,E,D)然后在其周围包装模式来使用Cipher“ DES”在Java中自己实现Triple-DES,请参见Java Triple DES encryption with 2 different keys。但是,仅使用密码“ DESede”要容易得多,它可以为您做很多事情,就像其他任何对称密码基元一样,将DESede视为该问题的答案。

另外,模式ECB也是危险的。夸张地说它总是像某些人一样不安全,但是从历史上看,很多非专家设计的使用它的应用都是不安全的。除非您对问题的了解远不止于此,或者除非您知道某个人在进行设计(或与之交互),否则请使用更好的既定模式,例如CBC或CTR。

07-24 09:17