今天,我写了一些代码,用AES加密字符串,用RSA加密密钥。当我试图解密所有内容时,Java给了我一个BadPaddingException。这是我的代码:
测验爪哇:
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");
}
}
钥匙匠。爪哇:
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();
}
}
加密机。爪哇:
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;
}
}
解密程序。爪哇:
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编码?
我已经使用openssl生成了一个私钥,并在Terminal/command中执行以下命令: null 所有这些都无法解密我的密钥。下面是我根据这篇文章编写的类[https://stackoverflow.com/questions/35276820/decrypting-an-openssl-pem-encoded-rsa-privest-key-with-java]: 我对安全问题一无所知,所
我一直在搜索,但我似乎找不到一个简单的方法解密使用RSA。 我生成了一个公钥和私钥,它们存储在两个单独的文件中,并且是XML格式的。使用FromXmlString将公钥关联到RSACryptoServiceProvider对象,然后加密一个字符串,这一点没有问题。当我试图解密一个加密的字符串时,我的困惑就来了。我不确定如何将私钥数据与RSACryptoServiceProvider关联,以便使用D
我想使用带有RSA算法的OpenSSL使用私钥加密文件: 现在,如果我执行解密操作: 此操作需要私钥 我知道我应该使用公钥进行加密,如果我使用私钥,我会得到一个签名。 然而,我想这样做是为了学习。
我被告知,对于非对称密码学,您使用公钥加密明文,并使用私钥解密明文。所以我尝试了以下方法: 以及加密和解密函数 我希望控制台显示,但它显示的是这个。我是否错误地使用了RSACryptoServiceProvider?
我在C#程序(我在下面提到)中使用了RSA非对称密钥加密算法,我必须通过java程序加密数据。我希望我的java程序生成与C#程序相同的加密密钥。 公钥: C#加密程序: Java加密方案: 我尝试了上述java程序,但结果如下: O+gw 7+X hY x A 9 ltD V 5 zE RsF 4 Dy Xg MTc/gx 82 wR tT 1 x fR 3 su Y 0 XB JLa dp 7
我找到了几个可以使用的解决方案。Net RSA Provider使用公钥对消息进行加密,并使用私钥对其解密。 但我想要的是用私钥加密,用公钥解密。 我希望在我的应用程序中存储公钥,并使用私钥加密许可证,例如在我的开发人员计算机上,将其发送到应用程序,并让信息使用公钥解密。 我怎样才能做到这一点?