МІНІСТЕРСТВО ОСВІТИ І НАУКИ, МОЛОДІ І СПОРТУ УКРАЇНИ
НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ “ЛЬВІВСЬКА ПОЛІТЕХНІКА”
Кафедра ЕОМ
/
Лабораторна робота №2
на тему:
“Перестановочний шифр”
з дисципліни:
“Захист інформації в комп'ютерних мережах”
Мета роботи: ознайомитись з основами класичної техніки шифрування – перестановочними шифрами
Теоретичні відомості
Метод Цезаря ґрунтувався на заміщенні символів відкритого тексту різними символами шифрованого тексту. Принципово інший клас перетворень будується на використанні перестановок букв відкритого тексту. Шифри, створені за допомогою перестановок, називають перестановочними шифрами.
Найпростіший з таких шифрів використає перетворення "драбинки", та полягає в тому, що відкритий текст записується уздовж похилих рядків певної довжини ("сходів"), а потім зчитується порядково по горизонталі. Наприклад, щоб зашифрувати повідомлення "meet me after the toga party" за методом драбинки зі сходами довжиною 2, запишемо це повідомлення у вигляді
m
e
m
a
t
r
h
t
g
p
r
y
e
t
e
f
e
t
e
o
a
a
t
Шифроване повідомлення буде мати такий вигляд.
MEMATRHTGPRYETEFETEOAAT
Такий "шифр" особливої складності для криптоаналізу не представляє. Більш складна схема припускає запис тексту повідомлення в горизонтальні рядки однакової довжини та наступне зчитування тексту стовпець за стовпцем, але не один за одним, а відповідно до деякої перестановки стовпців. Порядок зчитування стовпців при цьому стає ключем алгоритму. Розглянемо наступний приклад.
Ключ: 4 3 1 2 5 6 7
4
3
1
2
5
6
7
a
t
t
a
c
k
p
o
s
t
p
o
n
e
d
u
n
t
i
l
t
w
o
a
m
x
y
z
Відкритий текст:
Шифрований текст: TTNAAPTMTSUOAODWCOIXKNLYPETZ
Простий перестановочний шрифт дуже легко розпізнати, тому що букви в ньому зустрічаються з тією же частотою, що й у відкритому тексті. Наприклад, для тільки що розглянутого способу шифрування з перестановкою стовпців аналіз шифру виконати досить просто - необхідно записати шифрований текст у вигляді матриці й перебрати можливі варіанти перестановок для стовпців. Можна використати також таблиці значень частоти біграм та триграм.
Перестановочний шифр можна зробити більше захищеним, виконавши шифрування з використанням перестановок кілька разів. Виявляється, що в цьому випадку застосовану для шифрування перестановку відтворити вже не так просто. Наприклад, якщо попереднє повідомлення шифрувати ще раз за допомогою того ж самого алгоритму, то результат буде наступним.
Ключ: 4 3 1 2 5 6 7
4
3
1
2
5
6
7
t
t
n
a
a
p
t
m
t
s
u
o
a
o
d
w
c
o
i
x
k
n
l
y
p
e
t
z
Відкритий текст:
Шифрований текст: NSCYAUOPTTWLTMDNAOIEPAXTTOKZ
Щоб наочніше уявити те, що ми одержимо в підсумку повторного застосування перестановки, зіставимо кожну букву вихідного відкритого тексту з номером відповідної їй позиції. Наше повідомлення складається з 28 букв, і вихідною послідовністю буде послідовність
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Після першої перестановки одержимо послідовність, що усе ще зберігає деяку регулярність структури.
03
10
17
24
04
11
18
25
02
09
16
23
01
08
15
22
05
12
19
26
06
13
20
27
07
14
21
28
Після другої перестановки виходить наступна послідовність.
17
09
05
27
24
16
12
07
10
02
22
20
03
25
15
13
04
23
19
14
11
01
26
21
18
08
06
28
Регулярність цієї послідовності вже зовсім не проглядається, тому її криптоаналіз буде вимагати значно більших зусиль.
Хід роботи
Для розробки програми для шифрування тексту перестановочним методом використано середовище Eclipce і платформу JavaFX.
Для шифрування потрібно ввести повідомлення, ввести ключ і натиснути кнопку Шифрувати. Після чого отрумуємо результат. (рис. 1)
/
Рис. 1. Вікно програми (шифрування).
/
Рис. 2. Вікно програми (дешифрування).
Висновок: В даній лабораторній роботі я ознайомився з технікою перестановочного шифрування та розробив програму, яка шифрує повідомлення перестановочним методом.
Лістинг програми
MainOverviewController.javapackage application;
import java.util.Arrays;
import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.control.Alert.AlertType;
public class MainOverviewController {
@FXML
private TextField message;
@FXML
private TextField key;
@FXML
private TextField result;
@FXML
private Button cipher;
@FXML
private Button decipher;
public static String shufr(int[] keys, char[] mass, int c, int sizeOfKey){
String result = "";
int counter=0;
int counter1=0;
for (int i = 0; i < keys.length; i++) {
if (keys[i]==c) {
counter = i;
}
}
for (int i = 0; i < mass.length; i++) {
if(i==(counter+counter1)){
result+=mass[i];
counter1+=sizeOfKey;
}
}
counter1=0;
counter=0;
return result;
}
public static String deShufr(int[] keys, char[] mass, int c, int sizeOfKey){
String result = "";
int col = keys.length;
int row = ((mass.length%col)==0) ? ((mass.length) / col) : ((mass.length/col) + 1);
for (int j = 0; j < keys.length; j++) {
for (int i = 0; i < mass.length; i++) {
if(i==((keys[j]-1)*(row)+c)){
if((mass.length%keys.length>0)&&(i==(mass.length-1))){
System.out.println("i = "+i);
result+=mass[i];
System.out.println("here");
j+=1000;
break;
}else{
System.out.println("i = "+i);
result+=mass[i];
}
}
}
}
return result;
}
@FXML
public void onCipherButtonClick(){
if(key.getText().equals("")){
Alert alert = new Alert(AlertType.ERROR);
alert.setTitle("Error");
alert.setHeaderText("Не заповнені всі поля");
alert.setContentText("Заповніть, будь ласка, всі поля.");
alert.showAndWait();
}else{
String resultString="";
char[] mess = message.getText().toCharArray();
int keys[] = new int[key.getText().length()];
int keysNew[] = new int[key.getText().length()];
int keyFrom = Integer.valueOf(key.getText());
for (int i = 0; i < key.getText().length(); i++) {
keys[key.getText().length()-i-1] = keyFrom%10;
keyFrom/=10;
}
for (int i = 0; i < keys.length; i++) {
keysNew[i] = keys[i];
}
Arrays.sort(keysNew);
for (int i = 0; i < keys.length; i++) {
resultString+=shufr(keys, mess, keysNew[i],key.getText().toCharArray().length);
}
result.setText(resultString);
}
}
@FXML
public void onReCipherButtonClick(){
if(key.getText().equals("")){
Alert alert = new Alert(AlertType.ERROR);
alert.setTitle("Error");
alert.setHeaderText("Не заповнені всі поля");
alert.setContentText("Заповніть, будь ласка, всі поля.");
alert.showAndWait();
}else{
String resultString="";
char[] mess = message.getText().toCharArray();
int keys[] = new int[key.getText().length()];
int keyFrom = Integer.valueOf(key.getText());
for (int i = 0; i < key.getText().length(); i++) {
keys[key.getText().length()-i-1] = keyFrom%10;
keyFrom/=10;
}
for (int i = 0; i < ((double)message.getText().length()/keys.length); i++) {
resultString+=deShufr(keys, mess, i,key.getText().toCharArray().length);
System.out.println(resultString);
}
result.setText(resultString);
}
}