디지털 암호화
대칭키 암호체계
$$ E_{k}(p)=c\\ D_{k}(c)=p $$
E : encrypt function
D : decrypt function
k : secret key
p : plain text
c : cipher text
인코딩과 디코딩에 같은 키를 사용한다.
비대칭키 방식보다는 컴퓨팅 파워가 덜 들지만, 각 호스트쌍 마다 각각의 비밀키를 나눠가져야 하고 이 비밀키를 탈취당하면 제3자도 메세지를 암호화, 복호화할 수 있게된다.
대칭키 알고리즘으로는 AES, CHACHA20_POLY1305, DES, Triple-DES, RC2, RC4, Camelia, ARIA 등이 있다.
( * 현재 제일 많이 쓰이는 건 AES, CHACHA20_POLY1305는 2015년에 발표된 속도가 더 빨라진 차세대 알고리즘이고, 나머지는 outdated, not secure...라고 한다 특히 DES, RC4 )
비대칭키 암호체계
$$ E_{pk}(p)=c\\ D_{sk}(c)=p $$
pk : public key
sk : private secret key
두개의 비대칭키를 사용한다.
인코딩 키는 모두에게 공개되어 있고(공개키), 호스트만이 개인 디코딩키를(비공개키) 알고 있다.
모든 사람이 X에게 보내는 메세지를 같은 키로 인코딩 할 수 있지만, X를 제외한 누구도 그 메세지를 디코딩할 수 없다. 왜냐하면 오직 X만이 디코딩 개인 키 $d^x$를 갖고 있기 때문이다.
키의 분리는, 메세지의 인코딩은 누구나 할 수 있도록 해주는 동시에, 메세지를 디코딩하는 능력은 소유자에게만 부여한다. - 『HTTP 완벽가이드』, p364
비대칭키(공개키)암호화 방식의 단점은 계산이 느린편이라는 것이다.
공개키 알고리즘으로는 RSA, ECC (Elliptic curve cryptography - modern successor of RSA) 등이 있다.
디지털 서명
$$ SIGN_{sk}(m)=s\\ VERIFY_{pk}(m,s)=ok ? $$
m : message
s : signature
메세지에 붙어있는 암호 체크섬이다.
주로 사용되는 알고리즘은 RSA, ECDSA, DSA등이 있음...
이 체크섬으로 보장할 수 있는 것
1. 저자가 누구인지 (authentication)
개인키를 가진 저자만이 공개키로 verify될 수 있는 서명을 작성할 수 있기 때문에 저자가 개인키를 가진 자임을 보장할 수 있다.
2. 메세지가 중간에 위조되지 않았음 (무결성 integrity)
메세지를 위조하려고 하더라도 개인키를 가지고 있지 않은 한 서명까지 바꿀 순 없기 때문에, 받은 메세지가 위조되었다면 서명과 verify 해봤을 때 결과가 not okay로 나올 것이다.
* JWT에도 Signature 파트가 있는데 (Header.Payload.Signature 형식으로 되어있음)
공식문서를 보면 서명부분은 1) 시크릿키+해싱 (HS256 = HMAC with SHA-256 )이나 2) 비대칭키 방식 (RSA, ECDSA)으로 생성될 수 있는데,
서명된 토큰은 1. 무결성을 보장하고 2. 만약 비대칭키 방식으로 사용해 서명됐다면 서명한 사람이 개인키를 가진 자임을 보장할 수 있다. 라고 소개하고 있다.
(해싱으로는 데이터 무결성까지만 보장할 수 있다.
authentication, 즉 상대방이 믿을만한지 검증하는 것은 이 public key와 대응되는 private key를 저 상대방이 가졌음을 검증 할 수 있는 mechanism이 포함된 비대칭키 베이스의 알고리즘이어야 한다.)
* HMAC = Hash-based Message Authentication Code (MAC = 데이터 무결성 checksum)
(+ 참고 - 단방향 암호화 )
위의 대칭키, 비대칭키 암호화는 더 큰 틀에서, 복호화할 수 있는 양방향 암호화로 분류할 수 있고
SHA, MD, WHIRPOOL 같은 암호화 해시함수(cryptographic hash function)는 복화화 할 수 없는 단방향 암호화 알고리즘이다.
다이제스트 = 해시함수 리턴값.
원래의 메세지를 알아낼 수 있는 방법은 같은 해시값이 나올때까지 무작위로 메세지들을 해싱해보는 brute force 나
미리 계산한 ( 메세지 , 다이제스트 ) pair를 저장하고 있는 rainbow table (precomputed table for caching the output of cryptographic hash function, usually for cracking password hashes.) 에서 찾아보는 방법밖에 없다.
applications
- 메세지나 파일의 무결성 입증 => 전송 전후의 메세지 다이제스트가 같은지 비교
(옛날에 모바일 포렌식 수업에서도 과제 output file 내용을 일일이 확인하기 번거로우니까 교수님이 파일 해시 돌린 값 제출하라고 했었다!)
- 디지털 서명
- proof-of-work => 비트코인 채굴, hashcash에 적용 ?
- file, data identifier => git같은 vcs에서 파일 식별할때
(또 번들링 파일에서 파일에 변경사항 있어서 새로 번들링해야 하는지 판단할때도 기존 파일명에 붙어있는 해시값과 비교한다고 들은 것 같음..)
- 패스워드 저장
=> 해시함수를 보완하기 위해 임의의 문자열을 덧붙여 다이제스트를 생성하는 salting이나 해시 함수를 여러번 iterate해서 다이제스트를 생성하는 key-stretching같은 기법이 사용된다.
[key-stretching] || - concatenation , p - password , s - salt
salting and stretching password - John D.cook
이 기법들이 적용된 대표적인 password-hashing 알고리즘으로는 PBKDF2, bcrypt, scrypt, Argon2 등이 있음.