【问题标题】:RSA-AES Decryption Issue - javax.crypto.BadPaddingException: Decryption errorRSA-AES 解密问题 - javax.crypto.BadPaddingException:解密错误
【发布时间】:2019-05-07 00:58:30
【问题描述】:

我需要将 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.. 等所有这些东西尝试了很多东西。

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 代码中使用相同的键,它将起作用。 有人可以帮忙吗?

【问题讨论】:

  • 您的填充模式与 RSA 不匹配。复制/粘贴加密不起作用。

标签: java python encryption aes rsa


【解决方案1】:

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

  • 虽然创建了OAEPParameterSpec-instance (oaepParams),但它并没有在任何地方使用! oaepParams 必须作为 Cipher#init 调用中的第三个参数传递。

  • OAEP 使用默认为空字节数组 (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 解密部分。

【讨论】:

  • 非常感谢。它现在正在工作,发布更改以下行,`OAEPParameterSpec oaepParams = new OAEPParameterSpec("SHA-256", "MGF1", new MGF1ParameterSpec("SHA-256"), PSource.PSpecified.DEFAULT); ` to ` OAEPParameterSpec oaepParams = new OAEPParameterSpec("SHA-256", "MGF1", new MGF1ParameterSpec("SHA-256"), new PSource.PSpecified("OAEP Encrypted".getBytes(StandardCharsets.UTF_8))); ` 非常感谢。我们花了一周的时间来为这个问题设置这个标签。再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-18
  • 1970-01-01
相关资源
最近更新 更多