Forum Stats

  • 3,838,708 Users
  • 2,262,394 Discussions
  • 7,900,739 Comments

Discussions

RSA BadPaddingException when decrypting

I am encrypting some bytes of data On a java smart card using a public key i generated on a desktop app, but when i try to decrypt the data on my desktop i get the `BadPaddingException :  Data must start with zero`, I read that this might be caused by the use of a false private key to decrypt the data, please bare with me as i explain the steps i went through, if anyone has a better solution of course i'm all ears.

1. First of all i generated a public/private key pair on a desktop app and loaded them on the smart card using the following code ( being generated in BigInteger type, I converted them to hexadecimal, and from hexa decimal to a byte array ) :

        void keyGen(String ID)throws Exception{

            // where ID is the name of the user

            KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");

            kpg.initialize(512);

            KeyPair kp = kpg.genKeyPair();

            this.pubKey = (RSAPublicKey) kp.getPublic();

            this.privKey = (RSAPrivateKey) kp.getPrivate();

          

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

            this.pub = fact.getKeySpec(kp.getPublic(), RSAPublicKeySpec.class);

            this.priv = fact.getKeySpec(kp.getPrivate(),  RSAPrivateKeySpec.class);

          

            saveToFile(ID+".pub", pub.getModulus(),  pub.getPublicExponent());

            saveToFile(ID+".priv", priv.getModulus(),  priv.getPrivateExponent());

          

        }

here is the savetofile function :

        public void saveToFile(String fileName,  BigInteger mod, BigInteger exp) throws IOException {

              ObjectOutputStream oout = new ObjectOutputStream(

                new BufferedOutputStream(new FileOutputStream(fileName)));

              try {

                oout.writeObject(mod);

                oout.writeObject(exp);

              } catch (Exception e) {

                throw new IOException();

              } finally {

                oout.close();

              }

            }

this is the line used to store the public key on the smart card :

    Main.sRmi.setPub(Crypto.hexStringToByteArray(Main.crypto.getPubMod().toString(16)),

     toByteArray("0"+Main.crypto.getPubexp().toString(16)));

( The zero is added to the string because we cannot convert a string of odd hexadecimals into bytes )

2. Then I try to encrypt the data using that public key inside the card, and this is the function i'm using :

        private Cipher cipherRSA = Cipher.getInstance(Cipher.ALG_RSA_PKCS1, false);

        private byte[] cipherText = new byte[64];

  

        public byte[] encrypt(byte[] clearText){

          

            cipherRSA.init(rsa_PublicKey, Cipher.MODE_ENCRYPT);

            cipherRSA.doFinal(clearText, (short)0,  (short)clearText.length,cipherText, (short)0 );

            return cipherText;

        }

3. Then I try to get this encrypted value on another desktop application, and decrypt it using the private key i'm reading from the file :

This is how I read the private key from the file :

    public void init (String ID ) throws FileNotFoundException, IOException, Exception{

      

        Object o[] = openFile(ID+".pub");

        setPubMod((BigInteger) o[0]);

        setPubexp((BigInteger) o[1]);

        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(this.pubMod, this.pubexp);

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

        pubKey = (RSAPublicKey) fact.generatePublic(keySpec);

        o = openFile(ID+".priv");

        setPrivMod((BigInteger) o[0]);

        setPrivexp((BigInteger) o[1]);

        RSAPrivateKeySpec keySpec1 = new RSAPrivateKeySpec(this.privMod, this.privexp);

        fact = KeyFactory.getInstance("RSA");

        privKey = (RSAPrivateKey) fact.generatePrivate(keySpec1);

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

        cipher.init(Cipher.ENCRYPT_MODE, pubKey);

    }

After getting the private key in the BigInteger Variable, I decrypt using the following method :

    public byte[] rsaDecrypt(byte[] data) throws Exception, BadPaddingException {

        

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

          cipher.init(Cipher.DECRYPT_MODE, privKey);

          byte[] clearData = cipher.doFinal(data);

          return clearData;

        }

To sum it all up, I create a key pair in BigInteger Format, I save the BigInteger Variable into a Serialized array of two BigIntegers to be used by the other desktop App, then I convert them into Hexa String, then into an array of bytes which i put inside the smart card.

Can anyone please tell me what's wrong with this procedure ? is it too much ? is there a better way to do so ? Thank you

If you need anymore Information please let me know.

**EDIT : **

I think i know where the problem is, it's with the key stored inside the smart card, converting it the way I did obviously is not working, seing how i read it from the card and printed it out and got

a completely different result, so the question is now, how do i export successfully a public key created on java.crypto ( in BigInteger) to the Smart card where public keys are stored in Bytes ?

I found this :

Sets the public exponent value of the key. The plaintext data format is big-endian and right-aligned (the least significant bit is the least significant bit of last byte). Input exponent data is copied into the internal representation.

so how can i convert a big integer to this big-endian byte format ? thank you

Tagged:
This discussion has been closed.