【问题标题】:How to encrypt image with ecc in java如何在java中使用ecc加密图像
【发布时间】:2019-05-11 10:36:07
【问题描述】:

我必须用ECC加密bmp图像,但我发现它非常困难,尤其是当像素将映射到椭圆曲线上时,我完全不明白。所以我研究了其他选择并找到了 ECIES。

我尝试使用 bouncycastle 在 java 中实现它,它可以工作,但问题是我的代码将图像加密为文件,但我去加密图像的像素并获得一个新的加密图像,这样我就可以计算加密和未加密图像之间的 PSNR。 我试图单独加密每个像素而不是创建加密图像,但没有奏效。 是否有一些功能可以帮助我或 BC 中的任何东西?或者我必须在没有它的情况下实现 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());
   }

【问题讨论】:

  • 当然不能读取——这就是加密的目的。在正确加密的文件中,如果没有事先解密,没有一个字节是可用的。因此,加密的 BMP 文件没有 BMP 头,也没有 BMP 数据。
  • 这是我让它可读的问题。我试图加密每个像素但它没有工作
  • 这没有任何意义。文件是加密的或可读的,但绝不会同时加密。编辑您的问题,准确描述您想要实现的目标以及为什么要这样做。
  • Tnx 给你的笔记。我编辑我的问题
  • 似乎您做了很多假设,这些假设可能是错误的,从而导致您采用错误的方法。你想达到什么目的?计算噪声比?

标签: java image encryption elliptic-curve


【解决方案1】:

您似乎做出了一些错误的假设,您可能需要重新考虑/重新考虑您的方法。

获取新的加密图像。然后计算主题间的(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 输出比输入数据长得多,因此将输入值直接映射到相同维度的输出并不容易(大小)

【讨论】:

  • 我用 AES 和 RC4 加密图像没有任何问题,我使用 img.getRGB(x,y) 加密每个像素,它可以工作并创建加密图像。但是对于 ECC,如果我加密每个像素,我将获得更长的输出(如您所说)并且无法创建加密图像。所以有什么我可以做的吗?BC 中的任何功能可以提供帮助?
  • @Chada 你主要是在要求错误的东西(没有图书馆可以帮助你)。 ECC 旨在加密/交换用于加密数据的加密密钥,而不是数据本身(尝试了解有关混合加密的更多信息,同样适用于 RSA)。从理论上讲,您可以制作一些任意映射,但这可能不是目的。
  • 我在这里迷路了。我一直在寻找 ecc 并找到了一些关于使用 ecc 加密图像的文档,例如(International Journal of Advance Research In Science 中使用椭圆曲线加密的图像加密和解密和工程)所以你能给我一些建议或一些可以帮助我的文件吗?我真的需要用 ecc 加密图像。
  • @Chada 我找到了paper,如果你想重复这个过程,我建议你自己实现算法(映射32x32块)。此选项可能无法在 BC(或其他地方)开箱即用,因为它会很慢并且阅读论文我看到作者忽略了很多导致密码不安全结果的事情。
  • 问题是我根本不了解映射过程。如何在 EC 中映射像素??如果你有一些关于它的论文?或者如果你能解释一下,我会很感激的
猜你喜欢
  • 2016-02-08
  • 1970-01-01
  • 1970-01-01
  • 2015-08-07
  • 1970-01-01
  • 2019-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多