Diffie-Hellman protocol, DH protocol 은 공개 키를 분배 하는 방안이다.
데이터를 동일한 키로 암호화, 복호화한다는 상황을 가정해보자. 사용하는 키를 통신을 주고 받는 쪽과 주고 받아야하는데 이 키는 어떻게 안전하게 주고 받을 수 있을까?
1976년 11월에 스탠퍼드에서 Whitfield Diffie와 Martin Hellman이 발표한 논문에서 공개 키를 분배하는 방법을 발표하였고, 이 방식은 아직도 대부분 통신방식에서 이용하게 된다. https에서도 이 DH 키를 통해서 데이터를 암호화, 복호화하여 주고 받게 된다.
철수, 영희가 DH 프로토콜을 이용하여 동일한 암호화 키를 공유하는 방식을 한번 보자.
g^a
를 n
으로 나눈 값을 영희에게 전달하고, 영희는 g^b
를 n
으로 나눈 값을 전달한다. 이때 이 값을은 외부에 노출되게 되지만 a,b 값은 노출되지 않았기에 n이 충분히 큰 수이며 소수라면, 이때 노출되는 값들이 n으로 나눈 값이기에 특정되기 어렵다. ^a
, ^b
연산을 하고 n
으로 나누면 동일한 값을 갖게 되면서 이 값을 키 값으로 이용한다.g^ab
나 g^ba
나 같은 값이 나온다는 거듭제곱 연산의 특성을 이용한 것이라 할 수 있다.
해커라면 외부에 노출되는 g(5)
, n(23)
, g^a(8)
, g^b(19)
값으로 brute-force하여 해당 키 값을 맞추려 할 텐데,
이때 n의 값에 따라 추론할 수 있는 범위가 정해진다. 이 범위가 좁으면 안되기에 n의 값은 소수이면서 (n-1) / 2
의 값 또한 소수인 수로 선정해야 특정할 수 있는 범위가 줄어든다. 또한 이 수가 작으면 결국 최종 키 값이 n
으로 나눈 나머지 수 이기에 위의 예시처럼 n
값이 23
이라면 키 값이 0~22
가지 이기에 상당히 위험하다고 볼 수 있다. 실제로는 2048 ~ 4096 bit 범위의 수를 사용한다고 한다.
아래와 같은 상황을 보자.
중간에 해커가 철수에게 마치 본인이 영희인거첨, 영희에게는 철수인거처럼 주고 받는 키 값을 가로채면서 철수, 영희와 각각 키 교환을 해서 철수, 영희와 공유키를 갖은 다음 둘 사이의 통신을 해킹 할 수 있다.
이를 방지하기 위해서는 철수, 영희는 각각 중간에 해커가 개입된 것이 아닌 실제 철수, 영희가 맞는지 확인하는 과정을 거쳐야한다.
다행히 이를 확인할 수 있는 방법이 있다. (RSA 비대칭키 암호화) 이에 DH 단독으로 사용된다기 보다 RSA와 함께 사용된다.
어플리케이션 서버 버전, openssl 버전 등에 따라 DH 키 교환하는 과정에서 사용되는 n
의 값의 지원범위에 따라 에러가 발생할 수 있다.
SSLError(SSLError(1, '[SSL: DH_KEY_TOO_SMALL] dh key too small)
이런 에러가 발생할 수 있는데, 이는 TLS handshake 과정에서 키를 교환하면서 사용되는 n
값의 지원범위가 맞지 않아서이다. dh key 개념을 알고 있다면 보다 빠르게 현상을 이해하고 대처할 수 있을 것 이다. 파이썬 서버의 버전을 3.10으로 올리면, dh 키 길이 제한을 2048bit 이상으로 강제하기 때문에 1024bit 까지 사용하고 있는 외부와 통신에서 tls연결이 안되는 이슈를 경험할 수 있다.
참고자료(책 Serious Cryptography(2018))
함께 볼만한 영상
https://www.youtube.com/watch?v=NmM9HA2MQGI
https://www.youtube.com/watch?v=Yjrfm_oRO0w