2015-02-07 6 views
0

Мне нужно встроить текст в зашифрованное изображение (Stegnography). Я googled и нашел коды для встраивания текста в изображение. Но сначала я должен зашифровать изображение и вставить текст в это зашифрованное изображение. Мои попытки заключаются в следующем.Чтение зашифрованных байтов из изображения в java

/* 
* To change this template, choose Tools | Templates 
* and open the template in the editor. 
*/ 
package tbn; 

import java.awt.Graphics2D; 
import java.awt.Point; 
import java.awt.Transparency; 
import java.awt.image.BufferedImage; 
import java.awt.image.ColorModel; 
import java.awt.image.ComponentColorModel; 
import java.awt.image.DataBuffer; 
import java.awt.image.DataBufferByte; 
import java.awt.image.Raster; 
import java.awt.image.WritableRaster; 
import java.io.File; 
import java.io.IOException; 
import java.security.InvalidKeyException; 
import java.security.NoSuchAlgorithmException; 
import java.security.SecureRandom; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.crypto.BadPaddingException; 
import javax.crypto.Cipher; 
import javax.crypto.IllegalBlockSizeException; 
import javax.crypto.KeyGenerator; 
import javax.crypto.NoSuchPaddingException; 
import javax.crypto.SecretKey; 
import javax.imageio.ImageIO; 

/** 
* 
* @author user 
*/ 
public class DbtClass { 

    public static void main(String[] args) { 
     try { 
      BufferedImage orgnlimage = ImageIO.read(new File("parrruuuuu.png")); 
      orgnlimage = user_space(orgnlimage); 
      byte[] orgnlimagebytes = get_byte_data(orgnlimage); 
      byte[] encryptedbytes = encrypt(orgnlimagebytes, "abc"); 
      BufferedImage encryptedimage = toImage(encryptedbytes, orgnlimage.getWidth(), orgnlimage.getHeight()); 
      ImageIO.write(encryptedimage, "png", new File("encrypted.png")); 

      ///////////////////////////////////////////////////////////////////// 
      ///////////////////////////////////////////////////////////////////// 

      byte[] encryptedbytes2 = get_byte_data(encryptedimage); 
      System.out.println("encryptedbytes before writing: "+encryptedbytes2.length); 

      BufferedImage encryptedimage3 = ImageIO.read(new File("encrypted.png")); 
      byte[] encryptedbyte3 = get_byte_data(encryptedimage3); 
      System.out.println("encryptedbytes after writing: "+encryptedbyte3.length); 


     } catch (IOException ex) { 
      Logger.getLogger(DbtClass.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 

    public static BufferedImage user_space(BufferedImage image) { 
     //create new_img with the attributes of image 
     BufferedImage new_img = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_3BYTE_BGR); 
     Graphics2D graphics = new_img.createGraphics(); 
     graphics.drawRenderedImage(image, null); 
     graphics.dispose(); //release all allocated memory for this image 
     return new_img; 
    } 

    public static byte[] get_byte_data(BufferedImage image) { 
     WritableRaster raster = image.getRaster(); 
     DataBufferByte buffer = (DataBufferByte) raster.getDataBuffer(); 
     return buffer.getData(); 
    } 

    public static byte[] encrypt(byte[] orgnlbytes, String key) { 
     byte[] encbytes = null; 
     try { 
      Cipher cipher = Cipher.getInstance("AES"); 
      KeyGenerator keyGen = KeyGenerator.getInstance("AES"); 
      SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); 
      // cryptograph. secure random 
      random.setSeed(key.getBytes()); 

      keyGen.init(128, random); 
      // for example 
      SecretKey secretKey = keyGen.generateKey(); 
      cipher.init(Cipher.ENCRYPT_MODE, secretKey); 
      encbytes = cipher.doFinal(orgnlbytes); 
     } catch (NoSuchAlgorithmException ex) { 
      Logger.getLogger(DbtClass.class.getName()).log(Level.SEVERE, null, ex); 
     } catch (NoSuchPaddingException ex) { 
      Logger.getLogger(DbtClass.class.getName()).log(Level.SEVERE, null, ex); 
     } catch (InvalidKeyException ex) { 
      Logger.getLogger(DbtClass.class.getName()).log(Level.SEVERE, null, ex); 
     } catch (IllegalBlockSizeException ex) { 
      Logger.getLogger(DbtClass.class.getName()).log(Level.SEVERE, null, ex); 
     } catch (BadPaddingException ex) { 
      Logger.getLogger(DbtClass.class.getName()).log(Level.SEVERE, null, ex); 
     } 
     return encbytes; 
    } 

    public static BufferedImage toImage(byte[] imagebytes, int width, int height) { 
     DataBuffer buffer = new DataBufferByte(imagebytes, imagebytes.length); 
     WritableRaster raster = Raster.createInterleavedRaster(buffer, width, height, 3 * width, 3, new int[]{2, 1, 0}, (Point) null); 
     ColorModel cm = new ComponentColorModel(ColorModel.getRGBdefault().getColorSpace(), false, true, Transparency.OPAQUE, DataBuffer.TYPE_BYTE); 
     return new BufferedImage(cm, raster, true, null); 
    } 
} 

Здесь я был написан зашифрованное изображение с помощью растрового класса и ImageIO.write(). Тогда прочитайте это зашифрованные байты из файла Использование ImageIO.read(). Зашифрованный байт [] перед записью изображения и байт [] после прочтения изображения полностью разные

+0

Но прежде чем писать изображение в файл, из BufferedImage я получил дополнительные 16 байт, о которых вы упоминали. Поэтому я думаю, что проблема может быть в ImageIO.write() или в ImageIO.read() в любом случае, спасибо за ваш комментарий @ Reti43 – TBN

+0

«Стеганография - это искусство или практика сокрытия файла, сообщения, изображения или видео в другом файле , сообщение, изображение или видео ". Если вы считаете, что вам нужно зашифровать изображение для выполнения стеганографии, то вы полностью не в пути. –

+0

Вы впервые вложили сообщение в носитель, а затем зашифровали носитель? Почему вы даже зашифровали изображение носителя? И что вы подразумеваете под «* образ не может быть идентифицирован из байтов *»? – Reti43

ответ

1

Так вот что происходит. Предположим, что исходное изображение размером WxH. Поскольку у вас есть 3 байта на пиксель, ваше изображение, orgnlimagebytes, имеет S = 3*W*H байт.

Теперь вы шифруете это изображение с помощью AES, результатом чего является fixed block size of 16 bytes. Если S не делится на 16, оно будет дополнено так. Если он делится на 16, будет добавлен еще один блок из 16 байтов. Дело здесь в том, что зашифрованный массив байтов, encryptedbytes, имеет больший размер, чем orgnlimagebytes. Назовите это S'.

Теперь вы используете метод toImage для создания BufferedImage из этого массива байтов. Вы создаете буфер encryptedbytes, превращаете его в растровое и бла-бла-бла-бла-бла. У вас получилось изображение размером WxH. Однако происходит то, что объект BufferedImage имеет ссылку на буфер, содержащий S' элементов. Вы используете только первые элементы S для создания пикселей изображения, но вы можете получить доступ к остальным элементам из буфера. Поэтому, когда вы снова включаете BufferedImage в байтовый массив, encryptedbytes2, вы получаете все S' количество элементов назад.

Изображение имеет только WxH RGB пикселей, поэтому, если вы попытаетесь сохранить это в файле изображения, это все, что вы собираетесь сохранить. Вы не сохраните ни один из дополнительных байтов из ссылки на буфер. Поэтому, когда вы сохраняете и загружаете изображение и конвертируете его в массив байтов, вы получаете ожидаемое количество байтов, которое должно быть S.


Это объясняет непредвиденную несогласованность зашифрованного массива байтов до и после сохранения в файл. Однако, помимо метода шифрования, почему вы даже шифруете обложку? Было бы разумно, если бы вы зашифровали сообщение, прежде чем скрывать его в изображении для дополнительной безопасности, в случае, если кому-то удалось обнаружить и извлечь сообщение. Шифрование значений пикселей изображения обложки означает радикальное их изменение, что приводит к явным изменениям.

+0

http://stackoverflow.com/questions/28396404/save-encrypted-image-bytes-to-file-and-recover-to- original-image-in-java – TBN

+0

Документ очень трудно понять из-за низкого качества письменности, но ни в коем случае не говорит об шифровании AES. – Reti43

 Смежные вопросы

  • Нет связанных вопросов^_^