RSA-AES解密问题-javax.crypto.BadPaddingException:解密错误

时间:2019-05-07 00:58:30

标签: java python encryption aes rsa

我需要将python代码转换为RSA-AES解密逻辑的java代码。他们提供了RSA加密的字符串和私钥作为PEM文件格式。我们需要在Java代码中实现相同的解密。

在这里,我已经包含了python代码,(我们必须将其转换为java)

import base64

from Crypto.Cipher import AES

from cryptography.hazmat.primitives import hashes

from cryptography.hazmat.primitives.asymmetric import padding

from Crypto.PublicKey import RSA

from Crypto.Cipher import PKCS1_v1_5

from cryptography.hazmat.backends import default_backend

from cryptography.hazmat.primitives import serialization

encrypted = 'gBTI3T5KP8CG23_DLM7lVo9--pEQcoHaL2YxuhHqmv_guahHuOeDPQQiV3-yxXK4JXacIjqv7BL7QpTzq9v8HyK4P_f0PYFTH4RjnM_IYnAQPZt0ey2m2ckkvfuuAqeXvPEFoQtPfLPqqAokYzhH2O5K-VYth0tfTEjWGGNH7ukQjcjh3fUDneFBH4MVYuzGACRtG3gPTvCHnAuzAkA6UWfErXbh-17ZsBxpw-9wdcRtJ2DTE8rOZcpcT4NwXtURLDL6fl3eXaQFQA6BMZ2k1Iv19zjUD7WyN6NUZwQYdtMBq3PUMBd-uMNmB8YEb9sV4fEixbiZIS4j0y2gFCf0JrZXq7n9Jtv7_WTL0_jxoeysVauc2u3rc31jRtzHS6m1vTlg4qAcq390nk4m_QJyLq1RrvsWnyg6HjVpjSwSCEgZj441WWENWAaH0Tb2JhWosu53eiRTbjGivAKa0SUxpYW6b85DqW9jmYs9D9JrMwzVllmF6KaFa6lL3C97VZGmPZChUihqCvzp8tpxx7EPuPXloyFJaH3_oMW8PgQL0uBuCLfFt5pdxAp4QqEOe_z19IS27PSdJfFwZrk8DM3cLQEn__30EsnVC1e1fGrqz3Xh_Yvw-1kBZuer3YBpw43lIachaATy43EuVvM2gl1ppasBZQwMQWTWkJqrTyQBUmQ='

decoded = base64.urlsafe_b64decode(encrypted)

print('decode : ', decoded)

print('--------------- Started RSA Decryption ----------------------')

with open("./t2.pem", "rb") as key_file:

private_key = serialization.load_pem_private_key(

key_file.read(),

password=None,

backend=default_backend()

)

original_message = private_key.decrypt(

decoded,

padding.OAEP(

mgf=padding.MGF1(algorithm=hashes.SHA256()),

algorithm=hashes.SHA256(),

label="OAEP Encrypted"

)

)

print("RSA Decrypted Message",original_message)

print('--------------- Started AES Decryption ----------------------')

value = str(original_message)

key = b'1004063899047190'

value = base64.b64decode(value + '=' * (4 - len(value) % 4), '-_')

iv, value = value[:AES.block_size], value[AES.block_size:]

remainder = len(value) % 16

padded_value = value + '\0' * (16 - remainder)

cipher = AES.new(key, AES.MODE_CFB, iv, segment_size=128)

msg = cipher.decrypt(padded_value)[:len(value)]

print("message -- ",msg)


print("message -- ",msg)

尝试用Java代码“将加密的文本转换为RSA解密”时出现以下错误,

我已经尝试使用“ io.netty”,“ BouncyCastle”提供程序,apache BASE64,JavaUtil Base64 ..等等所有这些stufs。

package MMDemo.TarCopyJen2Master;

import java.io.BufferedReader;

import java.io.FileReader;

import java.io.IOException;

import java.security.GeneralSecurityException;

import java.security.KeyFactory;

import java.security.KeyPair;

import java.security.KeyPairGenerator;

import java.security.PrivateKey;

import java.security.PublicKey;
import java.security.Security;
import java.util.Base64;

import java.security.interfaces.RSAPrivateKey;

import java.security.spec.MGF1ParameterSpec;

import java.security.spec.PKCS8EncodedKeySpec;

import javax.crypto.Cipher;

import javax.crypto.SecretKey;

import javax.crypto.spec.OAEPParameterSpec;

import javax.crypto.spec.PSource;

import javax.crypto.spec.SecretKeySpec;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class PublickeyTest1 {

    public static void main(String[] args) throws Exception {

        Security.addProvider(new BouncyCastleProvider());
        String rsaEncrypted1 = "gBTI3T5KP8CG23_DLM7lVo9--pEQcoHaL2YxuhHqmv_guahHuOeDPQQiV3-yxXK4JXacIjqv7BL7QpTzq9v8HyK4P_f0PYFTH4RjnM_IYnAQPZt0ey2m2ckkvfuuAqeXvPEFoQtPfLPqqAokYzhH2O5K-VYth0tfTEjWGGNH7ukQjcjh3fUDneFBH4MVYuzGACRtG3gPTvCHnAuzAkA6UWfErXbh-17ZsBxpw-9wdcRtJ2DTE8rOZcpcT4NwXtURLDL6fl3eXaQFQA6BMZ2k1Iv19zjUD7WyN6NUZwQYdtMBq3PUMBd-uMNmB8YEb9sV4fEixbiZIS4j0y2gFCf0JrZXq7n9Jtv7_WTL0_jxoeysVauc2u3rc31jRtzHS6m1vTlg4qAcq390nk4m_QJyLq1RrvsWnyg6HjVpjSwSCEgZj441WWENWAaH0Tb2JhWosu53eiRTbjGivAKa0SUxpYW6b85DqW9jmYs9D9JrMwzVllmF6KaFa6lL3C97VZGmPZChUihqCvzp8tpxx7EPuPXloyFJaH3_oMW8PgQL0uBuCLfFt5pdxAp4QqEOe_z19IS27PSdJfFwZrk8DM3cLQEn__30EsnVC1e1fGrqz3Xh_Yvw-1kBZuer3YBpw43lIachaATy43EuVvM2gl1ppasBZQwMQWTWkJqrTyQBUmQ=";
        PrivateKey privateKey = getPrivateKey("D:/Infosys/Decrpyt/EncryptDec/private_key.pem");
        String rsaDecrypted = decrypt(rsaEncrypted1, privateKey);
        System.out.println("RSA Decrypted Text == " + rsaDecrypted);
    }

    public static String decrypt(String cipherText, PrivateKey privateKey)
            throws IOException, GeneralSecurityException {
        byte[] decodedCipherText = Base64.getUrlDecoder().decode(cipherText);

        System.out.println("Decoded Cipher text == " + decodedCipherText.toString());

        OAEPParameterSpec oaepParams = new OAEPParameterSpec(

                "SHA-256", "MGF1", new MGF1ParameterSpec("SHA-256"), PSource.PSpecified.DEFAULT);

        Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");

        cipher.init(Cipher.DECRYPT_MODE, privateKey);

        // cipher.init(Cipher.DECRYPT_MODE, privateKey);

        System.out.println("algo " + cipher.getAlgorithm());

        System.out.println("cipherText == " + cipherText);

        return new String(cipher.doFinal(decodedCipherText), "UTF-8");

    }

    private static String getKey(String filename) throws IOException {

        // Read key from file

        String strKeyPEM = "";

        BufferedReader br = new BufferedReader(new FileReader(filename));

        String line;

        while ((line = br.readLine()) != null) {

            strKeyPEM += line;// + "n";

        }

        br.close();

        return strKeyPEM;

    }

    public static RSAPrivateKey getPrivateKey(String filename) throws IOException, GeneralSecurityException {

        String privateKeyPEM = getKey(filename);

        System.out.println("PrivateKeyPem == " + privateKeyPEM);

        return getPrivateKeyFromString(privateKeyPEM);

    }

    public static RSAPrivateKey getPrivateKeyFromString(String key) throws IOException, GeneralSecurityException {

        String privateKeyPEM = key;

        // Remove the first and last lines

        privateKeyPEM = privateKeyPEM.replace("-----BEGIN RSA PRIVATE KEY-----", "");

        privateKeyPEM = privateKeyPEM.replace("-----END RSA PRIVATE KEY-----", "");

        privateKeyPEM = privateKeyPEM.replace("-----BEGIN PRIVATE KEY-----", "");

        privateKeyPEM = privateKeyPEM.replace("-----END PRIVATE KEY-----", "");

        System.out.println("privatekey pem after removal == " + privateKeyPEM);

        byte[] encoded = Base64.getDecoder().decode(privateKeyPEM); // for util base64

        KeyFactory kf = KeyFactory.getInstance("RSA");

        RSAPrivateKey privKey = (RSAPrivateKey) kf.generatePrivate(new PKCS8EncodedKeySpec(encoded));

        System.out.println("RSA Private Key after encoded: " + privKey);
        return privKey;

    }

}

这是我在尝试将加密的文本转换为RSA解密时遇到的错误。

Exception in thread "main" javax.crypto.BadPaddingException: Decryption error
    at sun.security.rsa.RSAPadding.unpadOAEP(RSAPadding.java:502)
    at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:296)
    at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:363)
    at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:389)
    at javax.crypto.Cipher.doFinal(Cipher.java:2164)
    at com.infy.rsaaes.RSAAESEncryptDecrypt.PublickeyTest1.decrypt(PublickeyTest1.java:129)
    at com.infy.rsaaes.RSAAESEncryptDecrypt.PublickeyTest1.main(PublickeyTest1.java:79)

在这里,我给了私钥(PEM)文件格式来解密文本。

-----BEGIN PRIVATE KEY-----

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

-----END PRIVATE KEY-----

如果我们在该python代码中使用相同的密钥,它将起作用。 有人可以帮忙吗?

1 个答案:

答案 0 :(得分:0)

正如评论中已经提到的,填充有问题:

  • 尽管创建了一个OAEPParameterSpec实例(oaepParams),但没有在任何地方使用它! oaepParams必须作为Cipher#init调用中的第三个参数传递。

  • OAEP使用 label ,默认情况下它是一个空字节数组(PSource.PSpecified.DEFAULT)。尽管这很不常见,但是Python代码并未使用该默认值(即空字节数组),而是使用了自定义字节序列(更确切地说,是字符串OAEP Encrypted,采用UTF-8编码)。因此,在OAEPParameterSpec中- 构造函数调用PSource.PSpecified.DEFAULT必须替换为new PSource.PSpecified("OAEP Encrypted".getBytes(StandardCharsets.UTF_8))

有关OAEP和PSource.PSpecified的详细说明,请参见herehere。如果两个错误均已修复,则Java代码的RSA解密与Python代码(UQQtMe0oUzkguQLzvcBcJMAvmsx2XWU6G-CMZtV1dR0qtu2LXwE=)相对应。顺便说一下,Java代码仅包含Python代码的RSA解密部分。