Uploaded by ybrbnf2013n

Отчёт по ЛР 3. Яковлев

advertisement
ФЕДЕРАЛЬНОЕ АГЕНТСТВО ЖЕЛЕЗНОДОРОЖНОГО ТРАНСПОРТА
Федеральное государственное бюджетное образовательное учреждение
высшего образования
«Петербургский государственный университет путей сообщения
Императора Александра I»
(ФГБОУ ВО ПГУПС)
Факультет «Автоматизация и интеллектуальные технологии»
Кафедра «Информатика и информационная безопасность»
Лабораторная работа № 3
по дисциплине
«Защита информации»
«Реализация функций шифрования и обмена ключами шифрования в программах на языке
Java»
Выполнил обучающийся
Курс 4
Группа ИВБ-711
Н. Д. Яковлев
М. Ф. Соломатова
Проверил
Санкт-Петербург
2022
Оценка лабораторной работы
Показатель
оценивания
Критерии
Шкала
оценивания
оценивания
Представленное программное
обеспечение работоспособно,
3
выполняет требуемые функции
Работоспособность программного
обеспечения
Программное обеспечение не
работоспособно или не
0
выполняет требуемые функции
Замечания отсутствуют, либо
обнаруженные недостатки
устраняются студентом в
2
течение лабораторного
занятия, на котором работа
представляется к сдаче
Замечания к разработанному
программному обеспечению
Имеются недостатки в
результатах работы, не
устраненные студентом в день
0
сдачи лабораторной работы (в
течение лабораторного
занятия)
Количество баллов по результатам проверки и защиты лабораторной
работы (вписывается преподавателем)
1. Задание
1. Разработать два приложения:

приложение-сервер – выполняет функцию генерации и экспортирования
ключей алгоритма RSA, а также симметричного шифрования;

приложение-клиент – импортирует ключи, генерируемые серверным
приложением, расшифровывает сообщение.
Примечание. Обмен ключами может производиться путем передачи BLOB через
сетевое соединение между компьютерами по локальной сети (используются TCP-сокеты)
или через файл на общедоступном диске.
2. Реализовать в приложении-сервере возможность расшифрования (развертки)
симметричных ключей на закрытом ключе RSA.
3. Реализовать в приложении-клиенте возможность зашифрования (свертки)
симметричных ключей на открытом ключе RSA.
4. В обоих приложениях реализовать функцию симметричного шифрования на
общем секретном ключе.
5. Проверить работоспособность приложений:

сгенерировать пару «открытый-закрытый ключ»;

передать открытый ключ клиентскому приложению;

сгенерировать симметричные ключи шифрования (генерация производится
на клиентской стороне; ключи генерируются для использования в
симметричных шифрах, указанных в варианте задания);

передать серверу симметричные ключи, зашифрованные с помощью
открытого ключа по алгоритму RSA;

на серверной стороне – расшифровать симметричные ключи, после чего
зашифровать произвольное сообщение;

передать зашифрованные данные клиенту;

на клиентской стороне – расшифровать полученные данные.
Если открытые и расшифрованные данные совпадают, значит,
криптографические функции в приложениях реализованы правильно.
все
2. Выполнение
В ходе выполнения лабораторной работы разработано программное обеспечение,
демонстрирующее работу алгоритмов шифрования RSA и AES.
Исходный текст разработанного программного обеспечения на языке Java выглядит
следующим образом:
Server.java – Приложение-сервер:
import java.awt.*;
import java.awt.event.*;
import java.security.*;
import javax.crypto.*;
import java.util.concurrent.TimeUnit;
import java.util.Arrays;
import java.util.Base64;
import java.io.*;
import java.net.*;
import javax.crypto.spec.SecretKeySpec;
public class Server extends Panel
{
String path;
Label L1,L2,L3;
Button B1,B2;
TextField T1;
SecretKey secretKey;
KeyPair keyPair;
public Server(){
try{
path
=
new
File(Server.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getPath();
}catch(URISyntaxException e){System.out.println(e.getMessage());}
try{
SecureRandom secureRandom = new SecureRandom();
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048, secureRandom);
keyPair = keyPairGenerator.generateKeyPair();
}catch(Exception e){System.out.println(e.getMessage());}
setLayout(new BorderLayout());
Panel p1 = new Panel();
this.add(p1,BorderLayout.CENTER);
L1 = new Label("Введите сообщение и нажмите \"Enter\" для отправки:");
p1.add(L1);
T1 = new TextField(70);
p1.add(T1);
L2 = new Label("
");
p1.add(L2);
T1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
String message = e.getActionCommand();
T1.setText("");
try{
cipherWrite(message, path + "/data.txt", secretKey);
L2.setText("Отправлено");
try{TimeUnit.SECONDS.sleep(2);}catch(InterruptedException
re){System.out.println(re.getMessage());}
L2.setText("");
}catch(Exception ex){
L3.setText("Исключение: " + ex.getMessage());
System.out.println(ex.getMessage());
try{TimeUnit.SECONDS.sleep(2);}catch(InterruptedException
re){System.out.println(re.getMessage());}
L3.setText("Получите симметричный ключ");
}
}
});
B1 = new Button("Отправить открытый ключ");
B1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae){
try{
sendPublicKey(path + "/key.txt", keyPair.getPublic());
L2.setText("Отправлено");
L3.setText("Открытый ключ: " + keyPair.getPublic());
try{TimeUnit.SECONDS.sleep(2);}catch(InterruptedException
re){System.out.println(re.getMessage());}
L2.setText("");
L3.setText("");
}catch(Exception
ex){L3.setText("Исключение:
"
+
ex.getMessage()); System.out.println(ex.getMessage());}
}
});
p1.add(B1);
B2 = new Button("Получить симметричный ключ");
B2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae){
try{
byte[] encodedKey = readKey(path + "/symKey.txt",
keyPair.getPrivate());
byte[]
decodedKey
=
Base64.getDecoder().decode(Base64.getEncoder().encodeToString(encodedKey));
secretKey = new SecretKeySpec(decodedKey, "AES");
L3.setText("Симметричный ключ: " + secretKey);
}catch(Exception ex){
L3.setText("Исключение: " + ex.getMessage());
System.out.println(ex.getMessage());
try{TimeUnit.SECONDS.sleep(2);}
catch(InterruptedException
re){System.out.println(re.getMessage());}
L3.setText("Симметричный ключ не был отправлен");
}
}
});
p1.add(B2);
L3 = new Label("");
this.add(L3,BorderLayout.SOUTH);
}
public
void
sendPublicKey(String
path,
PublicKey
publicKey)
FileNotFoundException, IOException{
FileOutputStream writer = new FileOutputStream(path);
writer.write(publicKey.getEncoded());
writer.flush();
writer.close();
throws
}
public byte[] readKey(String path, PrivateKey privateKey) throws Exception{
byte[] buf = new byte[128];
int c;
FileInputStream reader = new FileInputStream(path);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
CipherInputStream readerCipher = new CipherInputStream(reader,
cipher);
while((c = readerCipher.read(buf))>0){
if(c < 128) buf = Arrays.copyOf(buf, c);
}
return buf;
}
public void cipherWrite(String message, String path, SecretKey secretKey) throws
Exception{
byte[] b = message.getBytes();
FileOutputStream writer = new FileOutputStream(path);
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
CipherOutputStream writerCipher = new CipherOutputStream(writer,
cipher);
writerCipher.write(b);
writerCipher.flush();
writerCipher.close();
}
public static void main(String args[]){
Server panel = new Server();
Frame frame = new Frame("Server");
frame.add(panel);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
frame.setSize((int)screenSize.getWidth()/2-20, (int)screenSize.getHeight()/4);
frame.setLocation(10, 10);
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
}
}
Client.java – Приложение-клиент:
import java.awt.*;
import java.awt.event.*;
import java.security.*;
import javax.crypto.*;
import java.util.concurrent.TimeUnit;
import java.util.Arrays;
import java.util.Base64;
import java.io.*;
import java.net.*;
import java.security.spec.X509EncodedKeySpec;
public class Client extends Panel
{
String path, oldLastLine = "";
Label L1,L2;
Button B1,B2,B3;
SecretKey secretKey;
PublicKey public_key;
public Client(){
try{
path = new
File(Client.class.getProtectionDomain().getCodeSource().getLocation().toURI()).getPath();
}catch(URISyntaxException ex){System.out.println(ex.getMessage());}
setLayout(new BorderLayout());
Panel p1 = new Panel();
this.add(p1,BorderLayout.CENTER);
L1 = new Label("
");
p1.add(L1);
B1 = new Button("Получить открытый ключ");
B1.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae){
try{
KeyFactory factory = KeyFactory.getInstance("RSA");
public_key = factory.generatePublic(new
X509EncodedKeySpec(readKey(path + "/key.txt")));
L2.setText("Открытый ключ: " + public_key);
try{TimeUnit.SECONDS.sleep(2);}catch(InterruptedException
re){System.out.println(re.getMessage());}
L2.setText("");
}catch(Exception ex){
L2.setText("Исключение: " + ex.getMessage());
System.out.println(ex.getMessage());
try{TimeUnit.SECONDS.sleep(2);}catch(InterruptedException
re){System.out.println(re.getMessage());}
L2.setText("Открытый ключ не был отправлен");
}
}
});
p1.add(B1);
B2 = new Button("Отправить симметричный ключ");
B2.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae){
try{
KeyGenerator keyGenerator =
KeyGenerator.getInstance("AES");
secretKey = keyGenerator.generateKey();
sendKey(secretKey, path + "/symKey.txt", public_key);
L2.setText("Симметричный ключ: " + secretKey);
L1.setText("Отправлено");
try{TimeUnit.SECONDS.sleep(2);}catch(InterruptedException
re){System.out.println(re.getMessage());}
L1.setText("");
}catch(Exception ex){
L2.setText("Исключение: " + ex.getMessage());
System.out.println(ex.getMessage());
try{TimeUnit.SECONDS.sleep(2);}catch(InterruptedException
re){System.out.println(re.getMessage());}
L2.setText("Получите открытый ключ");
}
}
});
p1.add(B2);
B3 = new Button("Проверить почту");
B3.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent ae){
try{
L2.setText("Сообщение: " + readCipher(path + "/data.txt",
secretKey));
}catch(Exception ex){
L2.setText("Нет новых сообщений");
System.out.println(ex.getMessage());
try{TimeUnit.SECONDS.sleep(2);}catch(InterruptedException
re){System.out.println(re.getMessage());}
L2.setText("");
}
}
});
p1.add(B3);
L2 = new Label("");
this.add(L2,BorderLayout.SOUTH);
}
public void sendKey(Key key, String path, PublicKey public_key) throws Exception{
FileOutputStream writer = new FileOutputStream(path);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, public_key);
CipherOutputStream writerCipher = new CipherOutputStream(writer,
cipher);
writerCipher.write(key.getEncoded());
writerCipher.flush();
writerCipher.close();
}
public String readCipher(String path, Key key) throws Exception{
String lastLine = "Нет новых сообщений";
FileInputStream reader = new FileInputStream(path);
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, key);
CipherInputStream readerCipher = new CipherInputStream(reader, cipher);
byte[] buf = new byte[256];
int c;
while((c = readerCipher.read(buf))>0){
if(c < 256) buf = Arrays.copyOf(buf, c);
lastLine = new String(buf);
if(lastLine.equals(oldLastLine)){
lastLine = "Нет новых сообщений";
throw new Exception();
}
else oldLastLine = lastLine;
}
return lastLine;
}
public byte[] readKey(String path) throws Exception{
byte[] buf = new byte[2048];
int c;
FileInputStream reader = new FileInputStream(path);
while((c = reader.read(buf))>0){
if(c < 2048) buf = Arrays.copyOf(buf, c);
}
return buf;
}
public static void main(String args[]){
Client panel = new Client();
Frame frame = new Frame("Client");
frame.add(panel);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
frame.setSize((int)screenSize.getWidth()/2-20, (int)screenSize.getHeight()/4);
frame.setLocation((int)screenSize.getWidth()/2+10, 10);
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.exit(0);
}
});
}
}
Результат тестирования разработанного программного обеспечения:
Вывод
В результате выполнения данной лабораторной работы можно сделать вывод о том,
что алгоритмы шифрования AES и RSA могут быть реализованы с помощью языка
программирования Java.
Download