1

I make encryption on python and try to decrypt it on Java, but always get decryption error

I have part of code for encrypt and decrypt message in JAVA encoded in RSA For decrypt:

import java.security.*;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import javax.crypto.Cipher;

public class Decrypter
{
    public static void main(String[] args)
    {

        try {
            String encoded_data = "PueF1RC5giqmUK9U+X80SwjAjGmgfcHybjjQvWdqHSlua1rv6xr7o6OMutHBU+NRuyCJ3etTQssYOMGiWPITbEC8xr3WG9H9oRRnvel4fYARvQCqsGmf9vO9rXcaczuRKc2zy6jbutt59pKoVKNrbonIBiGN1fx+SaStBPe9Jx+aZE2hymDsa+xdmBSCyjF30R2Ljdt6LrFOiJKaDiYeF/gaej1b7D8G6p0/HBPxiHMWZhx1ZfylSvZ6+zyP0w+MJn55txR2Cln99crGtcdGeBDyBtpm3HV+u0VlW7RhgW5b+DQwjQ/liO+Ib0/ZIPP9M+3sipIwn2DKbC45o0FZHQ==";
            byte[] decodeData = Base64.getDecoder().decode(encoded_data);

            String publicKeyString = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxzN2+mrQRXKshq3k0r06" +
                    "0/FoWafOCl6fCCyuu/7SejNU95SN2LZyopA3ipamY5MeK1G1XHOhEfkPWcYcgUbz" +
                    "TdD166nqJGi/O+rNK9VYgfhhqD+58BCmLlNidYpV2iDmUZ9B/cvVsQi96GY5XOaK" +
                    "xuVZfwrDK00xcOq+aCojQEvMh+gry05uvzfSv9xK3ki5/iCMY62ReWlmrY0B19CQ" +
                    "47FuulmJmrxi0rv2jpKdVsMq1TrOsWDGvDgZ8ieOphOrqZjK0gvN3ktsv63kc/kP" +
                    "ak78lD9opNmnVKY7zMN1SdnZmloEOcDB+/W2d56+PbfeUhAHBNjgGq2QEatmdQx3" +
                    "VwIDAQAB";
            KeyFactory kf = KeyFactory.getInstance("RSA");
            byte[] encodedPb = Base64.getDecoder().decode(publicKeyString);
            X509EncodedKeySpec keySpecPb = new X509EncodedKeySpec(encodedPb);
            PublicKey pubKey = kf.generatePublic(keySpecPb);


            Cipher cipherDecr = Cipher.getInstance("RSA");
            cipherDecr.init(Cipher.DECRYPT_MODE, pubKey);
            byte[] cipherDataDecr = cipherDecr.doFinal(decodeData);
            String result = new String(cipherDataDecr);
            System.out.println("result = "+result);
        }catch (Exception e){
            e.printStackTrace(System.out);
        }

    }
}

Unfortunately I can't make changes in this code, so all what I can is make changes in python part. This part work correctly. for check I use this code for encrypt:

import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import javax.crypto.Cipher;

public class Encrypter
{
    public static void main(String[] args)
    {
        try {   
            String data = "111111111222";
            String privateKeyString = "here is my privat key";

            byte [] encoded = Base64.getDecoder().decode(privateKeyString);
            System.out.println("encoded = "+encoded);

            java.security.Security.addProvider( new org.bouncycastle.jce.provider.BouncyCastleProvider());
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            KeySpec ks = new PKCS8EncodedKeySpec(encoded);
            RSAPrivateKey privKey = (RSAPrivateKey) keyFactory.generatePrivate(ks);
            System.out.println("privKey = "+privKey);

            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
            cipher.init(Cipher.ENCRYPT_MODE, privKey);

            byte[] cipherData = cipher.doFinal(data.getBytes());

            String card = Base64.getEncoder().encodeToString(cipherData);
            System.out.println("data = "+card);
        }catch (Exception e){
            e.printStackTrace(System.out);
        }

    }
}

And when I use result from Java code for encrypt and put this result to decrypt Java file - all work's great. I need same encryption part, but writing with python.

Part for encrypt with python

import base64
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5

data = '111111111222'
privat_key = 'here is my privat key'
key = RSA.importKey(privat_key)
cipher = PKCS1_v1_5.new(key)
encrypted_message = str(base64.b64encode(cipher.encrypt(base64.b64decode(data))), 'utf8')
print(encrypted_message)

So, questions is how I should encrypt message for correct decryption with on Java? I tried different libs (standard rsa, Pycrypto RSA, PKCS1_OAEP, PKCS1_v1_5) and nothing help me

P.S. I know about wrong way for use keys pair, but it is requirements of the external system

UPDATE:

Using new instance fetch me to the some result. I changed format as Maarten Bodewes said

Cipher cipherDecr = Cipher.getInstance("RSA/ECB/NoPadding");

decryption result: ����2����ٰoܬ���(�RM@�/���u*�d�{���w�b+���v�ݏ[�$�#��xJo�s��F1���X��}���1 ���������t%`�YA/��?� �ɼej�X�T�+6Y4D��!���

I can't read it, but it's not a Exception, it is good. Try to move this way

UPDATE:

I define that Java used RSA/ECB/PKCS1Padding as default. So I should use same in python

3
  • If you encrypt in your Python code, why do you assume that data is Base64 encoded? That's different from what you do in Java. Commented Apr 27, 2017 at 17:57
  • Could you decrypt in Java using "RSA/ECB/NoPadding", and base 64 encode the result, and put that into the question? It depends on the implementation which PKCS#1 padding (for signing or encryption) is used. Commented Apr 27, 2017 at 20:32
  • This python script is not first. I tried different libs in different ways to make it run. You can excchange base64 encoding cipher.encrypt(base64.b64decode(data)) with cipher.encrypt(data.encode()) Unfortunately it doesn't have effect on the decryption result Commented Apr 28, 2017 at 8:05

2 Answers 2

4

First of all I defined that java

Cipher cipher = Cipher.getInstance("RSA");

expanded in

Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");

or

Cipher cipher = Cipher.getInstance("RSA/None/PKCS1PADDING");

For RSA no different what is defined in second argument (None or ECB). RSA doesn't use it.

So I need add padding to my encryption in python. Unfortunately PyCrypto hasn`t PKCS1PADDING, so i can't encrypt with this padding.

Next step I found M2Crypto lib https://gitlab.com/m2crypto/m2crypto This fork worked for python3. just download and build it(instruction in repo)

Than I wrote this code and it works:

import M2Crypto

# read privat key
privatKey = M2Crypto.RSA.load_key('privat.key')
# encrypt plaintext using privat key
ciphertext = privatKey.private_encrypt(data.encode('utf-8'), M2Crypto.RSA.pkcs1_padding)

encrypted_message = str(base64.b64encode(ciphertext), 'utf8')
print(encrypted_message)

That's all. It works for me, and I believe, it can help u.

Sign up to request clarification or add additional context in comments.

2 Comments

If you encrypt with the private key then really, nobody can help you.
All what I need to understood is a difference between using RSA in java and python. As I said in topic, encryption with privat key was requrement of the external system
0

According to my code, Bouncy uses the padding for signature generation, so I presume that is what is different. You can perform a "raw" decrypt (modular exponentiation) and remove the padding yourself.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.