如何在Java中使用ECC加密图像

时间:2019-05-11 10:36:08

标签: java image encryption elliptic-curve

我必须用ECC加密bmp图像,但是我发现这非常困难,尤其是当像素将映射到椭圆曲线上时,我一点也不了解。因此,我研究了其他选择并发现了ECIES。

我尝试使用bouncycastle在Java中实现它,但是它的工作原理是我的代码将图像加密为文件,但是我去加密了图像的像素并获得了新的加密图像,因此我可以计算出加密和未加密图像之间的PSNR。 我尝试单独加密每个像素,而不是创建加密图像,但是没有用。 是否有某些功能可以帮助我或不列颠哥伦比亚省的任何事情?或者我必须在没有它的情况下实现ECIES?

这是我尝试过的:

   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 个答案:

答案 0 :(得分:0)

似乎您在做出一些错误的假设,并且您可能想重新考虑/重新考虑您的方法。

  

以获取新的加密图像。然后计算主题之间的(PSNR)峰值信噪比

BMP图像格式不仅仅包含像素。如前所述,存在头元数据(大小,深度,...),如果您对整个文件进行加密,它将不再有意义(它将不再是bmp)。我想您可以创建新图像并在图像级别逐像素处理像素,而不仅仅是加密输入文件。例: https://www.dyclassroom.com/image-processing-project/how-to-get-and-set-pixel-value-in-java

int p = img.getRGB(x,y);
  

所以我研究了其他选项并找到了ECIES。

ECIES是一种混合方案,您可以查看以下针对ECIES加密的答案https://gist.github.com/amrishodiq/9821413  。输出将需要包含更多/其他信息,而不仅仅是像素,而且绝对不是您可以打开和比较的任何BMP。

混合加密方案假定数据是通过对称密码加密的(我不确定在这种情况下BC使用哪种密码,如果有人知道,请发表评论),其中加密密钥是使用ECC派生的。

因此,最后,您将比较由基础对称算法(例如aes256-cbc)加密的像素,该算法旨在提供与随机输出无法区分的输出。

  

必须使用ECC加密bmp图像

如果您要加密每个像素(假设您将每个像素表示为16位rgb),则ECC输出比输入数据长得多,因此将输入值直接映射到相同尺寸的输出并不容易(大小)