问题
I have to encrypt a bmp image with ECC, but I found it very difficult especially when the pixels will be mapped on the elliptic curve, I didn't understand it at all. So I researched other options and found ECIES.
I tried to implement it in java using bouncycastle, it works but the problem is that my code encrypt the image as a file ,but i went to encrypt the pixels of the image and get a new encrypted image so I can calculate the PSNR between the encrypted and the unencrypted images. I tried to encrypt every pixel alone than create the encrypting image but didn't work. Is there some function can help me or anything in BC?or do i have to implement ECIES without it?
This is what i tried:
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC", "BC");
ECNamedCurveParameterSpec curveParameterSpec = ECNamedCurveTable.getParameterSpec("secp384r1");
keyPairGenerator.initialize(curveParameterSpec, new SecureRandom());
KeyPair KeyPair = keyPairGenerator.generateKeyPair();
ECPublicKey publicKey = (ECPublicKey) KeyPair.getPublic();
ECPrivateKey privateKey = (ECPrivateKey) KeyPair.getPrivate();
javax.crypto.Cipher c1 = javax.crypto.Cipher.getInstance("ECIES", "BC");
javax.crypto.Cipher c2 = javax.crypto.Cipher.getInstance("ECIES", "BC");
c1.init(ENCRYPT_MODE, publicKey, new SecureRandom());
c2.init(DECRYPT_MODE, privateKey, new SecureRandom());
try{
File bmpFile = new File("C:\\Users\\acer\\Desktop\\py\\6.bmp");
BufferedImage image = ImageIO.read(bmpFile);
// to byte
ByteArrayOutputStream baos=new ByteArrayOutputStream();//length=32 bytes, though its size increases if necessary.
ImageIO.write(image, "bmp", baos );
byte[] b = baos.toByteArray();
byte[] cipherimage = c1.doFinal(b, 0, b.length);
byte[] plainimage = c2.doFinal(cipherimage, 0, cipherimage.length);
bmpFile=new File("C:\\Users\\acer\\Desktop\\py\\encryptedimage.bmp");
FileOutputStream fos = new FileOutputStream(bmpFile);
fos.write(cipherimage);
fos.flush();
fos.close();
bmpFile=new File("C:\\Users\\acer\\Desktop\\py\\decryptedimage.bmp");
FileOutputStream fos1 = new FileOutputStream(bmpFile);
fos1.write(plainimage);
fos1.flush();
fos1.close();
} catch (IOException e){
System.out.println(e.getMessage());
}
回答1:
Seems you are making some wrong assumptions and you may want to reconsider / rethink your approach.
to get a new encrypted image. Then calculate the(PSNR)peak signal-to-noise ratio between theme
BMP image format consists of more than just pixels. As already commented, there are header metadata (size, depth, ,...) which, if you encrypt the whole file, won't make sense anymore (it won't be any bmp) . I'd say you can create a new image and process a pixel by pixel on the image level, not just encrypting an input file. Example: https://www.dyclassroom.com/image-processing-project/how-to-get-and-set-pixel-value-in-java
int p = img.getRGB(x,y);
So I researched other options and found ECIES.
ECIES is a hybrid scheme, you may have a look at following answer for ECIES encryption https://gist.github.com/amrishodiq/9821413 . The output will need to contain more/other information than just pixels and it is definitely not any BMP you can just open and compare.
Hybrid encryption scheme assumes that data are encrypted by a symmetric cipher (I am not sure which is used by BC in this case, if someone knows, please comment), where the encryption key is derived using ECC.
So at the end you'd be comparing pixels encrypted by an underlying symmetric algorithm (e. g. aes256-cbc), where it is designed to provide output indistinguishable from random output.
have to encrypt a bmp image with ECC
If you would encrypt each pixel (lets assume you will represent every pixel as 16 bit rgb), the ECC output is much longer than the input data, so it's not easy to direcly map input values into output of the same dimension (size)
来源:https://stackoverflow.com/questions/56089485/how-to-encrypt-image-with-ecc-in-java