https://100100e.tistory.com/317
이분이 그림도 그려놓고 아주 잘 설명해놓으셨다.
대칭키 방식
- A<->B 통신시 암호화를 위해 대칭키를 사용할 수 있다.
- 암호화, 복호화에 필요한 키가 동일하여 대칭키라 불린다.
- 암호화하여서 보낸 패킷을 중간에 가로채도 알아볼수없다.
- 하지만 키 자체가 한번은 통신으로 이동해야 하기 때문에 그중에 탈취되면 원본을 알아볼수 있게 된다.
- AES256
비대칭키 방식
- 서버에서 public key, private key를 발급한다. 둘은 소수를 이용해서 어쩌고 만든다.
- private key는 암호화, public key는 복호화에 사용된다.
- 클라이언트에게 public key를 건네준다.
- 서버에 데이터(ex. 로그인 중 password)를 전송시 public key를 이용해 암호화하여 송신한다.
- 제3자가 public key를 탈취했다하더라도 복호화에 사용할 수 없으므로 원본 password는 알아낼수없다.
- 서버에선 전송받은 데이터를 private key를 이용해 복호화한다. (ex. password 원본으로 변경하여 DB에서 조회한다)
- 대칭키 방식에 비해 암,복호화 속도가 느리다.
- RSA
인증서
- public key를 내가 정말 Request를 보내고자하는 서버로부터 발급받으면 상관없지만
3자가 서버인척하고 private key, public key를 발급후 public key를 내주면 그걸로 암호화한 데이터를 3자에게 보내게 되고 3자는 private key를 이용해 복호화하여 원본데이터를 알아낼 수 있다. (password) - 강력한 RSA를 이용해서 암호화한 데이터를 보냈다고 방심하지만 결국 public key 자체부터가 썩은 것이다.
- 이를 방지하고자 서버는 CA기관에 public key를 위탁하고 클라이언트는 CA로부터 public key를 받게된다.
- 내가 집에서 만든 서버로 RSA를 구현해서 클라이언트에게 전달해준다면 그건 곧 사설인증서가 되는거고
클라이언트쪽에선 브라우저에 warning이라는 문구가 뜨면서 신뢰할 수 없는데 괜찮겠냐는 메시지가 뜬다.
TLS
- 비대칭키 방식을 이용해서 쭉 모든 통신을 하면 좋겠지만 암,복호화 속도가 대칭키에 비해 낮다.
그 한계를 어떻게 극복하냐면 - public key를 받은 후 클라이언트는 대칭key를 서버에 암호화하여 전송한다. (세션키 라고불린다)
- 서버는 private key를 이용해 클라이언트로부터 전달받은 대칭key를 복호화하여 저장한다.
- 이제 대칭키를 서로 알게되었으니 패킷을 대칭key를 이용해 암호화 통신한다.
대칭키 방식의 취약점이 키가 탈취되면 끝장난다는 것인데
처음에 public key로 암호화하여 전송하였으니 제3자가 알아낼 수가 없다. - 이렇게 비대칭키 방식+대칭키 방식을 장점을 버무려서 사용하는 방식이 TLS이고 SSL이라고도 불린다.
HTTPS
- 기존 HTTP는 패킷이 암호화되어있지 않기 때문에 wireshark같은 툴로도 훔쳐서 안의 내용을 보기가 쉽다.
- TLS 보안방식을 적용시켜서 HTTP 패킷 자체를 암호화하면 HTTPS라고 불리는 것이다.
- 제대로된 HTTPS 통신 서버를 만드려면 CA기관에 돈주고 public key를 줘야하기도 하고
패킷을 받을 때마다 복호화해야하기 때문에 비용이 든다. - 사용자 password같은 민감한 정보를 제외하고 나머지 내용은 까봐도 별 의미없다고 생각되면 그냥 HTTP 통신을 사용하고, 그 패킷 안의 일부 민감한 정보만 RSA를 이용해 암,복호화 할 수 있다.
- 별 의미없다고 생각되는 내용일지라도 패킷이 훤히 들여다보인다면 고수에게 기가 막힌 방식으로 서버가 공격받을 수 있다. 괜히 HTTPS를 사용하는게 아니다.
HASH
- Hash Function을 이용한 단방향 암호화 방식이다.
- 보통 통신에 사용되는 암호화 방식은 주는 사람이 암호화하고 , 받는 사람이 복호화할 수 있어야 하는데 얘는 한번 암호화하면 끝이다.
- 하지만 얘도 쓸 데가 있다.
- 서버는 사용자의 정보 (ex. password)를 DB에 저장한다.
- 백날 대칭키 비대칭키 이용해서 데이터를 훔쳐보지 못하게 하지만 DB에서 원본 데이터가 털려버린다면 끝이다.
- 따라서 서버에선 복호화한 데이터(password)를 그대로 DB에 저장하고 비교하면 안된다.
- 이때 Hash를 사용해서 password를 암호화하고 DB에 저장한다.
서버 : password -> DB : 요상한값 - 저장할 때(회원가입) 사용한 Hash Function이랑 조회할 때(로그인) 사용한 Hash Function만 같으면 된다.
- 가끔 Hash Function이 내뱉는 암호화된 값이 중복된다는 문제가 있다고 한다. 이 말은 곧 정확한 password말고 다른 값들로 로그인을 할 수도 있고, 정확히 password를 입력했으나 로그인이 실패할수 있다는 말이 된다.
- 이를 방지하기 위해 Hash Function으로 나온 값에 Salt값을 또 더해서 다시 Hash Function에 넣고 이중으로 처리하는 방식이 있다.
- 소금을 친다.