Приложение, реализующее метод замены наименее значащих битов для файлов с расширением bmp

Изучение понятия и основных задач стеганографии - науки, изучающей способы и методы сокрытия информации. Характеристика метода замены наименее значащих битов для bmp файлов. Реализация метода замены НЗБ для bmp файлов на языке программирования Java.

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык русский
Дата добавления 13.02.2013
Размер файла 149,2 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru/

1. Введение

Стеганография - наука, изучающая способы и методы сокрытия информации. Цель стеганографии - тайная передача информации с целью сокрытия существования сообщения, в отличие от криптографии, которая скрывает содержимое секретного сообщения, но не скрывает существование секретной коммуникации. Как правило, сообщение будет выглядеть как что-либо иное, например, как изображение, статья, список покупок, письмо или судоку. Стеганографию обычно используют совместно с методами криптографии, таким образом, дополняя её.

Хотя термин « стеганография» появился только в конце 15- того столетия, использовать стеганографию начали несколько тысячелетий тому назад. В древние времена, сообщения скрывали на задней стороне восковых табличек для письма, писали на желудках кроликов или наносили в виде татуировки на скальпе рабов. Невидимые чернила использовались в течение многих столетий - детьми и студентами для забавы и тайными агентами и террористами при серьёзном шпионаже. Микрофотоснимки и микрофильмы, основные элементы кинофильмов о войне и шпионах, появлялись после изобретения фотографии.

За последние десять-двадцать лет, благодаря массовому распространению мультимедийных технологий и средств телекоммуникации, развитие стеганографии вышло на принципиально новый этап, который специалисты называют компьютерной стеганографией. Среди основных областей использований компьютерной стеганографии - скрытие сообщений, путем встраивания их в цифровые данные, имеющие, как правило, аналоговую природу.

2. Термины и определения стеганографии

Использование единой терминологии для компьютерной стеганографии было предложено в 1996 году, на конференции Information Hiding: FirstInformationWorkshop. Стенографическая система или стегосистема - совокупность средств и методов, которые используются для формирования скрытого канала передачи информации. Основной целью сокрытия сообщения является не ограничение или регламентирование доступа к файлу-контейнеру, а гарантирование в значительной степени целостности и возможности восстановления встроенного сообщения.

При построении стегосистемы должны учитываться следующие положения[3, 5]:

стегосистема должна иметь приемлемую вычислительную сложность реализации;

должна обеспечиваться необходимая пропускная способность;

методы скрытия должны обеспечивать аутентичность и целостность секретной информации для авторизованного лица;

потенциальный нарушитель имеет полное представление о стегосистеме и детали ее реализации; единственное, что ему неизвестно - это ключ, с помощью которого только его обладатель может установить факт наличия и содержание скрытого сообщения;

если факт существования скрытого сообщения становится известным нарушителю, это не должно позволить последнему извлечь его до тех пор, пока ключ сохраняется втайне;

нарушитель должен быть лишен любых технических и других преимуществ в распознании или раскрытии содержания секретных сообщений;

В общем случае стегосистема может быть рассмотрена как система связи, изображенная на рис.1.

Рис.1: Структурная схема стегосистемы, как системы связи

Основными стенографическими понятиями являются сообщение и контейнер.

Сообщение mM - это секретная информация, наличие которой необходимо скрыть. M = {m1, m2, mn} - множество всех сообщений.

Контейнер cCназывается несекретная информация, которую можно использовать для скрытия сообщения, С = {c1,c2,…cq} - множество все контейнеров, причем q>>n. В качестве сообщения и контейнера могут выступать как обычный текст, так и файлы мультимедийного формата.

Пустой контейнер (контейнер-оригинал) - это контейнер с, который не содержит скрытой информации.

Заполненный контейнер (контейнер-результат) - контейнер с, содержащий скрытую информацию m(cm). Одно из требований, которое при этом ставится: контейнер-результат не должен быть визуально отличим от контейнера-оригинала.

Выделяют два основных типа контейнера: потоковый и фиксированный.

Потоковый контейнер представляет собой непрерывно изменяющуюся последовательность битов. Сообщение встраивается в него в реальном времени, поэтому в кодере заранее неизвестно, хватит ли размеров контейнера для передачи всего сообщения. В один контейнер большого размера может быть встроено несколько сообщений. Интервалы между встроенными битами определяются генератором ПСП с равномерным распределением интервалов между отсчетами.

В фиксированном контейнере размеры и характеристики заранее известны, что позволяет выполнять вложение данных оптимальным образом.

Контейнер может быть случайным, избранным или навязанным. Избранный контейнер зависит от встроенного сообщения. Навязанный контейнер появляется, когда лицо, которое предоставляет контейнер, подозревает о возможной переписке, и желает предотвратить ее. На практике чаще применяются случайные контейнеры.

Начальную обработку скрываемой информации выполняет прекодер. В качестве одной из важнейших предварительных обработок сообщения можно назвать вычисление его обобщенного преобразования Фурье[1]. Это позволяет встраивать данные в спектральной области, что значительно повышает устойчивость наполненного контейнера к искажениям.

Запись сообщения в контейнер-оригинал, осуществляется стеганокодером. Вложение происходит одним из методов стенографической записи, к примеру, методом наименьших значащих битов.

Также, в большинстве систем для упаковки и извлечения сообщений используется ключ. По аналогии с криптографией, по типу ключа стегосистемы можно подразделить на два типа:

с секретным ключом;

с открытым ключом.

В стегосистеме с секретным ключом используется один ключ, который должен быть определен либо до начала обмена секретными сообщениями, либо передан по защищенному каналу.

В стегосистеме с открытым ключом для встраивания и извлечения сообщения используются разные ключи, которые различаются таким образом, что с помощью вычислений невозможно вывести один ключ из другого. Поэтому один ключ (открытый) может передаваться свободно по незащищенному каналу связи. Кроме того, данная схема хорошо работает и при взаимном недоверии отправителя и получателя.

3. Метод замены наименее значащих битов для BMP файлов

Метод замены наименее значащих битов (НЗБ) наиболее распространен среди методов замены данных в пространственной области неподвижных изображений[1].

Младший значащий бит изображения несет в себе меньше всего информации, человеческим взглядом изменения в нем неощутимы, что позволяет незаметно заменять НЗБ контейнера битами секретного сообщения.

Метод замены НЗБ имеет низкую стойкость к любым искажениям контейнера, что частично исправляется помехоустойчивым кодированием встраиваемого сообщения.

Наиболее прост этот метод при работе с растровыми изображениями в форматах без компрессии, к которым относятся и BMP файлы.[3]

Рассмотрим структуру bmp файла представленную на рис. 2:

Рис. 2. Структура bmp файла

В данном методе нас интересуют только биты изображения. Каждый пиксел описывается 3 байтами: значение красного, зеленого и синего цветов. Метод НЗБ позволяется записывать информацию в младшие биты каждого из этих байтов. Так как заголовочная информация BMP занимает 54 байта в начале файла[6], то мы можем записать сообщение размером (количество_байт_в_файле - 54) бит.

Сам алгоритм метода подразумевает разбиения сообщения на биты, которые последовательно записываются в младшие биты изображения. Для того, чтобы усложнить определение наличия сообщения в контейнере для злоумышленника, сообщение кодируется с помощью одного из криптографических шифров, и лишь после этого записывается в стеганоконтейнер.[1]

Также, для скрытия наличия сообщения в файле, младшие биты незадействованных байтов заполняются шумом, генерируемым генератором псевдослучайных чисел[1].

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

стеганография файл программирование бит

4. Реализация метода замены НЗБ для BMP файлов на языке программирования Java

Программа представляет собой графическое приложение. Предусмотрены следующие функции:

открыть bmp файл;

загрузить текстовый файл с ключом, либо написать ключ в текстовом поле самому;

записать в текстовое поле сообщение;

загрузить сообщение из текстового файла;

записать сообщение в открытый графический файл, методом НЗБ, кодируя его XOR шифром по данному ключу;

прочитать сообщение из файла, декодировав егоXORшифром с помощью данного ключа;

сохранить прочитанное сообщение в файл;

закрыть bmp файл;

XOR шифрование -вид симметричного шифрования, при котором каждый бит сообщения преобразуется с использованием нового бита ключа по следующему правилу: 0+0=0, 0+1=1, 1+0=1, 1+1=0.

Рассмотрим особенности реализации программы:

Программа содержит 4 класса:

Entry - входная точка приложения, осуществляет загрузку графического интерфейса программы.

StegoForm - описание графического интерфейса, и реализация всех связанных с ним функций.

StegoMessenger - класс, в котором описаны методы проверки контейнера на наличие сообщения, а также записи и чтения сообщения в контейнер.

XOREncoder - класс описывающий методы кодирования и декодирования сообщения с помощью XOR шрифта и передаваемого ключа.

Рассмотрим методы класса StegoMessenger:

getMaximumMessageByteLength - возвращает максимальный размер сообщения для данного файла, в байтах.

isFullContainer - проверяет файл на то, записано ли в него сообщение, кодированное ключом key. Для этого читает последний бит у первых 32 байтов после заголовка файла, декодирует с данным ключом, с помощью метода decrypt класса XOREncoder, и сравнивает с проверочным числом. Возвращает true - если числа совпали, и false - если нет.

writeToImage - метод, записывающий сообщение в файл. На вход ему передается адрес файла изображения, сообщение и ключ. Далее метод высчитывает длину массива байт, которые будут использованы для записи сообщения. Следующим шагом будет кодирование проверочного числа, используемого для проверки контейнера на наличие сообщения, длины сообщения и самого сообщения с помощью метода encrypt класса XOREncoder. После чего все три кодированных последовательности байт разбиваются на биты и последовательно записываются в последний бит байтов изображения, методом writeToLSB. Последним будет заполнение младших бит неиспользованных байт шумом, с помощью вызова метода writeNoiseToLSB.

readFromImage - метод, читающий сообщение из файла. На вход получает адрес файла изображения и ключ. Первый шаг -проверка на существование в контейнере сообщения, записанного данным ключом, действия аналогичны методу isFullContainer. Следующий шаг - чтение и декодирование длины записанного сообщения. Длина l- 32 битное число и хранится соответственно в младших битах следующих после проверочных 32 байтах. Далее, метод читает само сообщение длиной lбайт, декодирует его и возвращает.

Исходный код программы содержится в разделе «Приложения».

Заключение

Таким образом, мы создали приложение, реализующее метод замены наименее значащих битов для файлов с расширением bmp. При его небольшой сложности, этот метод, тем не менее, способен сохранить в тайне факт передачи информации и позволяет передавать достаточно большие сообщения.

Сама стеганография сейчас занимает свою нишу в обеспечении безопасности: она не заменяет, а дополняет криптографию. Сокрытие сообщения методами стеганографии значительно снижает вероятность обнаружения самого факта передачи сообщения. А если это сообщение к тому же зашифровано, то оно имеет еще один, дополнительный, уровень защиты. Также очень перспективно использование стеганографии в тех странах, где существуют законы, ограничивающие применение криптографии, как еще одного способа ограничить доступ к файлам.

Список используемых источников

1.Конахович Г. Ф., Пузыренко А. Ю. Компьютерная стеганография. Теория и практика. -- К.: МК-Пресс, 2006. -- 288 с, ил.

2. Стеганография для судебного исследователя. Краткий Обзор Гари Кесслер (Gary C.Kessler)

3. Хорошко В.О., Азаров О. Д., Шелест М. Э., Яремчук Ю.Э. Основы компьютерной стеганографии: Начальное пособие для студентов и аспирантов. Винница: ВДТУ, 2003 - 143 с.

4. О. В. Генне, Опубликовано: журнал "Защита информации. Конфидент", №3, 2000

5. Грибунин В.Г., Оков И. Н., Туринцев И.В. Цифровая стеганография. - М.: Солон-Пресс, 2002. - 272 с.

Приложения

Исходный код программы:

Классru.sgu.steganography.Entry:

public class Entry {

public static void main(String[] args) {

JFrame frame = new JFrame("StegoForm");

frame.setContentPane(new StegoForm().mainPanel);

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.pack();

frame.setVisible(true);

}

}

Классru.sgu.steganography.StegoForm:

public class StegoForm {

public static final String CURRENT_DIR_PATH = "D:/";

private static final String TEXT_SIZE_LABEL_TEXT = "Available text size = %d";

publicJPanelmainPanel;

privateJPanelimagePanel;

privateJButtonopenBmpButton;

privateJLabelimageLabel;

privateJFileChooserimageFileChooser;

privateJButtoncloseBmpButton;

privateJButtonwriteMessageButton;

privateJTextAreawriteTextArea;

privateJLabeltextLengthLabel;

privateJPanelwriteAreaPanel;

privateJScrollPanewriteAreaScrollPane;

privateJTextPanereadTextPane;

privateJButtonreadMessageButton;

privateJScrollPanereadAreaScrollPane;

privateJFileChooserkeyFileChooser;

privateJTextFieldkeyTextField;

privateJButtonloadKeyButton;

privateJButtonloadMessageButton;

privateJButtonsaveReadedDataButton;

privateJFileChoosermessageFileChooser;

private byte[] data;

private String key = "";

private long maxTextByteLength = 0;

private long writeAreaByteSize = 0;

private void createUIComponents() {

mainPanel = new JPanel();

imagePanel = new JPanel();

openBmpButton = new JButton();

imageLabel = new JLabel();

imageFileChooser = new JFileChooser(new File(CURRENT_DIR_PATH));

imageFileChooser.setFileFilter(new FileNameExtensionFilter("Bmp files", "bmp"));

closeBmpButton = new JButton();

textLengthLabel = new JLabel();

writeMessageButton = new JButton();

writeAreaPanel = new JPanel();

writeTextArea = new JTextArea();

writeAreaScrollPane = new JScrollPane(writeTextArea);

loadMessageButton = new JButton();

readMessageButton = new JButton();

readTextPane = new JTextPane();

readAreaScrollPane = new JScrollPane(readTextPane);

saveReadedDataButton = new JButton();

keyTextField = new JTextField(1);

loadKeyButton = new JButton();

keyFileChooser = new JFileChooser(new File(CURRENT_DIR_PATH));

keyFileChooser.setFileFilter(new FileNameExtensionFilter("Txt files", "txt"));

messageFileChooser = new JFileChooser(new File(CURRENT_DIR_PATH));

}

publicStegoForm() {

writeTextArea.setDocument(new PlainDocument() {

@Override

protected void removeUpdate(DefaultDocumentEventchng) {

writeAreaByteSize = writeTextArea.getText().getBytes().length;

}

@Override

public void insertString(int offset, String str, AttributeSetattr) throws BadLocationException {

if (str == null)

return;

textLengthLabel.setText(String.format(TEXT_SIZE_LABEL_TEXT, maxTextByteLength - writeAreaByteSize));

if ((writeAreaByteSize) <= maxTextByteLength) {

for (char c : str.toCharArray()) {

writeAreaByteSize += String.valueOf(c).getBytes().length;

super.insertString(offset, str, attr);

++offset;

}

}

}

});

keyTextField.setDocument(new PlainDocument() {

@Override

protected void removeUpdate(DefaultDocumentEventchng) {

super.removeUpdate(chng); //To change body of overridden methods use File | Settings | File Templates.

key = keyTextField.getText();

}

@Override

public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {

if (str == null)

return;

str = str.substring(0, Math.min(100 - getLength(), str.length()));

super.insertString(offs, str, a);

key = keyTextField.getText();

}

});

openBmpButton.addActionListener(new ActionListener() {

@Override

public void actionPerformed(ActionEvent e) {

int status = imageFileChooser.showOpenDialog(null);

if (status == JFileChooser.APPROVE_OPTION) {

File imageFile = imageFileChooser.getSelectedFile();

if (imageFile != null) {

reloadImage(imageFile);

maxTextByteLength = StegoMessenger.getMaximumMessageByteLength(imageFile);

textLengthLabel.setText(String.format(TEXT_SIZE_LABEL_TEXT, maxTextByteLength));

}

}

}

});

writeMessageButton.addActionListener(new ActionListener() {

@Override

public void actionPerformed(ActionEvent e) {

try{

StegoMessenger.writeToImage(imageFileChooser.getSelectedFile(),writeTextArea.getText(), key);

reloadImage(imageFileChooser.getSelectedFile());

setEnabledTo(true, readTextPane, readMessageButton, saveReadedDataButton);

} catch (IOException e1) {

System.out.println("message was not write");

}

}

});

readMessageButton.addActionListener(new ActionListener() {

@Override

public void actionPerformed(ActionEvent e) {

if (checkToRead(imageFileChooser.getSelectedFile())) {

readTextPane.setText(" ");

try {

data = StegoMessenger.readFromImage(imageFileChooser.getSelectedFile(), key);

readTextPane.setText(new String(data));

setEnabledTo(true, readTextPane, saveReadedDataButton);

} catch (IOException e1) {

setEnabledTo(false, readTextPane, saveReadedDataButton);

readTextPane.setText("File does not contain message");

}

}else {

setEnabledTo(false, readTextPane, saveReadedDataButton);

readTextPane.setText("File does not contain message");

}

}

});

closeBmpButton.addActionListener(new ActionListener() {

@Override

public void actionPerformed(ActionEvent e) {

imageLabel.setIcon(null);

setEnabledTo(false, closeBmpButton, readTextPane, readMessageButton, writeMessageButton, writeTextArea, saveReadedDataButton);

}

});

loadKeyButton.addActionListener(new ActionListener() {

@Override

public void actionPerformed(ActionEvent e) {

int status = keyFileChooser.showOpenDialog(null);

if (status == JFileChooser.APPROVE_OPTION) {

File keyFile = keyFileChooser.getSelectedFile();

if (keyFile != null) {

key = new String(readDataFrom(keyFile));

keyTextField.setText(key);

}

}

}

});

loadMessageButton.addActionListener(new ActionListener() {

@Override

public void actionPerformed(ActionEvent e) {

int status = keyFileChooser.showOpenDialog(null);

if (status == JFileChooser.APPROVE_OPTION) {

File msgFile = keyFileChooser.getSelectedFile();

if (msgFile != null) {

data = readDataFrom(msgFile);

if(msgFile.getName().endsWith("txt")){

writeTextArea.setText(new String(data));

}

try{

StegoMessenger.writeToImage(imageFileChooser.getSelectedFile(),new String(data), key);

reloadImage(imageFileChooser.getSelectedFile());

setEnabledTo(true, readTextPane, readMessageButton, saveReadedDataButton);

} catch (IOException e1) {

System.out.println("message was not write");

}

}

}

}

});

saveReadedDataButton.addActionListener(new ActionListener() {

@Override

public void actionPerformed(ActionEvent e) {

int status = keyFileChooser.showSaveDialog(null);

if (status == JFileChooser.APPROVE_OPTION) {

File msgFile = keyFileChooser.getSelectedFile();

if (msgFile != null) {

try {

BufferedWriterbufferedWriter = new BufferedWriter(new FileWriter(msgFile));

for (byte b : data) {

bufferedWriter.write(b);

}

bufferedWriter.close();

} catch (IOException e1) {

System.out.println("File not save");

}

}

}

}

});

}

private byte[] readDataFrom(File keyFile) {

try {

ByteBuffer bb = ByteBuffer.allocate((int) keyFile.length());

BufferedReaderbr = new BufferedReader(new FileReader(keyFile));

while (br.ready()) {

bb.put((byte) br.read());

}

br.close();

returnbb.array();

} catch (IOException e) {

return new byte[0];

}

}

private void reloadImage(File imageFile) {

BufferedImage image;

image = null;

try {

image = ImageIO.read(imageFile);

Thread.yield();

} catch (IOException e1) {

System.out.println("Load image error");

}

setRightIconTo(imageLabel, image);

setEnabledTo(true, closeBmpButton, writeTextArea, writeMessageButton, readMessageButton, readTextPane);

}

privatebooleancheckToRead(File imageFile) {

try {

returnStegoMessenger.isFullContainer(imageFile, key);

} catch (IOException e) {

return false;

}

}

private void setRightIconTo(JLabelimageLabel, BufferedImage image) {

doubleminBoundCoefficient = getMinimumBound(image.getWidth(), image.getHeight(), imagePanel.getWidth(), imagePanel.getHeight());

intimageWidth = (int) (image.getWidth() * minBoundCoefficient) - 7;

intimageHeight = (int) (image.getHeight() * minBoundCoefficient) - 7;

Image imageIcon = image.getScaledInstance(imageWidth, imageHeight, Image.SCALE_DEFAULT);

ImageIcon icon = new ImageIcon(imageIcon);

imageLabel.setIcon(icon);

}

private double getMinimumBound(intinWidth, intinHeight, intoutWidth, intoutHeight) {

returnMath.min((double) outWidth / inWidth, (double) outHeight / inHeight);

}

private void setEnabledTo(boolean enabled, JComponent... params) {

if (params.length == 0) {

return;

}

for (JComponentparam : params) {

param.setEnabled(enabled);

}

}

}

КлассStegoMessenger:

public class StegoMessenger {

private static final int BYTE_SIZE = 8;

private static final int MSG_LENGTH_PREFIX = 4 * 8;

private static final int BMP_HEADER_LENGTH = 54;

private static final int MSG_CHECK_PREFIX = 4 * 8;

private static final long[] CHECK_MESSAGE_NUMBER = {314159265l};

private static final int GLOBAL_PREFIX = BMP_HEADER_LENGTH + MSG_CHECK_PREFIX + MSG_LENGTH_PREFIX;

private static final Random rand = new Random();

public static long getMaximumMessageByteLength(File file) {

return (file.length() - GLOBAL_PREFIX) / 8;

}

public static void writeToImage(File image, String message, String key)

throwsIOException {

RandomAccessFileraf = null;

BitSetkeyBitSet = BitSet.valueOf(key.getBytes());

BitSetmessageBitSet = BitSet.valueOf(message.getBytes());

intmessageBitLength = (int) messageBitSet.length();

BitSet check;

BitSet length;

check = BitSet.valueOf(CHECK_MESSAGE_NUMBER);

length = BitSet.valueOf(new long[]{(long) messageBitLength});

byte[] checkPixels;

byte[] lengthPixels;

byte[] messagePixels;

long tail;

try {

raf = new RandomAccessFile(image, "rw");

raf.seek(BMP_HEADER_LENGTH);

tail = (raf.length() - messageBitLength - GLOBAL_PREFIX);

if (tail < 0) {

throw new IOException("Stego container is too small for this message. Available to writing " +

+((raf.length() - GLOBAL_PREFIX) / 8)

+ "bytes, but expected message length = "

+ message.length());

}

check = XOREncoder.encrypt(check, keyBitSet);

length = XOREncoder.encrypt(length, keyBitSet);

messageBitSet = XOREncoder.encrypt(messageBitSet, keyBitSet);

checkPixels = new byte[MSG_CHECK_PREFIX];

lengthPixels = new byte[MSG_LENGTH_PREFIX];

messagePixels = new byte[messageBitLength];

raf.read(checkPixels);

raf.read(lengthPixels);

raf.read(messagePixels);

writeToLSB(checkPixels, check);

writeToLSB(lengthPixels, length);

writeToLSB(messagePixels, messageBitSet);

raf.seek(BMP_HEADER_LENGTH); /**/

raf.write(checkPixels);

raf.write(lengthPixels);

raf.write(messagePixels);

writeNoiseToLSB(raf);

} catch (IOException e) {

throw new IOException(

"Error when process is run in file " + image, e);

} catch (Exception e) {

e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.

} finally {

if (raf != null) {

raf.close();

}

}

}

public static byte[] readFromImage(File image, String key) throws IOException {

RandomAccessFileraf = null;

BitSetkeyBitSet = BitSet.valueOf(key.getBytes());

BitSetmessageBitSet;

BitSet check;

BitSet length;

byte[] checkPixels;

byte[] lengthPixels;

byte[] messagePixels;

try {

raf = new RandomAccessFile(image, "rw");

raf.seek(BMP_HEADER_LENGTH);

checkPixels = new byte[MSG_CHECK_PREFIX];

raf.read(checkPixels);

check = readFromLSB(checkPixels);

check = XOREncoder.decrypt(check, keyBitSet);

check.clear(MSG_CHECK_PREFIX, check.size());

if (CHECK_MESSAGE_NUMBER[0] != check.toLongArray()[0]) {

throw new IOException("Message is not stegocontainer");

}

lengthPixels = new byte[MSG_LENGTH_PREFIX];

raf.read(lengthPixels);

length = readFromLSB(lengthPixels);

length = XOREncoder.decrypt(length, keyBitSet);

length.clear(MSG_LENGTH_PREFIX, length.size());

intmessageBitSize = (int) length.toLongArray()[0];

messagePixels = new byte[messageBitSize];

raf.read(messagePixels);

messageBitSet = readFromLSB(messagePixels);

messageBitSet = XOREncoder.decrypt(messageBitSet, keyBitSet);

messageBitSet.clear(messageBitSize, messageBitSet.length());

returnmessageBitSet.toByteArray();

} catch (IOException e) {

throw new IOException("Error when process is run in file "

+ image + " \n" + e, e);

} catch (Exception e) {

throw new IOException("Error when process is run in file "

+ image + " \n" + e, e);

} finally {

if (raf != null) {

raf.close();

}

}

}

public static booleanisFullContainer(File image, String key) throws IOException {

RandomAccessFileraf = null;

BitSetkeyBitSet = BitSet.valueOf(key.getBytes());

byte[] checkPixels;

BitSet check;

try {

raf = new RandomAccessFile(image, "r");

raf.seek(BMP_HEADER_LENGTH);

checkPixels = new byte[MSG_CHECK_PREFIX];

raf.read(checkPixels);

check = readFromLSB(checkPixels);

check = XOREncoder.decrypt(check, keyBitSet);

check.clear(MSG_CHECK_PREFIX, check.size());

if (CHECK_MESSAGE_NUMBER[0] == check.toLongArray()[0]) {

return true;

}

return false;

} catch (IOException e) {

throw new IOException("Error in read image", e);

} finally {

if (raf != null) {

raf.close();

}

}

}

public static void writeNoiseToLSB(RandomAccessFileraf) throws IOException {

int tail = (int) (raf.length() - raf.getFilePointer());

byte[] b = new byte[3];

for (inti = 0; i< tail; i += 3) {

raf.read(b);

for (int j = 0; j <b.length; j++) {

b[j] &= 254;

b[j] |= rand.nextBoolean() ? 1 : 0;

}

raf.seek(raf.getFilePointer() - 3);

raf.write(b);

}

}

private static void writeToLSB(byte[] p, BitSet message) {

for (inti = 0; i<p.length; i++) {

p[i] &= 254;

p[i] |= message.get(i) ? 1 : 0;

}

}

private static BitSetreadFromLSB(byte[] p) {

BitSetbs = new BitSet(p.length);

for (inti = 0; i<p.length; i++) {

bs.set(i, (p[i] & 1) == 1);

}

returnbs;

}

}

КлассXOREncoder:

public class XOREncoder {

public static BitSet encrypt(BitSet message, BitSet key) {

return crypt(message, key);

}

private static BitSet crypt(BitSet message, BitSetkeyBits) {

BitSetcipherBits = new BitSet(message.length());

intkeyBitIndex = 0;

boolean bit;

if(keyBits.size() == 0){

return message;

}

for (inti = 0; i<message.size(); i++) {

bit = message.get(i) ^ keyBits.get(keyBitIndex);

cipherBits.set(i, bit);

keyBitIndex++;

keyBitIndex %= keyBits.size();

}

returncipherBits;

}

public static BitSet decrypt(BitSet cipher, BitSet key) {

BitSet message = crypt(cipher, key);

return message;

}

}

Размещено на Allbest.ru


Подобные документы

  • Принципы компьютерной стеганографии. Классификация методов сокрытия информации. Популярность метода замены наименьшего значащего бита. Сущность методов расширения палитры и блочного сокрытия. Применение методов в GIF изображениях. Реализация алгоритмов.

    курсовая работа [589,7 K], добавлен 17.02.2013

  • Основные понятия и назначение технологии JavaBeans, ее компоненты и принцип работы, преимущества. Методика создания jar файлов в среде Eclipse. Структура файлов манифеста. Создание многопоточных приложений. Изучение визуального редактора Java BeanBox.

    лабораторная работа [67,4 K], добавлен 30.06.2009

  • Исследование проблемы сравнения звуковых файлов и определение степени их схожести. Сравнение файлов с использованием метода нечеткого поиска, основанного на метрике (расстоянии) Левенштейна. Сравнение MIDI-файлов и реализация алгоритмов считывания.

    курсовая работа [2,0 M], добавлен 14.07.2012

  • Проектирование программного обеспечения. Схема начального формирования каталога файлов, вывода на экран каталога файлов, удаления файлов, сортировки файлов по имени, дате создания и размеру методом прямого выбора. Управление каталогом в файловой системе.

    курсовая работа [804,0 K], добавлен 08.01.2014

  • Принцип работы и программная реализация однозвучного, одноалфавитного и полиграммного шифра. Шифрование по методу подстановки, замены и кодового слова. Безопасность шифровки простой замены. Частотные характеристики текстовых сообщений и дешифрация.

    контрольная работа [1,1 M], добавлен 02.02.2012

  • Особенности работы "поисковика" дублирующихся файлов на диске. Выбор среды программирования. Разработка программного продукта. Основные требования, предъявляемые к программе, производящей поиск дублирующихся файлов на диске. Отображение скрытых файлов.

    курсовая работа [1,8 M], добавлен 28.03.2015

  • Основные понятия и принципы динамического программирования, реккурентность природы задач данного типа и функциональные уравнения Беллмана. Разработка структуры блок-схемы и реализация на ЭВМ построенного алгоритма на выбранном языке программирования.

    курсовая работа [30,2 K], добавлен 26.11.2010

  • Изучение основных этапов программирования на ассемблере, который является символическим представлением машинного языка, то есть каждой машинной команде соответствует команда ассемблера. Реализация алгоритма выполнения программы для просмотра bmp файлов.

    курсовая работа [248,0 K], добавлен 25.12.2012

  • Снижение трудоемкости выборки файлов; поиск текста при производстве компьютерных экспертиз. Автоматизированная индексация файлов и формализация задач; разработка инфологической, физической моделей системы с привязкой к СУБД; выбор языка программирования.

    дипломная работа [4,1 M], добавлен 24.09.2013

  • Понятие процесса архивации файлов. Программы, осуществляющие упаковку и распаковку файлов. Защита информации от несанкционированного доступа. Самораспаковывающиеся архивы. Основные характеристики программ-архиваторов. Распространенные алгоритмы сжатия.

    презентация [801,6 K], добавлен 23.10.2013

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.