我正在尝试使用具有两个不同密钥的三重DES来加密数据,因此给定两个密钥k1和k2,密码文本将是Ek1(Dk2(Ek1(明文)))其中E是加密和D解密。我正在尝试使用Java中的DES算法来模拟这个。这是代码:
public static void main(String[] args) {
SecretKey k1 = generateDESkey();
SecretKey k2 = generateDESkey();
String firstEncryption = desEncryption("plaintext", k1);
String decryption = desDecryption(firstEncryption, k2);
String secondEncryption = desEncryption(decryption, k1);
}
public static SecretKey generateDESkey() {
KeyGenerator keyGen = null;
try {
keyGen = KeyGenerator.getInstance("DES");
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(Test.class
.getName()).log(Level.SEVERE, null, ex);
}
keyGen.init(56); // key length 56
SecretKey secretKey = keyGen.generateKey();
return secretKey;
}
public static String desEncryption(String strToEncrypt, SecretKey desKey) {
try {
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, desKey);
String encryptedString = Base64.encode(cipher.doFinal(strToEncrypt.getBytes()));
return encryptedString;
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(Test.class
.getName()).log(Level.SEVERE, null, ex);
} catch (NoSuchPaddingException ex) {
Logger.getLogger(Test.class
.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalBlockSizeException ex) {
Logger.getLogger(Test.class
.getName()).log(Level.SEVERE, null, ex);
} catch (BadPaddingException ex) {
Logger.getLogger(Test.class
.getName()).log(Level.SEVERE, null, ex);
} catch (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("DES/ECB/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, desKey);
String decryptedString = new String(cipher.doFinal(Base64.decode(strToDecrypt)));
return decryptedString;
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(Test.class
.getName()).log(Level.SEVERE, null, ex);
} catch (NoSuchPaddingException ex) {
Logger.getLogger(Test.class
.getName()).log(Level.SEVERE, null, ex);
} catch (InvalidKeyException ex) {
Logger.getLogger(Test.class
.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalBlockSizeException ex) {
Logger.getLogger(Test.class
.getName()).log(Level.SEVERE, null, ex);
} catch (BadPaddingException ex) {
Logger.getLogger(Test.class
.getName()).log(Level.SEVERE, null, ex);
} catch (Base64DecodingException ex) {
Logger.getLogger(Test.class
.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
我有这个错误:javax.crypto.BadPaddingException:在尝试解密此代码行时,给定最终块没有正确填充:
String decryptedString = new String(cipher.doFinal(Base64.decode(strToDecrypt)));
您能帮我解决这个问题,或者您是否知道使用三重DES加密数据的直接方法,使用两个不同的密钥,总密钥长度为128位?我没有找到任何算法,因此我尝试使用简单的DES模拟它。
答案 0 :(得分:3)
您正在将任意字节转换为字符串,这会破坏它们。完全用字节工作。如果需要将加密数据转换为String,则使用Base64编码。
答案 1 :(得分:2)
为什么不使用包含的DESede算法?
将所有DES代码实例更改为DESede,并将密钥生成方法更改为:
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);
}
keyGen.init(112); // key length 112 for two keys, 168 for three keys
SecretKey secretKey = keyGen.generateKey();
return secretKey;
}
请注意现在如何使用DESede提供getInstance()方法,并且密钥大小已增加到112(三个密钥为168)。
从以下位置更改Cipher实例:
Cipher.getInstance("DES/ECB/PKCS5Padding");
到
Cipher.getInstance("DESede/ECB/PKCS5Padding");
你已经确定了。
答案 2 :(得分:0)
只需指出,具有112位密钥的DES实际上是双DES,而不是具有168位密钥(3 * 56)的三重DES。由于meet-in-the-middle attack (MITM) https://en.wikipedia.org/wiki/Meet-in-the-middle_attack
,切勿使用双DES。总之,不应再使用单DES(56位),双DES(112位)和三DES(168位),因为它们不提供128位安全性。