МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ “ЛЬВІВСЬКА ПОЛІТЕХНІКА”
Кафедра ЕОМ
Звіт
до лабораторної роботи № 6-7
з дисципліни: “ Захист інформації в комп’ютерних системах ”
на тему: СУЧАСНІ КОМП’ЮТЕРИЗОВАНІ МЕТОДИ ШИФРУВАННЯ ТА ДЕШИФРУВАННЯ ТЕКСТОВИХ ПОВІДОМЛЕНЬ
Мета: дослідження статистичних властивостей відкритого тексту та шифрованого тексту, вивчення простих методів шифрування та дешифрування інформації та їх властивостей для сучасних шифрів, які використовуються із застосуванням комп’ютерної техніки.
ЗАВДАННЯ
1. Ознайомитися із методами шифрування, описаними у коротких теоретичних відомостях.
2. Розробити програми для шифрування і дешифрування текстів шифром Хілла із використанням маскуючи символів із врахуванням, що:
мова програмування – за вибором студента;
відкритий текст (ВТ) для шифрування – довільний (за вибором студента);
для шифрування ВТ з допомогою шифру Хілла використовувати ключ, який формується з латинських букв (ключ повинен відповідати прізвищу студента). Довжина блоку для шифрування 3 символи. Довжина ключа - 9 символів (матриця 3х3). Якщо прізвище складається з меншої кількості букв, то використати перші літери імені студента. Якщо матриця ключ не має оберненої, то необхідно змінити декілька букв в матриці-ключі;
множення матриці ключа на матрицю ВТ виконувати у вигляді числових еквівалентних матриць. Обчислити обернену матрицю. Повне виведення оберненої матриці привести в звіті і виконати перевірку АЧА-1 = 1, де 1 – це одинична матриця;
варіант стосовно структури і методу використання маскувальних символів обирається відповідно до таблиці:
3. Для відкритого і шифрованого тексту виконати повний статистичний аналіз і привести графіки у звіті. На одному графіку побудувати характеристики з однаковим масштабом за спаданням частоти повторення кожного символу. Зробити висновки за результатами статистичного аналізу ШТ і ВТ.
4. Оформити та захистити звіт. У звіті обов’язково навести усі програми, які використані для шифрування та дешифрування, а також побудовані графіки. Зробити висновки за результатами статистичного аналізу ШТ і ВТ. Оцінити складність процедури шифрування і дешифрування.
Варіант:
3
3
статичний
{ vi; mi; vi}
Хід роботи
Лістинг програми:
package sample;
import java.io.*;
import java.util.Random;
public class HillCipher {
private StringBuilder finalRes = new StringBuilder();
public static String abc = " abcdefghijklmnopqrstuvwxyz";
public static StringBuilder builder = new StringBuilder();
public String randomLettersGenerator(String text) {
String str = "";
Random random = new Random();
char[] ptextchars = text.toCharArray();
int randomNum;
if (text.length() % 2 == 0) {
for (int i = 0; i < ptextchars.length; i += 2) {
randomNum = random.nextInt(('Z' - 'A') + 1) + 'A';
str += String.valueOf(ptextchars[i]) + String.valueOf((char) randomNum) + String.valueOf(ptextchars[i + 1]);
}
} else {
for (int i = 0; i < ptextchars.length - 1; i += 2) {
randomNum = random.nextInt(('Z' - 'A') + 1) + 'A';
str += String.valueOf(ptextchars[i]) + String.valueOf((char) randomNum) + String.valueOf(ptextchars[i + 1]);
}
str += ptextchars[ptextchars.length - 1];
}
return str;
}
public String getOriginalText(String text){
StringBuilder str = new StringBuilder();
str.append(text.charAt(0));
if (text.length() % 2 == 0) {
for (int i = 2; i < text.length(); i += 2) {
str.append(text.charAt(i)).append(text.charAt(++i));
}
} else {
for (int i = 2; i < text.length() - 1; i += 2) {
str.append(text.charAt(i)).append(text.charAt(++i));
}
str.append(text.charAt(text.length() - 1));
}
return str.toString();
}
public String getFinalRes() {
return finalRes.toString();
}
public void makeStatistics(String text, String decryptText, String nameStatisticsFile) {
double[] numberLettersTextMessage = new double[26];
double[] numberLettersDecryptText = new double[26];
double[] frequencyLettersTextMessage = new double[26];
double[] frequencyLettersDecryptText = new double[26];
double countLetters1 = 0;
double countLetters2 = 0;
char[] arrLetters = {'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
char[] arrText = text.toCharArray();
char[] arrDecryptText = decryptText.toCharArray();
for (int i = 0; i < 26; i++) {
numberLettersTextMessage[i] = 0;
numberLettersDecryptText[i] = 0;
}
for (int i = 0; i < arrText.length; i++) {
for (int j = 0; j < arrLetters.length; j++) {
if (arrText[i] == arrLetters[j]) {
numberLettersTextMessage[j]++;
countLetters1++;
continue;
}
}
}
for (int i = 0; i < arrDecryptText.length; i++) {
for (int j = 0; j < arrLetters.length; j++) {
if (arrDecryptText[i] == arrLetters[j]) {
numberLettersDecryptText[j]++;
countLetters2++;
continue;
}
}
}
File file = new File(nameStatisticsFile);
try (FileWriter writer = new FileWriter(file, false)) {
writer.write("Частоти появи літер");
writer.write(System.lineSeparator());
writer.write("Літера - Текст - Шифротекст");
writer.write(System.lineSeparator());
for (int i = 0; i < 26; i++) {
frequencyLettersTextMessage[i] = numberLettersTextMessage[i] // countLetters1;
frequencyLettersDecryptText[i] = numberLettersDecryptText[i] // countLetters2;
writer.write(arrLetters[i] + " - " +
frequencyLettersTextMessage[i] + " - " + frequencyLettersDecryptText[i]);
writer.write(System.lineSeparator());
}
} catch (IOException e) {
e.printStackTrace();
}
}
private int keymatrix[][];
private int linematrix[];
private int resultmatrix[];
public int[][] getKeymatrix() {
return keymatrix;
}
public void divide(String temp, int s) {
while (temp.length() > s) {
String sub = temp.substring(0, s);
temp = temp.substring(s, temp.length());
perform(sub);
}
if (temp.length() == s)
perform(temp);
else if (temp.length() < s) {
for (int i = temp.length(); i < s; i++)
temp = temp + ' '; //'x'
perform(temp);
}
}
public void perform(String line) {
linetomatrix(line);
linemultiplykey(line.length());
result(line.length());
}
public void keytomatrix(String key, int len) {
keymatrix = new int[len][len];
int c = 0;
for (int i = 0; i < len; i++) {
for (int j = 0; j < len; j++) {
keymatrix[i][j] = ((int) key.charAt(c)) - 97;
c++;
}
}
}
public void linetomatrix(String line) {
linematrix = new int[line.length()];
for (int i = 0; i < line.length(); i++) {
linematrix[i] = abc.indexOf(line.charAt(i));//((int) line.charAt(i)) - 97;
}
}
public void linemultiplykey(int len) {
resultmatrix = new int[len];
for (int i = 0; i < len; i++) {
for (int j = 0; j < len; j++) {
resultmatrix[i] += keymatrix[i][j] * linematrix[j];
}
resultmatrix[i] %= 26;
}
}
public void result(int len) {
String result = "";
for (int i = 0; i < len; i++) {
result += abc.charAt(resultmatrix[i]);//(char) (resultmatrix[i] + 97);
builder.append(abc.charAt(resultmatrix[i]));//(char) (resultmatrix[i] + 97));
}
System.out.print(result);
finalRes.append(result);
}
public boolean check(String key, int len) {
keytomatrix(key, len);
int d = determinant(keymatrix, len);
d = d % 26;
if (d == 0) {
System.out.println("Key is not invertible because determinant = 0...");
return false;
} else if (d % 2 == 0 || d % 13 == 0) {
System.out.println("Key is not invertible because determinant has common factor with 26...");
return false;
} else {
return true;
}
}
public int determinant(int A[][], int N) {
int res;
if (N == 1)
res = A[0][0];
else if (N == 2) {
res = A[0][0] * A[1][1] - A[1][0] * A[0][1];
} else {
res = 0;
for (int j1 = 0; j1 < N; j1++) {
int m[][] = new int[N - 1][N - 1];
for (int i = 1; i < N; i++) {
int j2 = 0;
for (int j = 0; j < N; j++) {
if (j == j1)
continue;
m[i - 1][j2] = A[i][j];
j2++;
}
}
res += Math.pow(-1.0, 1.0 + j1 + 1.0) * A[0][j1]
* determinant(m, N - 1);
}
}
return res;
}
public String cofact(int num[][], int f) {
int b[][], fac[][];
b = new int[f][f];
fac = new int[f][f];
int p, q, m, n, i, j;
for (q = 0; q < f; q++) {
for (p = 0; p < f; p++) {
m = 0;
n = 0;
for (i = 0; i < f; i++) {
for (j = 0; j < f; j++) {
b[i][j] = 0;
if (i != q && j != p) {
b[m][n] = num[i][j];
if (n < (f - 2))
n++;
else {
n = 0;
m++;
}
}
}
}
fac[q][p] = (int) Math.pow(-1, q + p) * determinant(b, f - 1);
}
}
return trans(fac, f);
}
String trans(int fac[][], int r) {
int i, j;
int b[][], inv[][];
b = new int[r][r];
inv = new int[r][r];
int d = determinant(keymatrix, r);
int mi = mi(d % 26);
mi %= 26;
if (mi < 0)
mi += 26;
for (i = 0; i < r; i++) {
for (j = 0; j < r; j++) {
b[i][j] = fac[j][i];
}
}
for (i = 0; i < r; i++) {
for (j = 0; j < r; j++) {
inv[i][j] = b[i][j] % 26;
if (inv[i][j] < 0)
inv[i][j] += 26;
inv[i][j] *= mi;
inv[i][j] %= 26;
}
}
System.out.println("\nInverse key:");
return matrixtoinvkey(inv, r);
}
public int mi(int d) {
int q, r1, r2, r, t1, t2, t;
r1 = 26;
r2 = d;
t1 = 0;
t2 = 1;
while (r1 != 1 && r2 != 0) {
q = r1 / r2;
r = r1 % r2;
t = t1 - (t2 * q);
r1 = r2;
r2 = r;
t1 = t2;
t2 = t;
}
return (t1 + t2);
}
public String matrixtoinvkey(int inv[][], int n) {
String invkey = "";
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
invkey += (char) (inv[i][j] + 97);
}
}
System.out.print(invkey);
return invkey;
}
}
Статистичний аналіз відкритого і зашифрованого тексту:
Результат:
/
Рис. 1. Графік частот повторення кожного символу відкритого тексту
/
Рис. 2. Графік частот повторення кожного символу шифротексту
/
/
Рис. 3. Результат виконання програми
Висновок
Під час виконання даної лабораторної роботи я реалізував шифр Хілла із додаванням маскуючих символів та провів частотний аналіз символів відкритого та зашифрованого тексту.