# 10. Secure Socket

#### 보안소켓

통신을 함에 있어서 도청과 같은 스누핑(snooping)을 방지해야함.

SSL, TLS 프로토콜과 관련된 암호화 알고리즘을 사용하여 소켓 암호화를 통해 보안을 강화.

* 보안 소켓 계층(SSL)
  * confidential과 인증의 다양한 수준을 사용해 TCP 클라이언트들이 HTTP 또는 TCP 서버들과 대화를 가능하게 하는 보안 프로토콜
* 전송 계층 보안(TLS)

***

#### 보안 통신

* 키값이 커질수록 brute-force attack 에 안전해지긴 함
* 비밀키 암호화 방식(대칭키 암호화)
  * 데이터를 암호화하고 복호화하는 데 같은 키가 사용된다.
* 공개키 암호화 방식(비대칭키 암호화)
  * 데이터를 암호화하고 복호화하는 데 다른 키가 사용된다.
  * 또한 인증과 무결성 검사에도 사용될 수 있다.
    * A와 B가 데이터를 주고 받음
    * B는 A의 공개키로 데이터를 암호화함.(B의 개인키가 있어야 데이터 복호화가 가능)
    * 추가로 A의 개인키로 암호화를 한번 더 함(B가 받을 때 A한테서 받았다는 인증)
    * 그러면 B는 A의 공개키로 복호화(A인증) , B의 개인키로 복호화(데이터 확인) 와 같은 과정

→ 링크 : <https://app.gitbook.com/o/PXSiL0xh2WRWMEyGmi4J/s/bEdan4W9LJw2zUmbk95v/readme/web-security/ssh>

#### 보안 클라이언트 소켓 만들기

java.net.Socket 객체를 생성하는 대신 javax.net.ssl.SSLSocketFactory로부터 createSocke()메서드를 사용, 소켓 객체를 얻을 수 있다.

* SSLSocketFactory는 추상 팩토리 디자인 패턴을 따르는 추상 클래스

```java
public abstract class SSLSocketFactory extends SocketFactory
```

* 정적 메서드인 getDefault를 호출 → SSLSocketFactory의 인스턴스를 얻을 수 있음

```java
public static SocketFactory getDefault()...

SocketFactory factory = SSLSocketFactory.getDefault();
Socket socket = factory.createSocket("login.abc.com", 7000);
```

#### 암호화 조합 선택하기

* DES/AES 는 블록 암호 알고리즘 → 여러 비트를 한번에 암호화 함
* DES는 항상 64비트 단위로 암호화를 함
* AES는 128, 192, 256비트 단위의 블록을 암호화할 수 있음. 블록 크기의 배수가 안되면 모자란 비트만큼 덧붙여서 인코딩 함
* RC4는 한번에 1바이트씩 암호화가 가능 → 한번에 1바이트씩 전송이 필요한 프로토콜에서 사용하기 적합함

#### 이벤트 핸들러

클라이언트와 서버 사이의 연결이 완료될 때, handshake-complete 이벤트 알림을 받기 위해서는*HandshakeCompletedListener* 인터페이스를 구현하기만 하면 된다.

```java
public interface HandshakeCompletedListener extends EventListener
```

#### 세션 관리

일반적으로 웹 연결은 일시적이며 모든 페이지는 분리된 소켓을 통해 요청된다.

* 세션을 통해 동일한 같은 공개키/개인키 조합을 사용

#### 클라이언트 모드

* 일반적으로 대부분의 보안 통신에서 서버는 인증을 해야함. 근데 클라이언트는 아님

```java
public abstract class SSLServerSocket extends ServerSocket 
```

* `setUseClientMode()` 메서드는 첫 핸드세이크 시에 인증이 필요한지 여부를 결정
  * client와 server 모두에서 사용 가능. true→인증 제공X, false→인증 시도
  * 한번만 설정, 두번째부턴 예외 발생.

#### 보안 서버 소켓 만들기

#### SSLServerSocket 설정하기

```java
public abstract class SSLSocket extends Socket 

public abstract class SSLServerSocket extends ServerSocket 
```

* SSLSocket과 같이 SSLServerSocket도 암호화 조합을 선택, 세션을 관리, 클라이언트가 스스로 인증이 필요한지를 결정하는 메서드를 제공함.
* 서버측에서 동작한다는 것이 차이
* 암호화 조합 선택 가능
* 세션관리 가능

  * 세션 설정을 위해서는 클라이언트와 서버 양쪽에서 동의가 필요
  * 서버쪽에서는 setEnableSessionCreation() 메서드로 허용 여부 설정
  * getEnableSessionCreation() 메서드로 허용 여부 판단.
  * 세션은 기본적으로 허용
  * 서버에서만 세션을 거부하면, 세션 생성을 원하는 클라이언트는 여전히 연결할 수 있음. 다만 세션을 얻지 못하고 모든 소켓에 대해 계속 handshake를 해야함.
  * 클라이언트에서만 세션을 거부하면, 대화는 할 수 있지만 세션을 생성할 수 없음.

  ```java
      public abstract void setEnableSessionCreation(boolean var1);

      public abstract boolean getEnableSessionCreation();
  ```
