0

I use the following code to encrypt some data and I want to move the decryption code to a server so need to send the cipherData (which is a byte [] array ) to my server over REST

        BigInteger modulus = new BigInteger("blah");
        BigInteger exponent = new BigInteger("blah");

        RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, exponent);

        KeyFactory encryptfact = KeyFactory.getInstance("RSA");
        PublicKey pubKey = encryptfact.generatePublic(keySpec);

        String dataToEncrypt = "Hello World";

        /**
         * Encrypt data
         */
        Cipher encrypt = Cipher.getInstance("RSA");
        encrypt.init(Cipher.ENCRYPT_MODE, pubKey);
        byte[] cipherData = encrypt.doFinal(dataToEncrypt.getBytes());

        System.out.println("cipherData: " + new String(cipherData));

        /**
         * Decrypt data
         */
        BigInteger privatemodulus = new BigInteger("blah");
        BigInteger privateexponent = new BigInteger("blah");

        RSAPrivateKeySpec privateKeySpec = new RSAPrivateKeySpec(privatemodulus, privateexponent);

        PrivateKey privateKey = encryptfact.generatePrivate(privateKeySpec);

        Cipher decrypt = Cipher.getInstance("RSA");
        decrypt.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decData = decrypt.doFinal(cipherData);

        System.out.println(new String(decData));

This works fine.

I was hoping I could just create a new String with the cipherData as a parm

When I try this with the above example I get the following error

byte[] decData = decrypt.doFinal(new String(cipherData).getBytes());

javax.crypto.BadPaddingException: Data must start with zero
at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:308)
at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:255)
at com.sun.crypto.provider.RSACipher.a(DashoA13*..)
at com.sun.crypto.provider.RSACipher.engineDoFinal(DashoA13*..)
at javax.crypto.Cipher.doFinal(DashoA13*..)
at com.test.EncryptTest.main(EncryptTest.java:52)

Any ideas?

1 Answer 1

3

I was hoping I could just create a new String with the cipherData as a parm

No. cipherData is arbitrary binary data. It's not encoded text, which is what the various String constructors expect. (As an aside, you should almost never call the String.getBytes() or new String(byte[]) which don't specify an encoding. Always specify an appropriate encoding, which will depend on the situation.)

Either transmit the data as binary data instead of going through text at all, or use Base64 to safely encode the binary data as text first, then decode it from Base64 to binary again later before decrypting. There's a public domain Base64 encoder which is easy to use.

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

2 Comments

@user1177292: Yes, that would work fine - or see the link in my answer for another one which is just a single source file you can include in your project.

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.