티스토리 뷰



1. 암호 알고리즘

  네트워크 환경은 누구나 접속할 수 있는 만큼 외부의 공격도 당한다. 따라서 국가적 기밀이나 군사적 자료 등 보안이 중요한 자료들도 편의성을 위해 인터넷 환경으로 전달되곤 하는데, 이런 경우 무엇 보다도 보안 문제에 대한 고민이 절실하다. 그렇기에 우린 암호화 방식을 이용해 

이런 상황들에 대한 보완을 진행한다. 


  우리가 네트워크 상에서 작성된 평문을 일련의 암호화 알고리즘을 이용하여 암호문으로 변경하는 것이 기본적인 암호 매커니즘이다. 누군가에게 전달하고싶은 파일이 있는데, 이 파일을 암호화 시켜야 한다고 가정하자.

A 라는 사람은 B에게 암호문을 전달하게 되는데, 이 두사람은 서로 어떤 방법으로 암호화를 진행했는지 반드시 알아야 우리의 정보를 정확히 전달 해줄 수 있다. 이렇게 암호화를 하는데, 이 암호화를 가능하게 해주는 것이 바로 Key이다. 


  아주 단순한 개념인데, A라는 사람이 전달하고 싶은 문장을 암호화를 통해 전달하고자 한다면 다음과 같은 과정을 거친다.



  암호화와 복호화를 하기 위해서는 A와 B 두사람이 서로 공유하는 Key가 존재해야한다. 이 키가 암호화와 복호화 모두 같은 경우가 대칭형 암호화이고, 서로 다른 경우가 비대칭형 암호화이다.


2. 대칭 키 암호 (Symmetric-Key Algorithm)



  대칭 키 암호 알고리즘은 암호문을 전달하는 대상과 전달 받는 대상이 같은 키를 사용하는 방법이다. 기본적으로 둘은 같은 Key를 공유해야 하고, 은밀한 경로를 통해 A라는 사람은 B에게 키를 전달해주어야 한다. 이 키에 대한 정보가 외부로 새어나간다면 외부에서 공격당할수 있으므로 주의해야한다.


- 장점

  • 동일한 키로 암호화를 작업하므로, 암호화 수행이 매우 빠르고 설계도 비교적 간편하다.
  • 다른 암호화 방식보다 암호화 과정에서 정보 정확도가 높다.


- 단점

  • 암호화 문서를 공유할 대상 끼리 모두 동일한 Key를 가져야하는데 이 과정에서 외부로 키가 유출될 가능성이 존재한다.
  • 기타 암호화 알고리즘보다 보안성이 좋지 않다.


2.1 AES (Advanced Encryption Standard)


2001년 미국의 표준 기술 연구소에서는 대칭 키 암호 알고리즘을 활용한 새로운 암호 표준을 만들게 된다. 벨기에의 암호학자 존 대먼과 빈센트 라이먼이 AES 공모전에서 수상하게 되면서 새로운 암호화 표준 알고리즘이 만들어지게 된다. 기존의 암호화 알고리즘인 DES이 현대 컴퓨터 시스템에 맞지 않는 부분이 많아 새로 만들게 되었다.


AES 방식은 4가지 과정으로 이루어진다.


  • subbytes : 평문을 비트에 맞게 여러 블록으로 쪼갠 뒤, 기존에 작성된 표에 따라 값을 치환한다.
  • shiftrows : 치환된 블록을 일정한 규칙에 따라 ROW 별로 회전 시킨다.
  • mixcolumn : 블록 구조에서 Column 끼리 행렬 곱을 시킨다.
  • addroundkey : Key의 값에 따라 XOR 연산을 실시 한다. (실제 암호화 부분)


좀 더 자세한 AES 방법에 대해 알고 싶다면 위키백과를 찾으면 더 자세한 내용을 볼 수 있다.


- 위키 백과 : 고급 암호화 표준

https://ko.wikipedia.org/wiki/%EA%B3%A0%EA%B8%89_%EC%95%94%ED%98%B8%ED%99%94_%ED%91%9C%EC%A4%80


3. 공개 키 암호화

  공개 키 암호화 방식은 기본적으로 암호화와 복호화에 사용되는 키가 서로 다른 것을 의미한다. 따라서 공개 키 암호화 방식은 대표적인 비대칭키 암호화 방식이다.

 

  공개 키는 키에 존재를 누구나 확인 할 수 있지만, 해당 크의 암호화와 복호화에 사용되늗 비밀키를 가진 사람만이 해당 키를 열어 볼 수 있다. 그리고 암호화와 복호화에 사용되는 키가 달라 비밀키의 종류는 2개가 된다.

 

 

- 공개키 암호화의 특징

  • 암호화와 복호화의 키가 다르므로 알고리즘이 복잡하다
  • 암호화 과정에서 자원이 많이 소모된다
  • 대칭 키 암호화 과정보다 보안성이 높다
  • 접근 권한이 있는 사람이 자신의 키만 관리하면 되므로 키 관리가 매우 용이하다

  복잡한 알고리즘 설계에 접근 과정도 힘들지만 공개 키 암호화를 많이 사용하는 이유는 바로 보안성과 키 관리 측면에서 매우 뛰어나기 떄문이다.

 

4. 전송 계층 보안 (Transport Layer Security)

  네트워크 계층 중 응용 계층에서 전송 계층으로 데이터를 전송할 때, 전송 계층 종단에서 작동하는 통신 프로토콜을 전송 계층 보안, TLS라고 부른다. 클라이언트/서버 응용 프로그램을 사용할 때 TLS 덕분에 데이터 무결성을 보장 받을 수 있게 된다.


  보안 소켓에서 작동하기 때문에 과거에는 보안 소켓 레이어라는 (Security Socket Layer, SSL)라는 이름으로 불렸다. 웹 브라우저, 전자 메일 등 응용 프로그램에서 작동할 때 TLS에 따라 데이터를 주고 받는다. 


  전송 계층 보안은 다음과 같은 순서로 작동하게 된다.


1. 지원 가능한 알고리즘 교환


2. 키 교환, 인증


3. 대칭 키 암호로 인증


  웹 브라우저에서 아래와 같은 메세지가 나올 때 TLS 가 작동 된 것이다.


(출처 : 나무위키 - TLS)


  보편적으로 작동하는 HTTP 위에 TLS를 사용해서 통신하는 것을 HTTPS라고 한다. 네트워크 보완성을 위해 대부분의 웹 브라우저가 TLS의 동작을 지원하기 때문에 HTTPS는 웹 브라우저에서 가장 보편적으로 사용되는 프로토콜이라고 할 수 있다.


5. 보안 소켓 사용

  네트워크에서 사용되는 암호화 방식과 보안 소켓이 작동되는 프로토콜을 알게 되었으니 이제 자바 프로그램에 보안 프로그램을 사용할 수 있도록 추가해야한다. 이미 Java 라이브러리를 통해 보안 소켓에 대한 정의를 해놓았기 때문에 우리는 이 라이브러리를 통해 우리의 프로그램에 보안 소켓을 추가하면된다.


  자바에서는 JSSE(Java Security Socket Extension) 를 통해 보안 소켓의 확장을 제공한다. 보안 소켓은 서버와 클라이언트 2곳의 통신에서만 작동 되고 양 노드의 코드가 서로 다르게 된다. JSSE에 대한 자세한 정보는 자바 레퍼런스 가이드를 통해 확인 할 수 있다


- JSSE 자바 레퍼런스 가이드 (영어)

https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#Introduction


  보안 소켓을 사용하기 위해서는 다음과 같은 코드를 서버와 클라이언트에 작성하게 된다.


- 서버

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
 
public class EchoServer{
    public static void main(String[] args){
        try{
            SSLServerSocketFactory sslserversocketfactory = (SSLServerSocketFactory)SSLServerSocketFactory.getDefault();
            SSLServerSocket sslserversocket = (SSLServerSocket)sslserversocketfactory.createServerSocket(443);
            System.out.println("Wating Connection");
            while(true){
                SSLSocket socket = (SSLSocket)sslserversocket.accept();
                ThreadServer thread = new ThreadServer(socket);
                thread.start();
            }
        }catch(Exception ex){    System.out.println(ex);}
    }
}
 
class ThreadServer extends Thread{
    private SSLServerSocket sslsocket;
    private SSLSocket socket;
    private InputStream input;
    private InputStreamReader reader;
    private BufferedReader br;
 
    public ThreadServer(SSLSocket socket){
        this.socket = socket;
    }
 
    public void run(){
        try{
            String fromClient = null;
            input = socket.getInputStream();
            reader = new InputStreamReader(input);
            br = new BufferedReader(reader);
 
            while((fromClient = br.readLine())!=null){
                System.out.println(fromClient);
                System.out.flush();
            }
        }catch(Exception e){
        }
    }
}

cs

 


- 클라이언트


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory; 
import java.io.*
 
public class EchoClient {
    public static void main(String[] arstring) {
        try { 
            SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
            SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket("localhost"9999); 
 
            InputStream inputstream = System.in
            InputStreamReader inputstreamreader = new InputStreamReader(inputstream); 
 
            BufferedReader bufferedreader = new BufferedReader(inputstreamreader); 
            OutputStream outputstream = sslsocket.getOutputStream(); 
            OutputStreamWriter outputstreamwriter = new OutputStreamWriter(outputstream); 
            BufferedWriter bufferedwriter = new BufferedWriter(outputstreamwriter); 
 
            String string = null
 
            while ((string = bufferedreader.readLine()) != null) { 
                bufferedwriter.write(string + '\n'); 
                bufferedwriter.flush(); 
                } 
        }
         catch (Exception exception) { 
            exception.printStackTrace(); 
        } 
    } 
}
 

cs


'Skill > Programming - Network' 카테고리의 다른 글

19. Java NIO (New IO)  (0) 2019.09.11
18. 서버 소켓 프로그래밍 예제 (Java)  (0) 2019.09.08
16. 서버 소켓  (0) 2019.08.16
15. 클라이언트 소켓  (0) 2019.08.04
14. HTTP 쿠키 (Cookie)  (0) 2019.07.28
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함