Skip to Main Content

Java Security

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Interested in getting your voice heard by members of the Developer Marketing team at Oracle? Check out this post for AppDev or this post for AI focus group information.

RSA BadPaddingException when decrypting

abdou-bouleghMay 13 2014

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

Comments

Processing
Locked Post
New comments cannot be posted to this locked post.

Post Details

Locked on Jun 10 2014
Added on May 13 2014
0 comments
1,146 views