gpt4 book ai didi

使用私钥进行 Java RSA 解密会出现 BadPaddingException

转载 作者:行者123 更新时间:2023-12-01 10:36:36 26 4
gpt4 key购买 nike

今天,我编写了一些代码来使用 AES 加密字符串并使用 RSA 加密 key 。当我尝试解密所有内容时,Java 给出了 BadPaddingException。这是我的代码:

测试.java:

import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.PrintWriter;
import java.security.Key;
import java.security.SecureRandom;
import java.util.Scanner;

public class Test {

private static String publicName = null;
private static String privateName = null;

public static void main(String[] args) throws Exception {
Scanner scanner = new Scanner(System.in);
System.out.println("Choose an option: \n(1) Decrypt \n(2) Encrypt \n(3) Generate Keypair");
int choice = scanner.nextInt();
if(choice == 1) decrypt();
else if(choice == 2) encrypt();
else if(choice == 3) makeKeypair();
}

private static void makeKeypair() throws Exception {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter the name of your public key: ");
publicName = scanner.nextLine() + ".key";
System.out.println("Enter the name of your private key: ");
privateName = scanner.nextLine() + ".key";
KeyMaker keyMaker = new KeyMaker(publicName, privateName);
keyMaker.generateKeys();
}

public static void encrypt() throws Exception {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter the text you want to encrypt: ");
String toEncrypt = scanner.nextLine();
System.out.println("Enter the name of the public key you want to use: ");
publicName = scanner.nextLine() + ".key";
Encrypter encrypter = new Encrypter(publicName);

Key key = generateKey();
String encryptedWithAES = encryptAES(toEncrypt, key);

String encodedKey = java.util.Base64.getEncoder().encodeToString(key.getEncoded());
String encryptedKey = encrypter.rsaEncrypt(encodedKey);
String finalOutput = encryptedKey + encryptedWithAES;

System.out.println("Enter the name of the file encrypted file which will be created: ");
String fileName = scanner.nextLine();
PrintWriter out = new PrintWriter(fileName + ".txt");
out.println(finalOutput);
out.close();

System.out.println("DONE - saved as: " + fileName + ".txt");
scanner.close();
}

public static void decrypt() throws Exception {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter the name of your encrypted file: ");
String fileName = scanner.nextLine() + ".txt";

String givenInput = null;
try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
String line;
while ((line = br.readLine()) != null) {
givenInput = givenInput + line;
}
}
assert givenInput != null;
String encryptedKey = givenInput.substring(0,172);
String encryptedWithAES = givenInput.replace(encryptedKey, "");

System.out.println("Enter the name of your private key: ");
privateName = scanner.nextLine() + ".key";
Decrypter decrypter = new Decrypter(privateName);
String decryptedKey = decrypter.rsaDecrypt(encryptedKey);

byte[] decodedKey = java.util.Base64.getDecoder().decode(decryptedKey);
Key originalKey = new SecretKeySpec(decodedKey, "AES");

String decryptedWithAES = decryptAES(encryptedWithAES, originalKey);
System.out.println(decryptedWithAES);
scanner.close();
}

public static Key generateKey() throws Exception {
KeyGenerator kg = KeyGenerator.getInstance("AES");
SecureRandom random = new SecureRandom();
kg.init(random);
return kg.generateKey();
}

private static String encryptAES(String message, Key key) throws Exception {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE,key);

byte[] stringBytes = message.getBytes();
byte[] raw = cipher.doFinal(stringBytes);
return Base64.encodeBase64String(raw);
}

public static String decryptAES(String encrypted, Key key) throws Exception {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, key);

byte[] raw = Base64.decodeBase64(encrypted);
byte[] stringBytes = cipher.doFinal(raw);
return new String(stringBytes, "UTF8");
}
}

KeyMaker.java:

import java.io.FileOutputStream;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

public class KeyMaker {
String publicName;
String privateName;

public KeyMaker(String publicName, String privateName) {
this.publicName = publicName;
this.privateName = privateName;
}

public void generateKeys() throws Exception{
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024);
KeyPair kp = kpg.genKeyPair();

PrivateKey privateKey = kp.getPrivate();
PublicKey publicKey = kp.getPublic();

X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(
publicKey.getEncoded());
FileOutputStream fos = new FileOutputStream(publicName);
fos.write(x509EncodedKeySpec.getEncoded());
fos.close();

PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(
privateKey.getEncoded());
fos = new FileOutputStream(privateName);
fos.write(pkcs8EncodedKeySpec.getEncoded());
fos.close();
}
}

加密器.java:

import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.io.*;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;

public class Encrypter {
String keyFileName;

public Encrypter(String keyFileName) {
this.keyFileName = keyFileName;
}

public String rsaEncrypt(String data) throws Exception {
PublicKey pubKey = readPublicKeyFromFile(keyFileName);
byte[] utf8 = data.getBytes("UTF-8");
Cipher cipher = Cipher.getInstance("RSA");

cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] enc = cipher.doFinal(Base64.encodeBase64(utf8));
return Base64.encodeBase64String(enc);
}

private PublicKey readPublicKeyFromFile(String keyFileName) throws Exception {
File filePublicKey = new File(keyFileName);
FileInputStream fis = new FileInputStream(keyFileName);
byte[] encodedPublicKey = new byte[(int) filePublicKey.length()];
fis.read(encodedPublicKey);
fis.close();

KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(
encodedPublicKey);
PublicKey pubKey = keyFactory.generatePublic(publicKeySpec);
return pubKey;
}
}

解密器.java:

import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.io.*;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;

public class Decrypter {
String keyFileName;

public Decrypter(String keyFileName) {
this.keyFileName = keyFileName;
}

public String rsaDecrypt(String str) throws Exception {
PrivateKey privateKey = readPrivateKeyFromFile(keyFileName);
Cipher cipher = Cipher.getInstance("RSA");

cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] dec = Base64.decodeBase64(str);
byte[] utf8 = cipher.doFinal(Base64.decodeBase64(dec));
return Base64.encodeBase64String(utf8);

}

private PrivateKey readPrivateKeyFromFile(String keyFileName) throws Exception {
File filePrivateKey = new File(keyFileName);
FileInputStream fis = new FileInputStream(keyFileName);
byte[] encodedPrivateKey = new byte[(int) filePrivateKey.length()];
fis.read(encodedPrivateKey);
fis.close();

KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(
encodedPrivateKey);
PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
return privateKey;
}
}

最佳答案

在解密器中,您将 Base64 编码的字符串解码为字节,然后再次解码。在您的加密器中,您对字节进行加密,并将其编码为 Base64 一次。这可能就是您的问题所在。

奇怪的是,您似乎执行了不必要的 Base64 操作。例如,在 Encrypter 中,您获取要加密的字符串的字节。为什么要再次对这些字节进行 Base64 编码?

关于使用私钥进行 Java RSA 解密会出现 BadPaddingException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34682894/

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