Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何通过DCT使用AES进行加密&;IDCT并将其解密回来?_Java_Android_Encryption_Dct - Fatal编程技术网

Java 如何通过DCT使用AES进行加密&;IDCT并将其解密回来?

Java 如何通过DCT使用AES进行加密&;IDCT并将其解密回来?,java,android,encryption,dct,Java,Android,Encryption,Dct,目前,我正在Android中进行图像加密和离散余弦变换(从概念上讲,它在中的工作应该几乎相同,但加密/解密步骤不同,并且没有洗牌步骤) 加密代码如下: 每个8x8块中的DCT 加密阵列坐标(0,0)处的DC值/低频值 将加密的字节转换为双数组 将第一个双精度数组保存到坐标(0,0) 将第二个双精度阵列保存到坐标(7,7) 执行IDCT 使用color.RGBA()函数将结果块从IDCT转换为RGBA颜色 把它和像素放在一起形成图像 解密本身: 每个8x8块中的DCT 从坐标(0,0)和(7,7)

目前,我正在Android中进行图像加密和离散余弦变换(从概念上讲,它在中的工作应该几乎相同,但加密/解密步骤不同,并且没有洗牌步骤)

加密代码如下:

  • 每个8x8块中的DCT

  • 加密阵列坐标(0,0)处的DC值/低频值

  • 将加密的字节转换为双数组

  • 将第一个双精度数组保存到坐标(0,0)

  • 将第二个双精度阵列保存到坐标(7,7)

  • 执行IDCT

  • 使用
    color.RGBA()
    函数将结果块从IDCT转换为RGBA颜色
  • 把它和像素放在一起形成图像
  • 解密本身:

  • 每个8x8块中的DCT
  • 从坐标(0,0)和(7,7)构造双数组
  • 将双数组转换为字节数组
  • 从步骤3中转换双数组后获取的字节数组中解密DC值/低频值
  • 获取解密字节块数组
  • 将解密的块转换为双值
  • 将双精度值保存到坐标(0,0)
  • 将坐标(7,7)设置为零
  • 在8x8块上执行IDCT
  • 使用
    color.RGBA()
    函数将结果块从IDCT转换为RGBA颜色
  • 把它和像素放在一起形成图像
  • //加密
    私有静态字节[]加密(字节[]原始,字节[]清除)引发异常{
    SecretKeySpec skeySpec=新SecretKeySpec(原始,加密算法);
    Cipher Cipher=Cipher.getInstance(“AES”);
    cipher.init(cipher.ENCRYPT_模式,skeySpec);
    返回密码.doFinal(清除);
    }
    //解密
    私有静态字节[]解密(字节[]原始,字节[]加密)引发异常{
    SecretKeySpec skeySpec=新SecretKeySpec(原始,加密算法);
    Cipher Cipher=Cipher.getInstance(“AES”);
    cipher.init(cipher.DECRYPT_模式,skeySpec);
    返回cipher.doFinal(加密);
    }
    公共静态字节[]toByteArray(双值){
    字节[]字节=新字节[8];
    ByteBuffer.wrap(字节).putDouble(值);
    返回字节;
    }
    公共静态字节[]toByteArray(双[]双数组){
    整数倍=Double.SIZE/Byte.SIZE;
    字节[]字节=新字节[doubleArray.length*倍];
    
    对于(int i=0;我有一个提示:您可以在CTR模式下使用AES创建一个流密码,只需按照本文操作即可,不过如果要重用密钥,您需要将IV存储在某个位置。@MaartenBodewes我最后提出了一个新问题,即如何将字节数组转换为8位int数组
    // To encrypt
    private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
        SecretKeySpec skeySpec = new SecretKeySpec(raw, encryptAlgorithm);
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
        return cipher.doFinal(clear);
    }
    
    // To decrypt
    private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
        SecretKeySpec skeySpec = new SecretKeySpec(raw, encryptAlgorithm);
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec);
        return cipher.doFinal(encrypted);
    }
    
    public static byte[] toByteArray(double value) {
        byte[] bytes = new byte[8];
        ByteBuffer.wrap(bytes).putDouble(value);
        return bytes;
    }
    
    public static byte[] toByteArray(double[] doubleArray){
        int times = Double.SIZE / Byte.SIZE;
        byte[] bytes = new byte[doubleArray.length * times];
        for(int i=0;i<doubleArray.length;i++){
            ByteBuffer.wrap(bytes, i*times, times).putDouble(doubleArray[i]);
        }
        return bytes;
    }
    
    public static double[] toDouble(byte[] bytes) {
        ByteBuffer bb = ByteBuffer.wrap(bytes);
        DoubleBuffer db = bb.asDoubleBuffer();
        double[] copy = new double[db.capacity()];
        db.get(copy);
        return copy;
    }
    
    public static Bitmap applyEncryption(Bitmap image, int blockSize) throws Exception {
        int xPos = 0, yPos = 0, a = 0, b = 0;
    
        int _w = image.getWidth();
        int _h = image.getHeight();
    
        int reconstImage[][] = new int[_w][_h];
        double dctArrayGray[][] = new double[8][8];
    
        // It will convert image bitmap pixels to 2-D arrays
        int[][] imageData = bitmapToArray(image);
    
        for (int i = 0; i< (_w / blockSize); i++) {
            xPos = i * blockSize;
            for (int j = 0; j < (_h / blockSize); j++) {
                yPos = j * blockSize;
    
                for (a = 0; a < blockSize; a++) {
                    for (b = 0; b < blockSize; b++) {
                        dctArrayGray[a][b] = (double) Color.red(imageData[xPos + a][yPos + b]);
                    }
                }
    
                DoubleDCT_2D dct = new DoubleDCT_2D(blockSize, blockSize);
                dct.forward(dctArrayGray, true);
    
    
    
                // Perform Encryption here....
                byte[] chiperBytes = encrypt("ThisIsASecretKey".getBytes(), toByteArray(dctArrayGray[0][0]));
    
                // This is the problem
                // it will overflow the minimum/maximum DCT values, since there are max/min
                //     when performing DCT
    
                // 1. Save the first array in coordinate (0,0)
                dctArrayGray[0][0] = toDouble(chiperBytes)[0];
    
                // 2. save the second array in coordinate (7,7)
                dctArrayGray[7][7] = toDouble(chiperBytes)[1];
    
                // This is the problem I think, it may have "bits lost", after I perform `Color.rgba()` on each block to get pixel values, after below looping. 
                // If I perform `dct.reverse` again, I will not get the same value as the `chiperBytes`
                // since it will also be decrypted (see the decryption function below this function).
                dct.inverse(dctArrayGray, true);
    
                for (a = 0; a < blockSize; a++) {
                    for (b = 0; b < blockSize; b++) {
                        int red = (int) Math.round(dctArrayGray[a][b]);
                        reconstImage[xPos+a][yPos + b] = Color.argb(0xFF, red, red, red);
                    }
                }
            }
        }
    
        // It will convert back the 2-D array to Bitmap image
        return arrayToBitmap(reconstImage);
     }
    
    
     // Decryption
    public static Bitmap applyDecryption(Bitmap decryptedImage, int blockSize) throws Exception {
        int xPos = 0, yPos = 0, a = 0, b = 0;
    
        int _w = decryptedImage.getWidth();
        int _h = decryptedImage.getHeight();
    
        int reconstImage[][] = new int[_w][_h];
        double dctArrayGray[][] = new double[8][8];
    
        // It will convert image bitmap pixels to 2-D arrays
        int[][] imageData = bitmapToArray(decryptedImage);
    
        for (int i = 0; i< (_w / blockSize); i++) {
            xPos = i * blockSize;
            for (int j = 0; j < (_h / blockSize); j++) {
                yPos = j * blockSize;
    
                for (a = 0; a < blockSize; a++) {
                    for (b = 0; b < blockSize; b++) {
                        dctArrayGray[a][b] = (double) Color.red(imageData[xPos + a][yPos + b]);
                    }
                }
    
                DoubleDCT_2D dct = new DoubleDCT_2D(blockSize, blockSize);
                dct.forward(dctArrayGray, true);
    
    
                // Perform Decryption here....
    
                // Get back the double values
                double[] encryptedDoubleValues = new double[2];
                encryptedDoubleValues[0] = dctArrayGray[0][0];
                encryptedDoubleValues[1] = dctArrayGray[7][7];
    
                // I got chiper block not completed EXCEPTION since I got bits lost during saving the encryption
                // block to image and after converting to RGBA from IDCT (Inverse DCT)
                byte[] chiperBytes = decrypt("ThisIsASecretKey".getBytes(), toByteArray(encryptedDoubleValues));
    
                // 1. Save the first array in coordinate (0,0)
                // This line below suppose to bring back the original value / almost the same with original
                dctArrayGray[0][0] = toDouble2(chiperBytes);
    
                // 2. save the second array in coordinate (7,7) and set it to zero
                // (since AC values are expected to be loss and not necessary needed)
                dctArrayGray[7][7] = 0;
    
    
                dct.inverse(dctArrayGray, true);
    
                for (a = 0; a < blockSize; a++) {
                    for (b = 0; b < blockSize; b++) {
                        int red = (int) Math.round(dctArrayGray[a][b]);
                        reconstImage[xPos+a][yPos + b] = Color.argb(0xFF, red, red, red);
                    }
                }
            }
        }
    
        // It will convert back the 2-D array to Bitmap image
        return arrayToBitmap(reconstImage);
    }