Java中使用ECC加密图像

时间:2019-05-20 23:34:41

标签: java image encryption elliptic-curve

我想用ECC加密图像,我尝试使用Bouncy Castle,但是它不能单独加密每个像素,我在这里的另一个问题中询问了它 在stackoverflow中,答案是在没有B ** C的情况下实现ECC。 所以我搜索了ECC并发现:

椭圆曲线密码学由三个不同的部分组成 操作:

1_密钥生成:

  • 我们需要一个point G,也称为生成器点。
  • 一个大整数nB被保留为私钥。
  • ,点PB = nB * G被声明为公共点。 -将纯文本消息映射到椭圆曲线上的一个点(为此, 每个像素并将其乘以G)。

2_加密:

  • 发件人选择一个random positive integer k

  • 然后使用公钥PB生成由以下组成的密码点Cm 两点。 Cm = [{k G}, {Pm +(k PB)}]

3_解密:

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

问题是当映射像素并对其进行加密时,结果是一个重点,即如何从中获取加密像素的值, 这样我就可以创建新图像了吗?我以正确的方式实施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());
        } 

        }

问题是在最后一个“ for”中,它映射像素并对其进行加密,但不知道如何将 像素中的cryptonedpixel来创建新图像。

1 个答案:

答案 0 :(得分:1)

  

我以正确的方式实施ECC吗?

绝对不是,您甚至都没有正确理解 ECC的方法。

ECC与RSA确实没有真正的加密操作。有ElGamal加密,但是因为ECC在如此小的顺序字段上运行,所以没有很好的加密方案与之兼容。除此之外,它还会扩展一条消息,例如10字节到64字节-只有在采取非常宽松的方法正确填充消息后,才能安全操作。因此,如果您使用直接ECC加密,则图像将增长6.4倍。

正如James所提到的,有一种叫做ECIES的东西,它基本上使用DH派生一个对称密钥,将带有消息的本地公钥发送出去,然后销毁临时私钥。然后,接收者可以使用其私钥和公钥导出相同的对称密钥。然后,可以使用此特定于消息的派生密钥来对消息(即像素数据)进行加密/解密,例如使用AES-CTR,它没有任何开销(IV除外,但是由于您拥有随机数据密钥,因此您可以可以使用静态IV / nonce,例如全零)。

不幸的是,这仍然会使您拥有公共密钥来存储在消息旁边。