简体   繁体   English

加密/解密的基本程序:javax.crypto.BadPaddingException:解密错误

[英]Basic Program for encrypt/Decrypt : javax.crypto.BadPaddingException: Decryption error

I have written a very basic program for Encrypt/Decrypt and trying to encrypt just single string right now. 我已经为加密/解密编写了一个非常基本的程序,现在尝试仅加密单个字符串。 Encryption is working fine but in Decryption it is throwing an error 加密工作正常,但在解密中抛出错误

javax.crypto.BadPaddingException: Decryption error. javax.crypto.BadPaddingException:解密错误。

It is throwing an error on below line 它在下面的行上引发错误

byte[] decodedData = (rsa.doFinal(decodedValue));

I tried multiple ways and went through lots of threads but not able to find the solution. 我尝试了多种方法并经历了很多线程,但找不到解决方案。 Can any one please help me with this issue? 有人可以帮我解决这个问题吗?

The class is simple with 4 methods only, first is test method, next is keystore load method, and rest of two methods are encrypt and decrypt. 该类很简单,仅具有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);
    }    
}

The Java API makes a difference between certificates and (RSA) private keys. Java API在证书和(RSA)私钥之间有所不同。 A private key, although associated with a certificate, is not part of a certificate. 私钥虽然与证书相关联,但不是证书的一部分。 Java (fortunately) differs with Microsoft's .NET API in this respect, the .NET API is full of such bad design choices. Java(幸运的是)在这方面与Microsoft的.NET API不同,.NET API充满了如此糟糕的设计选择。

When you're trying: 当您尝试时:

rsa.init(Cipher.DECRYPT_MODE, cert);

you should expect an error. 您应该期待一个错误。 The problem is however that this construct is sometimes used to raw "decrypt" RSA based signatures with a public key. 然而,问题在于该构造有时用于使用公钥原始“解密”基于RSA的签名。 So although you should always decrypt with a private key, decrypting with a public key is not explicitly disallowed (for the Sun providers). 因此,尽管您应该始终使用私钥解密,但是明确禁止使用公钥解密(对于Sun提供程序)。

So instead try and use KeyStore#getKey or (more modern but more convoluted) KeyStore#getEntry to retrieve the private key. 因此,请尝试使用KeyStore#getKey或(更现代但更复杂的) KeyStore#getEntry来检索私钥。 That is: if you do indeed have a private key in the keystore and the password to retrieve it. 那就是:如果你确实有在密钥存储和检索它的密码私钥。

Below is the final working code: 下面是最终的工作代码:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM