RSA/ECB/OAEPWithSHA-512AndMGF1Padding 在 Python 中使用私钥

RSA/ECB/OAEPWithSHA-512AndMGF1Padding Using private key in Python

提问人:Freest 提问时间:11/15/2023 最后编辑:Freest 更新时间:11/15/2023 访问量:96

问:

我需要在 Python 中实现 RSA/ECB/OAEPWithSHA-512AndMGF1Padding 加密。我有可用的 Java 代码,需要兼容的 Python 代码。

必须使用私钥对数据进行加密。

Java 加载键方法:

private static RSAPrivateKey buildRsaPrivateKey(String key) throws NoSuchAlgorithmException, InvalidKeySpecException {
    String privateKeyPEM = key
        .replace("-----BEGIN PRIVATE KEY-----", "")
        .replaceAll(System.lineSeparator(), "")
        .replace("-----END PRIVATE KEY-----", "");
    byte[] decoded = Base64.getDecoder().decode(privateKeyPEM);
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decoded);
    return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
}

Java 加密方法:

private static byte[] encryptRsa(byte[] data, RSAPrivateKey privateKey) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException {
    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-512AndMGF1Padding");
    cipher.init(Cipher.ENCRYPT_MODE, privateKey, new OAEPParameterSpec("SHA-512", "MGF1", new MGF1ParameterSpec("SHA-512"), PSource.PSpecified.DEFAULT));
    byte[] result = cipher.doFinal(data);
}

Java 解密:

private static RSAPublicKey buildRsaPublicKey(String key) throws NoSuchAlgorithmException, InvalidKeySpecException {
    String publicKeyPEM = key
        .replace("-----BEGIN PUBLIC KEY-----", "")
        .replaceAll(System.lineSeparator(), "")
        .replace("-----END PUBLIC KEY-----", "");
    byte[] decoded = Base64.getDecoder().decode(publicKeyPEM);
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decoded);
    return (RSAPublicKey) keyFactory.generatePublic(keySpec);
}

private static byte[] decryptRsa(byte[] data, RSAPublicKey publicKey) throws NoSuchPaddingException, NoSuchAlgorithmException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException, InvalidAlgorithmParameterException {
    Cipher cipher = Cipher.getInstance(CIPHER_TRANSFORMATION);
    cipher.init(Cipher.DECRYPT_MODE, publicKey, new OAEPParameterSpec("SHA-512", "MGF1", new MGF1ParameterSpec("SHA-512"), PSource.PSpecified.DEFAULT));
    return cipher.doFinal(data);
}

变式1:

def encrypt_rsa2(data, private_key):
    from Crypto.Cipher import PKCS1_OAEP, PKCS1_v1_5
    from Crypto.PublicKey import RSA
    from Crypto.Hash import SHA512
    from Crypto.Signature.pss import MGF1
    private_key = RSA.importKey(private_key)
    rsa_cipher = PKCS1_OAEP.new(
        private_key,
        hashAlgo=SHA512.new(),
        mgfunc=lambda x, y: MGF1(x, y, SHA512.new()),
    )
    rsa_cipher_text = rsa_cipher.encrypt(data)
    return rsa_cipher_text

变式2:

def encrypt_rsa(data, private_key_str):
    from cryptography.hazmat.backends import default_backend
    from cryptography.hazmat.primitives import hashes
    from cryptography.hazmat.primitives.asymmetric import padding
    from cryptography.hazmat.primitives.serialization import load_pem_private_key

    private_key = load_pem_private_key(
        private_key_str,
        password=None,
        backend=default_backend()
    )
    encrypted = private_key.public_key().encrypt(
        data,
        padding.OAEP(
            mgf=padding.MGF1(hashes.SHA512()),
            algorithm=hashes.SHA512(),
            label=None,
        )
    )
    return encrypted

这两种变体都会生成客户端无法解密的数据。

python 加密 加密 aes pycrypto

评论

1赞 Topaco 11/15/2023
对于加密,必须使用公钥。实际上没有使用私钥加密这样的东西,并且在库中(尤其是跨平台)中没有一致地实现,这可能就是它不起作用的原因。
1赞 Topaco 11/15/2023
除此之外,请不要在评论中发布代码,因为它很难阅读,而是编辑您的问题并将其放在那里。
1赞 Topaco 11/15/2023
您的 Java 代码对 OAEP: 根本不起作用。它仅适用于 PKCS#1 填充:jdoodle.com/ia/QJwInvalidKeyException: OAEP cannot be used to sign or verify signatures
1赞 Topaco 11/15/2023
@MarkRotteveel - ...有类似使用私钥加密的东西......我尽量避免使用这种措辞。正如您已经解释的那样,公钥的机密性和解密在术语上是矛盾的。但是,该表述也不适合作为手语的同义词,因为它没有考虑到两种语境中的不同填充,因此经常导致误解(教科书 rsa 除外,但对于具有相当学术重要性的实践来说,这是一个无关紧要的变体)。
1赞 President James K. Polk 11/15/2023
如果它适用于 Bouncycastle 提供程序,那么我认为这是 Bouncycastle 中的一个错误,而不是一个功能。

答: 暂无答案