我正在学习Java安全课程,我们正在学习加密和解密用户提供的信息。
编译代码没有问题,但是在运行代码时,它给出了“线程“ main”中的异常” javax.crypto.IllegalBlockSizeException:解密中的最后一块未完成。”
我相信正在发生的事情是内存地址分别存储在“ saltString ”和“ ciphertextString ”中。这两个变量都可以在“ 加密”方法中找到。
我认为这发生在以下两行中: “ 字符串ciphertextString = mycipher.doFinal(text).toString();”和“ 字符串saltString = mycipher.doFinal(salt).toString();”
我不确定如何为这些变量分配正确的信息。
感谢您的阅读。
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.util.*;
import java.util.Scanner;
import java.util.Random;
import java.util.Arrays;
public class PasswordEncryption{
private static int ITERATIONS = 1000;
public static void main(String[] args) throws Exception{
Scanner keyboard = new Scanner(System.in);
//obtain password and text message from the user
System.out.print("Please enter a password: ");
char[] password = keyboard.next().toCharArray();
Scanner keyboard2 = new Scanner(System.in);
System.out.print("Please enter a text message to encrypt: ");
String text = keyboard2.nextLine();
System.out.println();
String cipherText = encrypt(password, text);
System.out.println();
System.out.println("CipherText: " + cipherText);
System.out.print("Please re-enter your password to decrypt the string: ");
char[] validPassword = keyboard2.nextLine().toCharArray();
System.out.println("ValidPassword: " + validPassword);
String plainText = decrypt(validPassword, cipherText);
System.out.println(plainText);
}
private static String encrypt(char[] password, String plainText) throws Exception{
//begin by creating a random salt of 64 bits(8 bytes)
byte [] salt = new byte[8];
Random Random = new Random();
Random.nextBytes(salt);
System.out.println("Random bytes: " + Random.nextInt());
System.out.println("Salt: " + CryptoUtils.toHex(salt));
//create our key based on password
PBEKeySpec keySpec = new PBEKeySpec(password);
SecretKeyFactory keyFactory =
SecretKeyFactory.getInstance("PBEWithSHAAnd3KeyTripleDES");
SecretKey key = keyFactory.generateSecret(keySpec);
PBEParameterSpec paramSpec = new PBEParameterSpec(salt, ITERATIONS);
//create a cipher and initialize it for encrypting
Cipher mycipher = Cipher.getInstance("PBEWithSHAAnd3KeyTripleDES");
mycipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
byte[] text = CryptoUtils.toByteArray(plainText);
System.out.println("Plaintext: " + plainText);
System.out.println("PlaintTextArray: " + Arrays.toString(text));
String ciphertextString = mycipher.doFinal(text).toString();
String saltString = mycipher.doFinal(salt).toString();
return saltString + ciphertextString;
}
private static String decrypt(char[] password, String text) throws Exception{
//being by splitting the text into salt and text Strings
String salt = text.substring(0,12);
String ciphertext = text.substring(12,text.length());
//get the bytes for the salt and ciphertext
//store salt into saltArray for PBEParameterSpec to take in
byte[] saltArray = CryptoUtils.toByteArray(salt);
byte[] ciphertextArray = CryptoUtils.toByteArray(ciphertext);
System.out.println();
System.out.println("Salt: " + salt);
System.out.println("CiperText: " + ciphertext);
//create our key based on password
PBEKeySpec keySpec = new PBEKeySpec(password);
SecretKeyFactory keyFactory =
SecretKeyFactory.getInstance("PBEWithSHAAnd3KeyTripleDES");
SecretKey key = keyFactory.generateSecret(keySpec);
PBEParameterSpec paramSpec = new PBEParameterSpec(saltArray, ITERATIONS);
//perform the actual decryption
Cipher mycipher = Cipher.getInstance("PBEWithSHAAnd3KeyTripleDES");
mycipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
byte [] plaintextArray = mycipher.doFinal(ciphertextArray);
//System.out.println("plaintextArray: " + plaintextArray);
String plaintext = CryptoUtils.toString(plaintextArray);
return plaintext;
}
}