gpt4 book ai didi

java - 为什么我的 AES 加密会引发 InvalidKeyException?

转载 作者:IT老高 更新时间:2023-10-28 20:50:02 26 4
gpt4 key购买 nike

我目前正在开发一个使用 key 加密/解密特定文件的功能。我写了三个类,一个生成 key ,一个用 key 加密文件,一个解密。

生成 key 和加密文件工作正常,但是当我尝试解密文件时,在以下行抛出异常:c.init(Cipher.DECRYPT_MODE, keySpec);:

java.security.InvalidKeyException: Parameters missing

我认为我在将 key 流式传输到我的 byte[] 时做错了,或者在解密文件时出现了问题。

三个类的快速解释: KeyHandler 创建一个 AES key 并将其存储在硬盘上。 key /明文/加密/解密文件的名称目前是硬编码的,用于测试目的。

EncryptionHandler 将磁盘上的 .txt 文件转换为字节,使用 key 对文件进行加密,然后使用 CipherOutputStream 将加密后的字节写入磁盘。

DecryptionHandler当然与EncryptionHandler相反。

代码如下:

    public class KeyHandler {
Scanner scan = new Scanner(System.in);

public KeyHandler(){
try {
startMenu();
} catch (Exception e) {
System.out.println("fel någonstanns :)");
}
}

public void startMenu() throws Exception{

System.out.println("Hej. Med detta program kan du generera en hemlig nyckel"+"\n"+"Vill du:"+"\n"+ "1. Generera en nyckel"+"\n"+"2. Avsluta");
int val=Integer.parseInt(scan.nextLine());
do{
switch (val){
case 1: generateKey(); break;
case 2: System.exit(1);

default: System.out.println("Du måste välja val 1 eller 2");
}
}
while (val!=3);
}

public void generateKey() throws Exception{
try {
KeyGenerator gen = KeyGenerator.getInstance("AES");
gen.init(128);

SecretKey key=gen.generateKey();
byte[] keyBytes = key.getEncoded();
System.out.print("Ge nyckeln ett filnamn: ");
String filename = scan.next();
System.out.println("Genererar nyckeln...");
FileOutputStream fileOut = new FileOutputStream(filename);
fileOut.write(keyBytes);
fileOut.close();
System.out.println("Nyckeln är genererad med filnamnet: "+filename+"...");
System.exit(1);
} catch (NoSuchAlgorithmException e) {
}

}

public static void main(String[] args){
new KeyHandler();
}

}


public class EncryptHandler {
private String encryptedDataString;
private Cipher ecipher;

AlgorithmParameterSpec paramSpec;
byte[] iv;

public EncryptHandler(String dataString, String secretKey, String encryptedDataString){
this.encryptedDataString=encryptedDataString;
try {
encryptFile(dataString, secretKey);
} catch (Exception e) {

}
}

public void encryptFile(String dataString, String secretKey) throws Exception{

FileInputStream fis = new FileInputStream(secretKey);
ByteArrayOutputStream baos = new ByteArrayOutputStream();

int theByte = 0;
while ((theByte = fis.read()) != -1)
{
baos.write(theByte);
}
fis.close();

byte[] keyBytes = baos.toByteArray();
baos.close();
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");

try
{
ecipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
ecipher.init(Cipher.ENCRYPT_MODE, keySpec);

}
catch (Exception e)
{
e.printStackTrace();
}

System.out.println("Encrypting file...");
try
{

encryptStream(new FileInputStream(dataString),new FileOutputStream(encryptedDataString));
}
catch(Exception e){
e.printStackTrace();
}

}
public void encryptStream(InputStream in, OutputStream out){
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
try {
out = new CipherOutputStream(out, ecipher);

// read the cleartext and write it to out
int numRead = 0;
while ((numRead = in.read(buf)) >= 0) {
out.write(buf, 0, numRead);

}
bOut.writeTo(out);
out.close();
bOut.reset();

}
catch (java.io.IOException e)
{
}

}


public static void main(String[] args){
String data = "test.txt";
String keyFileName="a";
String encryptedFile="krypterad.txt";
//String encryptedFile =args[2];
new EncryptHandler(data, keyFileName, encryptedFile);
}

}


public class DecryptHandler {
public DecryptHandler(){

try {
decryptFile();
} catch (Exception e) {
System.out.println("något gick fel :) ");
}
}


public void decryptFile()throws Exception{
byte[] buf = new byte[1024];
String keyFilename = "hemlig";
FileInputStream fis = new FileInputStream(keyFilename);
ByteArrayOutputStream baos = new ByteArrayOutputStream();

int theByte = 0;
while ((theByte = fis.read()) != -1)
{
baos.write(theByte);
}
fis.close();

byte[] keyBytes = baos.toByteArray();
baos.close();
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");


Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
System.out.println("här");
c.init(Cipher.DECRYPT_MODE, keySpec);

System.out.println("Decrypting file...");
try{
decryptStream(new FileInputStream("krypterad.txt"),new FileOutputStream("Dekryperad.txt"), c, buf);
}
catch (java.io.IOException e){

}
System.out.println("File decrypted!");
}
public void decryptStream(InputStream in, OutputStream out, Cipher dcipher, byte[] buf){
try
{

in = new CipherInputStream(in, dcipher);

// Read in the decrypted bytes and write the cleartext to out
int numRead = 0;


while ((numRead = in.read(buf)) >= 0)
{
out.write(buf, 0, numRead);

}
out.close();


}
catch (java.io.IOException e){

}
}
public static void main(String[]args){
new DecryptHandler();
}
}

最佳答案

如果您使用像 CBC 这样的 block 链模式,您还需要为 Cipher 提供一个 IvParameterSpec。

所以你可以像这样初始化一个 IvParameterSpec:

    // build the initialization vector.  This example is all zeros, but it 
// could be any value or generated using a random number generator.
byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
IvParameterSpec ivspec = new IvParameterSpec(iv);

然后为了加密,将你初始化密码的代码更改为:

ecipher.init(Cipher.ENCRYPT_MODE, keySpec, ivspec);

你在哪里解密:

c.init(Cipher.DECRYPT_MODE, keySpec, ivspec);

所以你的完整代码应该是这样的(它适用于我):

    public class KeyHandler {

Scanner scan = new Scanner(System.in);

public KeyHandler() {
try {
startMenu();
} catch (Exception e) {
System.out.println("fel någonstanns :)");
}
}

public void startMenu() throws Exception {

System.out.println("Hej. Med detta program kan du generera en hemlig nyckel" + "\n" + "Vill du:" + "\n" + "1. Generera en nyckel" + "\n" + "2. Avsluta");
int val = Integer.parseInt(scan.nextLine());
do {
switch (val) {
case 1:
generateKey();
break;
case 2:
System.exit(1);

default:
System.out.println("Du måste välja val 1 eller 2");
}
} while (val != 3);
}

public void generateKey() throws Exception {
try {
KeyGenerator gen = KeyGenerator.getInstance("AES");
gen.init(128);

SecretKey key = gen.generateKey();
byte[] keyBytes = key.getEncoded();
System.out.print("Ge nyckeln ett filnamn: ");
String filename = scan.next();
System.out.println("Genererar nyckeln...");
FileOutputStream fileOut = new FileOutputStream(filename);
fileOut.write(keyBytes);
fileOut.close();
System.out.println("Nyckeln är genererad med filnamnet: " + filename + "...");
System.exit(1);
} catch (NoSuchAlgorithmException e) {
}

}

public static void main(String[] args) {
new KeyHandler();
}
}

public class EncryptHandler {

private String encryptedDataString;
private Cipher ecipher;
AlgorithmParameterSpec paramSpec;
byte[] iv;

public EncryptHandler(String dataString, String secretKey, String encryptedDataString) {
this.encryptedDataString = encryptedDataString;
try {
encryptFile(dataString, secretKey);
} catch (Exception e) {
}
}

public void encryptFile(String dataString, String secretKey) throws Exception {

FileInputStream fis = new FileInputStream(secretKey);
ByteArrayOutputStream baos = new ByteArrayOutputStream();

int theByte = 0;
while ((theByte = fis.read()) != -1) {
baos.write(theByte);
}
fis.close();

byte[] keyBytes = baos.toByteArray();
baos.close();
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");

// build the initialization vector. This example is all zeros, but it
// could be any value or generated using a random number generator.
byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
IvParameterSpec ivspec = new IvParameterSpec(iv);

try {
ecipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
ecipher.init(Cipher.ENCRYPT_MODE, keySpec, ivspec);

} catch (Exception e) {
e.printStackTrace();
}

System.out.println("Encrypting file...");
try {

encryptStream(new FileInputStream(dataString), new FileOutputStream(encryptedDataString));
} catch (Exception e) {
e.printStackTrace();
}

}

public void encryptStream(InputStream in, OutputStream out) {
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
try {
out = new CipherOutputStream(out, ecipher);

// read the cleartext and write it to out
int numRead = 0;
while ((numRead = in.read(buf)) >= 0) {
out.write(buf, 0, numRead);

}
bOut.writeTo(out);
out.close();
bOut.reset();

} catch (java.io.IOException e) {
}

}

public static void main(String[] args) {
String data = "test.txt";
String keyFileName = "a";
String encryptedFile = "krypterad.txt";
//String encryptedFile =args[2];
new EncryptHandler(data, keyFileName, encryptedFile);
}
}

public class DecryptHandler {

public DecryptHandler() {

try {
decryptFile();
} catch (Exception e) {
e.printStackTrace();
System.out.println("något gick fel :) ");
}
}

public void decryptFile() throws Exception {
byte[] buf = new byte[1024];
String keyFilename = "hemlig";
FileInputStream fis = new FileInputStream(keyFilename);
ByteArrayOutputStream baos = new ByteArrayOutputStream();

int theByte = 0;
while ((theByte = fis.read()) != -1) {
baos.write(theByte);
}
fis.close();

byte[] keyBytes = baos.toByteArray();
baos.close();
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");

// build the initialization vector. This example is all zeros, but it
// could be any value or generated using a random number generator.
byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
IvParameterSpec ivspec = new IvParameterSpec(iv);

Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
System.out.println("här");
c.init(Cipher.DECRYPT_MODE, keySpec, ivspec);

System.out.println("Decrypting file...");
try {
decryptStream(new FileInputStream("krypterad.txt"), new FileOutputStream("Dekryperad.txt"), c, buf);
} catch (java.io.IOException e) {
}
System.out.println("File decrypted!");
}

public void decryptStream(InputStream in, OutputStream out, Cipher dcipher, byte[] buf) {
try {

in = new CipherInputStream(in, dcipher);

// Read in the decrypted bytes and write the cleartext to out
int numRead = 0;


while ((numRead = in.read(buf)) >= 0) {
out.write(buf, 0, numRead);

}
out.close();


} catch (java.io.IOException e) {
}
}

public static void main(String[] args) {
new DecryptHandler();
}
}

关于java - 为什么我的 AES 加密会引发 InvalidKeyException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6669181/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com