我试图创建一个简单的加密/解密程序,但在解密时我遇到了问题。程序的工作方式,我从用户获得字符串输入,然后使用DES加密,转换为Base64并为用户提供转换后的密钥。但是,当我从用户那里得到密钥并尝试解密时,我得到错误:
java.security.InvalidKeyException:没有安装的提供程序支持此密钥:(null)
或
javax.crypto.BadPaddingException
我不知道故障是在加密时还是在解密时。这是相应的代码片段:
import javax.xml.bind.DatatypeConverter;
public static boolean encrypt(byte[] text){
Boolean yorn = false;
try{
myDesKey = KeyGenerator.getInstance("DES").generateKey();
//myDeskKey = myDesKey.toString();
Cipher desCipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
desCipher.init(Cipher.ENCRYPT_MODE, myDesKey);
//I felt it would be better seeing the secret key as "woatDnBJLAg=" instead of "com.sun.crypto.provider.DESKey@18765"
if (myDesKey != null) {
stringKey = DatatypeConverter.printBase64Binary(myDesKey.getEncoded());
System.out.println("actual secret_key:" + myDesKey);
byte[] encodedKey = DatatypeConverter.parseBase64Binary(stringKey);
myDesKey = new SecretKeySpec(encodedKey, 0, encodedKey.length,
"DES");
System.out.println("after encode & decode secret_key:"
+ DatatypeConverter.printBase64Binary(myDesKey.getEncoded()));
}
textEncrypted = desCipher.doFinal(text);
yorn = true;
JTextArea textArea = new JTextArea(2,50);
textArea.setText("Your encryption key is: " + stringKey + " . Ensure you store it in a safe place" );// + DatatypeConverter.printBase64Binary(myDesKey.getEncoded()));
textArea.setEditable(false);
JOptionPane.showMessageDialog(null, new JScrollPane(textArea), "RESULT", JOptionPane.INFORMATION_MESSAGE);
}catch(Exception e)
{
System.out.println("There has been an error encrypting the file");
yorn = false;
}
return yorn;
解密
public static String decrypt(byte[] cipherText, SecretKey key,String key1)
{
String plainText = "";
try{
SecretKey myDesKey = key;
if(key == null){
JOptionPane.showMessageDialog(null, "We were unable to find your decryption key. Please enter your decryption key below: ");
JTextArea textBox = new JTextArea(1,15);
JOptionPane.showMessageDialog(null, new JScrollPane(textBox),"Enter your decryption key ",JOptionPane.PLAIN_MESSAGE);
//myDesKey = textBox.toSecretKey;
}
Cipher desCipher;
desCipher = Cipher.getInstance("DES");
desCipher.init(Cipher.DECRYPT_MODE, myDesKey);
byte[] textDecrypted = desCipher.doFinal(cipherText);
plainText = new String(textDecrypted);
JOptionPane.showMessageDialog(null, plainText, "DECRYPTED MESSAGE", 0);
}catch(Exception e)
{
System.out.println("There has been an error decrypting the file");
System.out.println(e);
}return plainText;
}
}
我知道我可能会收到错误,因为我已经将来自各个堆栈的代码混杂在一起,而且我似乎已经失去了情节,但是我们将非常感谢任何帮助。 谢谢!
答案 0 :(得分:1)
您正在使用两种不同的密码。 Cipher.getInstance("DES")
未完全指定,因此可能默认为Cipher.getInstance("DES/ECB/PKCS5Padding")
,这与您在加密期间使用的CBC模式不同。
其次,由于您正在使用CBC模式,因此您需要管理初始化向量(IV),但您根本不需要这样做。您可以将IV作为Cipher#init
的第三个参数提供,也可以像现在一样自动生成,但是您必须将IV(desCipher.getIV()
)和密文一起发送给接收方。 IV并不是秘密的。一种常见的方法是将其添加到密文并在解密之前将其切掉。
最后,您在解密过程中使用的密钥与您在加密过程中使用的密钥不同,因为您在加密后对密钥进行了重新编码,但没有解码回来。