0

I want to encrypt an image with ECC, i tried using Bouncy Castle but it cant encrypt each pixel alone,and i asked about it in another question here in stackoverflow and the Answer was to implement ECC without B**C. So i searched about ECC and found:

Elliptic curve cryptography consists of three distinct operations:

1_ key generation:

  • we need a point G,also called as the generator point.
  • a large integer nB is kept as the Private Key.
  • and the point PB = nB * G is declared as public. -map the plaintext message to a point on the elliptic curve(for that i get each pixele and multiplying it with G).

2_ encryption:

  • the sender chooses a random positive integer k.

  • then uses the public key PB to generate the cipher point Cm that consists of two points. Cm = [{k G}, {Pm +(k PB)}].

3_ decryption:

C2 – nB * C1 = {Pm + (k * PB)}{nB * (k * G)}
                = Pm + k*(nB * G)nB * (k * G)
                = Pm

The problem is when mapping the pixel and encrypting it the result is a point,how to get the value of the encrypted pixel from it, so i can create the new image? i'm in the right way of implementing ECC??

   public static void main(String[] args) {
        try{

           X9ECParameters x9 = NISTNamedCurves.getByName("P-224"); 
           org.bouncycastle.math.ec.ECPoint g = x9.getG();
           BigInteger n = x9.getN();
           int nBitLength = n.bitLength();

           BigInteger privatekey;
           do{
                Random rand = new Random();
                privatekey = new BigInteger(nBitLength,rand);
           }
           while (privatekey.equals(ZERO)  || (privatekey.compareTo(n) >= 0));
                org.bouncycastle.math.ec.ECPoint publickey = g.multiply(privatekey); 

             BigInteger k;
             Random randk = new Random();
             k= new BigInteger(nBitLength,randk); 
            File bmpFile = new File("C:\\Users\\acer\\Desktop\\py\\6.bmp");
            BufferedImage image = ImageIO.read(bmpFile);
            int width           = image.getWidth();
            int height          = image.getHeight();

            BigInteger [][] pixels = new BigInteger [width][height];

            for( int i = 0; i < width; i++ )
                for( int j = 0; j < height; j++ )
                     pixels[i][j] = BigInteger.valueOf(image.getRGB( i, j ));

            org.bouncycastle.math.ec.ECPoint mappedpixel,encryptedpixel;

            for( int i = 0; i < width; i++ ){
                for( int j = 0; j < height; j++ ){
                    mappedpixel= g.multiply(pixels[i][j]);
                    encryptedpixel=mappedpixel.add(publickey.multiply(k));   

                }
            }     
        }
        catch (IOException e){
             System.out.println(e.getMessage());
        } 

        }

the problem is in the last 'for' it map the pixel and encrypt it but don't know how to put the value of encryptedpixel in the pixel to create the new image.

Chada
  • 3
  • 4

1 Answers1

2

I'm in the right way of implementing ECC?

Absolutely not, and you're not even going in the right way to understand ECC.

ECC doesn't really have an encryption operation the same way that RSA does. There is ElGamal encryption, but because ECC operates on such small order fields, no good encryption scheme is compatible with that. Besides that, it will expand a message of e.g. 10 bytes to 64 bytes - and that's only after taking a very liberal approach to padding the message correctly - something that is required for secure operation. So your image would grow by a factor 6.4 if you would use direct ECC encryption.

As James mentioned, there is something called ECIES which basically derives a symmetric key using DH, sending the local public key with the message, then destroying the temporary private key. The receiver can then derive the same symmetric key using his private key and the public key. This message specific derived key can then be used to encrypt / decrypt the message (i.e. pixel data), e.g.. using AES-CTR which doesn't have any overhead (other than the IV, but as you have a randomized data key, you can use a static IV/nonce of e.g. all zeros).

Unfortunately that will still leave you with the public key to store next to the message.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • I tried ecies with B**C but it encrypting all the image as a file not the pixels.and i have asked about it in here https://stackoverflow.com/questions/56089485/how-to-encrypt-image-with-ecc-in-java/56116415#comment98899367_56116415 – Chada May 21 '19 at 09:29
  • Well, yes, where to store the required overhead is an issue. However, ECIES is still the only way to perform this task. Trying to encrypt using any asymmetric algorithm without expanding the ciphertext is an exercise of futility: there is no practical asymmetric encryption without ciphertext expansion. That you encrypt the entire file rather than the pixels is of course an error in your implementation, rather than an issue with the idea. – Maarten Bodewes May 21 '19 at 15:40
  • So is there no way to encrypt an image with ecc?? – Chada May 21 '19 at 20:04
  • Not by implicitly mapping each pixel no, unless you want to expand your ciphertext and thus isage size by about 32 to 64 times. I don't know what to tell you other than the info in the answer. – Maarten Bodewes May 21 '19 at 21:33