0

I found this rsa code on net. I have problem with code, it is not working as expected for the larger text. However it decrypts fine for a few lines text. Can anyone point out the mistake it the code or logic please. Thanks

import java.math.BigInteger;  
import java.util.Random; 
import java.io.*; 
/**
*
* @author Mohtashim
*/
public class RSA {  

    private BigInteger p;  
    private BigInteger q;  
    private BigInteger N;  
    private BigInteger phi;  
    private BigInteger e;  
    private BigInteger d;  
    private int bitlength = 1024;  
    private int blocksize = 128; //blocksize in byte  

    private Random r;  
    public RSA() {  
        r = new Random();  
        p = BigInteger.probablePrime(bitlength, r);  
        q = BigInteger.probablePrime(bitlength, r); 

        long startTime= System.nanoTime();
        N = p.multiply(q);  
        phi = p.subtract(BigInteger.ONE).multiply(q.subtract(BigInteger.ONE));  
        long endTime= System.nanoTime();
        System.out.println((endTime-startTime)/1000);
        e = BigInteger.probablePrime(bitlength/2, r);  

        while (phi.gcd(e).compareTo(BigInteger.ONE) > 0 && e.compareTo(phi) < 0 ) {  
            e.add(BigInteger.ONE);  
        }     
        d = e.modInverse(phi);   

        System.out.println("p    : " + p);
        System.out.println("q    : " + q);
        System.out.println("phiN : " + N);
        //System.out.println("gcd  : " + gcd);
        System.out.println("e  : " + e);
        System.out.println("d    : " + d);   
    } 
    private static String bytesToString(byte[] encrypted) {  
        String test = "";  
        for (byte b : encrypted) {  
            test += Byte.toString(b);  
        }  
        return test;  
    }       
    public RSA(BigInteger e, BigInteger d, BigInteger N) {  
        this.e = e;  
        this.d = d;  
        this.N = N;  
    }  

    public byte[] encrypt(byte[] message) {       
        return (new BigInteger(message)).modPow(e, N).toByteArray();  
    }  

    public byte[] decrypt(byte[] message) {  
        return (new BigInteger(message)).modPow(d, N).toByteArray();  
    }  

    public static void main(String[] args) throws IOException {
        // TODO code application logic here
        RSA objRSA;
        objRSA = new RSA();
        int intC=0;

        byte[] encrypted = objRSA.encrypt("hello bhai jan kia haal hein aaq k hyl".getBytes());
        String decrypted = new String (objRSA.decrypt(encrypted));
        System.out.println("encrypted: "+ encrypted);
        System.out.println("decrypted: "+ decrypted);         
    }

}
David
  • 63
  • 1
  • 10
  • 2
    Look at this, it may explain why you experience problems with bigger cleartext: http://stackoverflow.com/questions/11822607/what-rsa-max-block-size-to-encode – mwhs May 07 '14 at 11:59
  • 1
    "It is not working as expected" is a very vague term, if you face an error always paste the error message, if your code behaves different than expected, always make clear what you expected and what the code actually did, so we can help you – LionC May 07 '14 at 12:04
  • 1
    I think his problem is the wrong understanding of how to use RSA. It should only be used as a building block in a crypto protocol, not as the algo to encrypt the entire payload. The code above works as expected. The problem is the user :-) – mwhs May 07 '14 at 12:06
  • 1
    "textbook" RSA cannot encrypt anything larger then the modulus (it's modular exponentiation, so this should not be a surprise). Secure modes of RSA (e.g. OAEP) specify padding, adding an additional overhead to be subtracted from the maximum size of the message. – Maarten Bodewes May 07 '14 at 13:37
  • @owlstead This time it's you with the answer-as-comment ;) Did I infect you? – CodesInChaos May 07 '14 at 20:05
  • @CodesInChaos You got me there, posted as an answer instead - I'm a bit flabbergasted that you found this one comment-that-should-have been-answer though. You did not write a spider to look for it, I hope? :) – Maarten Bodewes May 07 '14 at 21:52
  • @LoinC message gets decrypted wrongly and does not through any exception i.e it shows decrypted message as it is still encrypted – David May 08 '14 at 08:11
  • So the answer is that RSA should not be used to encrypt huge amount of data but only key? – David May 08 '14 at 08:11

1 Answers1

2

Generic answer

"textbook" RSA cannot encrypt anything larger than the modulus (it's modular exponentiation, so this should not be a surprise). Secure modes of RSA - for instance OAEP - use padding, creating an additional overhead. So this overhead needs to be subtracted from the size of the modulus to get the maximum size of the message that can be encrypted. Raw or textbook RSA (just modular exponentiation) is not secure; a secure padding mode such as OAEP is required.

To solve this issue you should use hybrid encryption for practical purposes. Note that you should not simply split the plaintext into block sized parts and encrypt those except for practice purposes.

For practice purposes only

As long as you keep the input of raw / textbook RSA smaller than the modulus you should be fine. This may mean that you'd have to rebase or split your data elements (e.g. use US-ASCII or values 0..25 for letters instead of UTF-16 which uses two bytes for each character).

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263