【问题标题】:Can anyone tell what I did the mistake in image encryption and decryption process using RSA谁能告诉我在使用 RSA 的图像加密和解密过程中犯了什么错误
【发布时间】:2015-07-31 16:03:54
【问题描述】:

我已将图像分割成一定数量的子图像,并对每个子图像进行加密和解密处理。之后,我将所有加密字节存储到一个 jpg 文件中,并将解密字节存储到另一个 jpg 文件中。 但是我没有从解密文件和原始图像中获得相同的字节。 代码如下。

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigInteger;

import javax.imageio.ImageIO;
public class ImageSplitTest {
    private static final BigInteger N = null;
    public ImageSplitTest() {
        // TODO Auto-generated constructor stub
    }

    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub
        File file = new File("C:\\Users\\Shwetha\\workspace\\penguins.jpg"); // I have bear.jpg in my working directory  
        byte b[]=rsa1.readBytesFromFile(file);
        System.out.println("original image bytes"+ b);
        FileInputStream fis = new FileInputStream(file);  
        BufferedImage image = ImageIO.read(fis); //reading the image file  

        int rows = 2; //You should decide the values for rows and cols variables  
        int cols = 2;  
        int chunks = rows * cols;  

        int chunkWidth = image.getWidth() / cols; // determines the chunk width and height  
        int chunkHeight = image.getHeight() / rows;  
        int count = 0;  
        BufferedImage imgs[] = new BufferedImage[chunks]; //Image array to hold image chunks  
        for (int x = 0; x < rows; x++) {  
            for (int y = 0; y < cols; y++) {  
                //Initialize the image array with image chunks  
                imgs[count] = new BufferedImage(chunkWidth, chunkHeight, image.getType());  

                // draws the image chunk  
                Graphics2D gr = imgs[count++].createGraphics();  
                gr.drawImage(image, 0, 0, chunkWidth, chunkHeight, chunkWidth * y, chunkHeight * x, chunkWidth * y + chunkWidth, chunkHeight * x + chunkHeight, null);  
                gr.dispose();  
            }  
        }  
        System.out.println("Splitting done");  

        //writing mini images into image files  
        for (int i = 0; i < imgs.length; i++) {  
            ImageIO.write(imgs[i], "jpg", new File("img" + i + ".jpg"));  


        }  
        System.out.println("Mini images created");  
       rsa1 rsa=new rsa1();
        BufferedImage[] buffImages = new BufferedImage[chunks];  
        byte[] decrypted=null;
        byte[] bytesImage=null;
        for (int i = 0; i < imgs.length; i++) {  
         bytesImage= rsa.readBytesFromFile(new File(
                "img" + i + ".jpg"));
          //readBytesFromFile: method to read file as bytes


     byte[] encrypted = rsa.encrypt(bytesImage);    
         rsa.writeBytesToFile(new File(
                "C:\\Users\\Shwetha\\workspace\\encrypted.jpg"),encrypted );

      //writeBytesToFile: method to write as bytes

    // decrypt
         decrypted = rsa.decrypt(encrypted); 
        rsa. writeBytesToFile(new File(
                "C:\\Users\\Shwetha\\workspace\\decrypted1.jpg"),decrypted );
    }
     System.out.println("bytes from decryption"+decrypted);  
     System.out.println("bytes before encryption"+bytesImage);
}

}

readBytesFromFile、加密和解密方法存在于 rsa1 calss 中。

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.util.Random;

public class rsa1 {
    private BigInteger p;
    private BigInteger q;
    private BigInteger N;
    private BigInteger phi;
    private static BigInteger e;
    private BigInteger d;
    private int bitlength = 1024;

    private Random r;
     public rsa1() {
        r = new Random();
        p = BigInteger.probablePrime(bitlength, r);
        q = BigInteger.probablePrime(bitlength, r);
        N = p.multiply(q);

        phi =   p.subtract(BigInteger.ONE).multiply(q.subtract(BigInteger.ONE));
        e = BigInteger.probablePrime(bitlength/2, r);
        System.out.println("e : "+e);

        while (phi.gcd(e).compareTo(BigInteger.ONE) > 0 && e.compareTo(phi) < 0 ) {
            e.add(BigInteger.ONE);
        }
       d = e.modInverse(phi);
     }

    public byte[] encrypt(byte[] image) {   
       byte[] encryptedImage = new byte[image.length];
      for (int i =0 ; i< image.length; i++){
          encryptedImage[i]= (BigInteger.valueOf(image[i])).modPow(e, N).byteValue(); 

       }   
        return encryptedImage;
    }
    public byte[] decrypt(byte[] image) {   
       byte[] decryptedImage = new byte[image.length];
       for (int i =0 ; i< image.length; i++){
           decryptedImage[i]= (BigInteger.valueOf(image[i])).modPow(d, N).byteValue();

        } 

        return decryptedImage;

        }
    public static byte[] readBytesFromFile(File file) throws IOException {
        InputStream is = new FileInputStream(file);

           // Get the size of the file
           long length = file.length();

           // You cannot create an array using a long type.
           // It needs to be an int type.
           // Before converting to an int type, check
           // to ensure that file is not larger than Integer.MAX_VALUE.
           if (length > Integer.MAX_VALUE) {
             throw new IOException("Could not completely read file " + file.getName() + " as it is too long (" + length + " bytes, max supported " + Integer.MAX_VALUE + ")");
           }

           // Create the byte array to hold the data
           byte[] bytes = new byte[(int)length];

           // Read in the bytes
           int offset = 0;
           int numRead = 0;
           while (offset < bytes.length && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
               offset += numRead;
           }

           // Ensure all the bytes have been read in
           if (offset < bytes.length) {
               throw new IOException("Could not completely read file " + file.getName());
           }

           // Close the input stream and return bytes
           is.close();
           return bytes;
        // TODO Auto-generated method stub

     }


     }

谁能告诉我如何从解密的 jpg 文件或解密的字节中恢复我的原始图像。

【问题讨论】:

  • 特别是,如果你想测试你是否可以加密和解密任意数据,你绝对不需要任何图像处理代码......

标签: java encryption cryptography


【解决方案1】:

您在加密期间几乎丢弃了所有信息。如果您对单个字节的输入执行位大小为 1024 的 RSA,则结果将是 1024 位,而不是 8 位。因此,当您调用 byteValue() 时,您会丢弃包含重要信息的其他 1016 位。

当您使用教科书 RSA(只是模幂运算)时,您的解密方法不会注意到。它也会执行模幂运算,检索一些随机值,然后将其输入byteValue()

您应该阅读混合密码系统并使用 RSA OAEP 创建用于图像加密的安全协议。它目前的协议方式(包括安全性)存在致命缺陷。

【讨论】:

    猜你喜欢
    • 2010-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-30
    • 2011-02-24
    • 1970-01-01
    • 2021-02-25
    • 2018-05-06
    相关资源
    最近更新 更多