javax.crypto.BadPaddingException:解密错误 - 无法解密加密的公钥

时间:2017-03-11 23:39:53

标签: java encryption

以下是我的加密设置

public static final String ALGORITHM = "RSA";
public static final String CIPHER = "RSA/ECB/PKCS1Padding";
public static final String HASH_ALGORITHM = "SHA-256";
public static final String SIGNATURE_ALGORITHM = "SHA256withRSA";
public static final int KEY_SIZE = 1048;

这是我加密的代码

public byte[] encrypt(byte[] toEncrypt, String keyPath){

    int keyLength = KEY_SIZE/8 - 11;

    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    String toEncryptString = new String(toEncrypt,StandardCharsets.UTF_8);

    String[] lines = toEncryptString.split("(?<=\\G.{" + keyLength + "})");

    byte[] encryptedData = new byte[0];

    try{
        inputStream = new ObjectInputStream(new FileInputStream(keyPath));
        final PublicKey publicKey = (PublicKey) inputStream.readObject();
        final Cipher cipher = Cipher.getInstance(CIPHER);

        cipher.init(Cipher.ENCRYPT_MODE,publicKey);

        if(toEncrypt.length >= keyLength){
            for(String line : lines){
                byteArrayOutputStream.write(cipher.doFinal(line.getBytes("UTF-8")));
            }
        }else{
            byteArrayOutputStream.write(cipher.doFinal(toEncrypt));
        }
        encryptedData = byteArrayOutputStream.toByteArray();

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (BadPaddingException e) {
        e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
        e.printStackTrace();
    }

    byte[] cipheredData = base64Encoder(encryptedData);

    System.out.println(Arrays.toString(cipheredData));

    return cipheredData;
}

这是我的解密代码

public byte[] decrypt(byte[] toDecrypt, String keyPath) {
    byte[] decypherText = base64Decoder(toDecrypt);

    System.out.println(toDecrypt.length);
    System.out.println(decypherText.length);

    int keyLength = KEY_SIZE/8 - 11; 

    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    String toEncryptString = Arrays.toString(decypherText);

    String[] lines = toEncryptString.split("(?<=\\G.{" + keyLength + "})");

    byte[] decipheredData = new byte[0];

    try{
        inputStream = new ObjectInputStream(new FileInputStream(keyPath));
        final PrivateKey privateKey = (PrivateKey) inputStream.readObject();
        final Cipher cipher = Cipher.getInstance(CIPHER);

        cipher.init(Cipher.DECRYPT_MODE,privateKey);

        if(decypherText.length >= keyLength){
            for(String line : lines){
                byteArrayOutputStream.write(cipher.doFinal(line.getBytes("UTF-8")));
            }
        }else{
            byteArrayOutputStream.write(cipher.doFinal(decypherText));
        }
        decipheredData = byteArrayOutputStream.toByteArray();

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    } catch (BadPaddingException e) {
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
        e.printStackTrace();
    }

    System.out.println(Arrays.toString(decipheredData));

    return decipheredData;
}

我试图加密公钥&#34; A&#34;使用公钥&#34; B&#34;。加密成功,但当我尝试使用私钥&#34; B&#34;解密时,它会给我错误。

代码看起来很好,已经多次审核了,过去16个小时,已经在这里的几个帖子中搜索过了,并没有为我的问题找到合适的答案。

此外,它在解密时已经给了我BadPaddingException。 &#34;数据不得超过131个字节&#34;。但是,我使用带填充的密码,因此它只能解密120字节的数据。为什么这个错误,如果加密的公钥被分成120个字节的块?

编辑:在其他人说加密公钥是一种谜之前,请记住,这是项目的目的......将公钥作为ID,因此需要加密,以便没有人发现用户的ID。

1 个答案:

答案 0 :(得分:1)

您的代码没有意义。您正试图在明文字符串上拆分密文。它不在那里。拆分字符串时它被删除了。在任何情况下,数据都已加密,因此在其中搜索明文是徒劳的。

您应该使用"(?<=\\G.{" + keyLength + "})"作为分隔符进行base64解码,解密,读取对象,然后重新组合

事实上,为什么你首先分裂然后加密多行是一个谜。

为什么你要序列化是另一回事。只需加密整个事物,不进行拆分,对其进行base64编码,然后保存。解密时,只需对其进行解码并解密即可。

最后,为什么你要加密公共密钥 是一个完全的谜。这是 PUBLIC 。不是秘密。