Programmer
Programmer

Reputation: 1

File Encryption Using RSA

I'm trying to implement RSA algorithm. I want to encrypt an image. The problem is when the decrypt is finished, the file can't be read. I don't know where is the problem exactly. This is the implementation of RSA:

import java.awt.image.BufferedImage;
import java.math.BigInteger;
import java.util.Random;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;


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 Random r;
 public RSA() {
    r = new Random();
    p = BigInteger.probablePrime(bitlength, r);
    q = BigInteger.probablePrime(bitlength, r);
    N = p.multiply(q);

    phi =   p.subtract(BigInteger.ONE).multiply(q.subtract(BigInteger.ONE));
    e = BigInteger.probablePrime(bitlength/2, r);
    System.out.println("e : "+e);

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

This is the main method:

 public static void main (String[] args) throws IOException
       {

RSA rsa = new RSA();   

      byte[] bytesImage= rsa.readBytesFromFile(new File(
            "F:\\calla.jpg"));
      //readBytesFromFile: method to read file as bytes


 byte[] encrypted = rsa.encrypt(bytesImage);    
     writeBytesToFile(new File(
            "F:\\encryptedcalla.jpg"),encrypted );
  //writeBytesToFile: method to write as bytes

// decrypt
    byte[] decrypted = rsa.decrypt(encrypted); 
     writeBytesToFile(new File(
            "F:\\decryptedcalla.jpg"),decrypted );


}

This is the method of encryption:

    // Encrypt image
 public byte[] encrypt(byte[] image) {   
     byte[] encryptedImage = new byte[image.length];
    for (int i =0 ; i< image.length; i++){
        encryptedImage[i]= (BigInteger.valueOf(image[i])).modPow(e, N).byteValue(); 

     }   
      return encryptedImage;
}

This is the method of decryption:

 public byte[] decrypt(byte[] image) {   
    byte[] decryptedImage = new byte[image.length];
    for (int i =0 ; i< image.length; i++){
        decryptedImage[i]= (BigInteger.valueOf(image[i])).modPow(d, N).byteValue();

     } 

     return decryptedImage;

} 

The methods of reading and writing are described here: http://www.java2s.com/Code/Java/File-Input-Output/Readfiletobytearrayandsavebytearraytofile.htm

Upvotes: 0

Views: 2008

Answers (1)

Solomon Slow
Solomon Slow

Reputation: 27115

The problem is, as you say, in this step:

encryptedImage[i]= (BigInteger.valueOf(image[i])).modPow(e, N).byteValue();

The problem is, that modPow() is returning a 1024-bit number, and you are trying to stuff that into an 8-bit byte. You can't do that without losing some information, and if you lose any information, then you won't be able to decrypt the message.

RSA is mathematical cryptography: You have to encode your message as a number, then you encrypt by computing a function that turns that number into a different number (that's the modPow(e, N)). Then you have to transmit the whole encrypted message number.

The recipient of the message takes the encrypted number and runs it through the decryption function modPow(d, N) which should give back the original number, and then that can be transformed back into the original message.

But the recipient has to get the whole 1024-bit number in order for the decryption to work.

If you use RSA to encrypt each individual byte of the image, then for each byte in to the encryption algorithm, you will have to send a 1024-bit packet to the recipient. Then the recipient can decrypt that packet, and extract the original byte.

Or, you could encrypt two bytes at a time, or ten bytes, or 100 bytes; but what you can't do is make the "packets" any smaller than 1024 bits.

Upvotes: 1

Related Questions