1

I am working on a project where I need to show some encryption decryption over the RMI network. I am using RSA system for this. On decryption, my code is giving me the following error :

javax.crypto.BadPaddingException: Message is larger than modulus
    at sun.security.rsa.RSACore.parseMsg(RSACore.java:182)
    at sun.security.rsa.RSACore.crypt(RSACore.java:112)
    at sun.security.rsa.RSACore.rsa(RSACore.java:103)
    at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:355)
    at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:382)
    at javax.crypto.Cipher.doFinal(Cipher.java:2087)
    at Node.decryptData(Node.java:463)
    at Node.receiveMsgL(Node.java:451)
    at MiniServer.callLeaderR(MiniServer.java:89)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:322)
    at sun.rmi.transport.Transport$1.run(Transport.java:177)
    at sun.rmi.transport.Transport$1.run(Transport.java:174)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport.java:173)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:556)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:811)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:670)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)

This is my decryption code :

private void decryptData(String PrivateK,byte[] data) throws IOException {
        System.out.println("\n-------DECRYPTION STARTED----");
        byte[] descryptedData = null;

        try {
            PrivateKey privateKey = readPrivateKeyFromFile(PrivateK);
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            descryptedData = cipher.doFinal(data);
            System.out.println("Decrypted Data: " + new String(descryptedData));

        } catch (Exception e) {
            e.printStackTrace();
        }   

        System.out.println("------DECRYPTION COMPLETED-----");      
    }

I have tried using cipher.update(byte[] data) while encrypting. I have String data and I convert it to byte array using string.getByte() while encrypting. If I use update method, it gives me an error of IllegalBlockException that data cannot be larger than modulus.

Please help me out in this. I am unable to find the bug in my code.

user207421
  • 305,947
  • 44
  • 307
  • 483
user3606758
  • 11
  • 1
  • 1
  • 2
  • The RSA, especially in ECB mode ([ECB/PKCS5Padding](http://stackoverflow.com/questions/6258047/java-default-crypto-aes-behavior) is the default if you do not specify the full transformation string), is not really suited for encrypting large amounts of data. Can you switch to AES (AES/CTR/PKCS5Padding should be pretty good starting point) or are you required to use RSA only? – Oleg Estekhin May 06 '14 at 06:22
  • @OlegEstekhin: Iirc the ECB in RSA/ECB/* is only a dummy value that has to be placed there because the framework expects to find a mode. @ user36... Rsa all by itself is only able to encrypt a limited amount of data (depending on the key size, somewhere around 250bytes). It is also generally not recommended to encrypt your use data directly with RSA, but only exchange a symmetric key with it. What are your requirements exactly? Can you use SSL/TLS? – Perseids May 06 '14 at 06:41

1 Answers1

3

Asymmetric ciphers like RSA are designed to encrypt short data, typically an symmetric key, while large data is encrypted with symmetric block ciphers (which symmetric key will be exchanged with an asymmetric ciphers). There are really a lot of similar questions and answers on StackOverflow. This one is one provides quite good answer.

Community
  • 1
  • 1
divanov
  • 6,173
  • 3
  • 32
  • 51
  • @divanovPerseidsOleg I am only trying to encrypt small data like one word. It gives me the error when I just send a string "msg" which is very small. – user3606758 May 06 '14 at 15:30
  • You can do something like `assert data.length * 8 < ((RSAPrivateKey)privateKey).getModulus().bitLength();` in `decryptData()` to check the data length. – divanov May 06 '14 at 15:58