[英]Basic Program for encrypt/Decrypt : javax.crypto.BadPaddingException: Decryption error
我已经为加密/解密编写了一个非常基本的程序,现在尝试仅加密单个字符串。 加密工作正常,但在解密中抛出错误
javax.crypto.BadPaddingException:解密错误。
它在下面的行上引发错误
byte[] decodedData = (rsa.doFinal(decodedValue));
我尝试了多种方法并经历了很多线程,但找不到解决方案。 有人可以帮我解决这个问题吗?
该类很简单,仅具有4种方法,首先是测试方法,其次是密钥库加载方法,其余两种方法是加密和解密。
package XXXX;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
public class EncryptDecryptUtil {
private String publicKeyStoreFileName = "C:\\Program Files\\Java\\jdk1.8.0_51\\jre\\lib\\security\\cacerts";
private String pubKeyStorePwd = "XXX";
private String pubKeyAlias="XXXX";
private static final String JKS = "JKS";
private static final int CONST_16 = 16;
public String TestMethod(final String clearText) throws InvalidKeyException, NoSuchAlgorithmException,
NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, KeyStoreException,
CertificateException, IOException, UnrecoverableKeyException {
byte[] ecryptedAESKey = generateEncryptedData("TEST");
System.out.println("Encrypted Key = " + ecryptedAESKey);
System.out.println("Decrypted Key = " + generateDecryptedData(ecryptedAESKey));
return generateDecryptedData(ecryptedAESKey);
}
private KeyStore loadKeyStore() throws KeyStoreException, NoSuchAlgorithmException, CertificateException,
IOException {
KeyStore keystore = KeyStore.getInstance(JKS);
FileInputStream tmp = new FileInputStream(publicKeyStoreFileName);
keystore.load(tmp, pubKeyStorePwd.toCharArray());
tmp.close();
return keystore;
}
private byte[] generateEncryptedData(final String data) throws NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException,
KeyStoreException, CertificateException, IOException, UnrecoverableKeyException {
Base64 base64 = new Base64();
X509Certificate cert;
KeyStore keystore = loadKeyStore();
cert = (java.security.cert.X509Certificate) keystore.getCertificate(pubKeyAlias);
Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding");
rsa.init(Cipher.ENCRYPT_MODE, cert);
byte[] ecrypteddata = (base64.encode(rsa.doFinal(data.getBytes(StandardCharsets.UTF_8))));
return ecrypteddata;
}
public String generateDecryptedData(final byte[] encryptedData) throws NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException,
KeyStoreException, CertificateException, IOException, UnrecoverableKeyException {
Base64 base64 = new Base64();
X509Certificate cert;
KeyStore keystore = loadKeyStore();
cert = (java.security.cert.X509Certificate) keystore.getCertificate(pubKeyAlias);
Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding");
rsa.init(Cipher.DECRYPT_MODE, cert);
byte[] decodedValue = base64.decode(encryptedData);
byte[] decodedData = (rsa.doFinal(decodedValue));
return new String(decodedData);
}
}
Java API在证书和(RSA)私钥之间有所不同。 私钥虽然与证书相关联,但不是证书的一部分。 Java(幸运的是)在这方面与Microsoft的.NET API不同,.NET API充满了如此糟糕的设计选择。
当您尝试时:
rsa.init(Cipher.DECRYPT_MODE, cert);
您应该期待一个错误。 然而,问题在于该构造有时用于使用公钥原始“解密”基于RSA的签名。 因此,尽管您应该始终使用私钥解密,但是明确禁止使用公钥解密(对于Sun提供程序)。
因此,请尝试使用KeyStore#getKey
或(更现代但更复杂的) KeyStore#getEntry
来检索私钥。 那就是:如果你确实有在密钥存储和检索它的密码私钥。
下面是最终的工作代码:
import org.apache.commons.codec.binary.Base64;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
/**
* Created by Suchit Pandya on 9/16/2016.
*/
public class EncryptLogic2 {
private String publicKeyStoreFileName = "C:\\Program Files\\Java\\jdk1.8.0_51\\jre\\lib\\security\\cacerts";
private String pubKeyStorePwd = "password";
private String pubKeyAlias="certName";
private static final String JKS = "JKS";
private static final String SHA1PRNG = "SHA1PRNG";
private static final String RSA = "RSA/ECB/PKCS1Padding";
private static final int CONST_16 = 16;
private static byte[] asKey;
public String TestMethod(final String clearText) throws InvalidKeyException, NoSuchAlgorithmException,
NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, KeyStoreException,
CertificateException, IOException, UnrecoverableKeyException {
String ecryptedData = generateEncryptedData(clearText);
String decryptedData = generateDecryptedData(ecryptedData);
System.out.println("*********** Decrypted Data = " + decryptedData);
return decryptedData;
}
private KeyStore loadKeyStore() throws KeyStoreException, NoSuchAlgorithmException, CertificateException,
IOException {
KeyStore keystore = KeyStore.getInstance(JKS);
FileInputStream tmp = new FileInputStream(publicKeyStoreFileName);
keystore.load(tmp, pubKeyStorePwd.toCharArray());
tmp.close();
return keystore;
}
private String generateEncryptedData(final String data) throws NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException,
KeyStoreException, CertificateException, IOException, UnrecoverableKeyException {
Base64 base64 = new Base64();
X509Certificate cert;
KeyStore keystore = loadKeyStore();
cert = (java.security.cert.X509Certificate) keystore.getCertificate(pubKeyAlias);
Cipher rsa = Cipher.getInstance(RSA);
Key key = cert.getPublicKey();
rsa.init(Cipher.ENCRYPT_MODE, key);
byte[] ecrypteddata = rsa.doFinal(data.getBytes(StandardCharsets.UTF_8));
return Base64.encodeBase64String(ecrypteddata);
}
public String generateDecryptedData(final String encryptedData) throws NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException,
KeyStoreException, CertificateException, IOException, UnrecoverableKeyException {
Base64 base64 = new Base64();
X509Certificate cert;
KeyStore keystore = loadKeyStore();
Cipher rsa = Cipher.getInstance(RSA);
Key key = keystore.getKey(pubKeyAlias, pubKeyStorePwd.toCharArray());
rsa.init(Cipher.DECRYPT_MODE, key);
byte[] decodedValue = base64.decode(encryptedData);
byte[] decodedData = (rsa.doFinal(decodedValue));
return new String(decodedData, StandardCharsets.UTF_8);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.