티스토리 뷰

개요

 

지난번 포스팅에 이어 실제 코드 구현을 해보자

-  실제구현은  "권경모"님과 함께 하였다.

덤으로 Constant time comparison 대해서도 알아보자 .

 

(참고) 현재까지 관련 포스팅 모음

- Slack slash command: Verifying requests from Slack: https://jusths.tistory.com/75

- Golang: Github - Travis-CI - Heroku: https://jusths.tistory.com/69

- Slack slash command + Golang server: https://jusths.tistory.com/72

- Slack slash command 는 무얼 보내주는 걸까: https://jusths.tistory.com/73

 

 

드디어, 실제 코드를 보자

 

- 코드링크: https://github.com/nicewook/slack_slash_cmd2

 

1) 환경변수 가져오기

 

로컬 PC SLACK_SIGNING_SECRET 이라고 환경변수를 설정해두었다. 이제  Golang 코드 내에서 읽어와 있다.

set 으로 설정하고 echo 값을 확인해보자.

 


 

os.LookupEnv() 함수를 이용해 "SLACK_SIGNING_SECRET" 환경변수를 읽어와서 

slack2 변수인 SlackSigningToken 저장해둔다.

 

 

2) HTTP POST 에서 원하는 정보 추출하기

 

- HTTP POST Handler() 함수에서는 우선 Verification 시도한다.

- 필요한 재료인,  받은 HTTP POST request message   Server 환경변수 값을 가져온 slackSigningToken VerifyRequest() 넣어준다.

이때 verification 에서 message consume 해버리면, verification 이후의 r.ParseForm() 에서 없다.

이에 대한 대비책 참고 링크: https://jusths.tistory.com/65

- 만약 Verification 과정을 무사히 마쳤다면  Server "Request accepted" 라는 회신을 것이다.

물론 최종 목표는 시간 정보를 받아 다른 Time zone 시간으로 변경, 회신하는 것이다.

 


 

- 첫번째 사각 박스에서 req.Body 정보를 추출해낸뒤, 다시 req.Body 채워준다. (위에 언급한 대비책 적용)

- 두번째 사각 박스에서 verification 필요한 정보인 request Body, timestamp, signature 추출한 다음

서버가 가진 slackSiginingToken 함께 Verify() 함수로 넘겨준다.

 


 

 

3)  HMAC 으로 signature 만들어 비교하기

 

- Server 에서 Signature 만들기 위한 재료를 message 만들어서 checkMAC() 함수로 보낸다.

 


 

-  Golang 제공하는 hmac   key, message 조합하면 아래와 같이 calculatedMAC 계산해낼 있다.

- 참고: Golang 에서의 HMAC 사용법: https://golang.org/pkg/crypto/hmac/

- calculatedMAC: Golang Server 계산해낸 signature

- receivedMAC: Slack 계산해서 보내온 signature

 

- 둘을 그냥 비교해도 동작은 하지만, 보안상 안전한 hmac.Equal() 이용하여 verify 해준다.

 


 

 

hmac.Equal() 보안

 

hmac.Equal() 들여다보면 subtle.ConstantTimeCompare() 사용하고,

함수의 설명을 보면 중요한 문구가 나온다.

 

"The time taken is a function of the length of the slices and is independent of the contents"

함수 실행시 소요시간은, 비교하는 슬라이스의 길이와 관련이 있고, 슬라이스가 담고 있는 내용과는 무관하다는 것이다.

 

말의 의미를 찾아가다보면 "constant time comparison" 이란 키워드를 만나게 된다.

 

 

 

Constant time comparison

 

아래 링크내용을 짧게 줄여서 설명해본다.

관련 링크: https://codahale.com/a-lesson-in-timing-attacks/

 

단순히 문자열 개를 비교할 때에는 결과값이 리턴되는 시간이 가변하며,

이를 통해 해커의 attack 가능하다는 것이다.

 

우리의  Token "CCCCC" 라고 가정해보자

 

해커는 A****, B****, C**** 차례대로 시도해본다.

이때 각각의 리턴시간이 1ms, 1ms , 2ms  이라면  해커는 첫번째 문자가 C라는 것을 알아차리게 된다.

왜냐하면, 단순 문자열 비교는 A, B 경우는 동일 문자열이 아니라고 바로 리턴해주지만,

C 경우는  첫번째 문자는 같다는 것을 확인하고, 두번째 문자열을 비교하는 작업까지 하기 때문이다.

 

이게 과연 가능할까 싶지만, 실제로는 로컬 PC 아니라 LAN 환경하에 원격의 서버에 대해서도 20 us 정도까지도 구분해 있다 한다.

 

해법은 무엇일까?

 

간단하다. 비교할 문자열의 모든 문자를 비교한 다음에 결과를 리턴하게 하는 것이다.

이것이 위에 ConstantTimeCompare() 함수의 설명에서  언급한

"The time taken is a function of the length of the slices and is independent of the contents" 의미이다.


반응형
반응형
잡학툰 뱃지
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/11   »
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
글 보관함