한동안 바빠 오랜만에 글을 쓰는것 같다.
얼마전 프로젝트를 통해 REST 통신시 데이터 인증을 하기 위해 HMAC SHA-256 알고리즘을 사용한다는 것을 알게 되었다.
일방향 암호화라 복호화가 불가능하다. 클라이언트와 서버가 동일한 키값을 이용하여 데이터에 대한 무결성을 확인한다.
HMAC SHA-256에 대한 자세한 내용 및 이론은 아래 링크를 참조
소스로 확인해보자.
C# Code
* C# HMACSHA256 클래스에 대한 정의는 아래 링크를 참조
https://msdn.microsoft.com/ko-kr/library/system.security.cryptography.hmacsha256(v=vs.110).aspx
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 | // System.Security.Cryptography <- using을 해야 C#의 HMACSHA256 클래스 사용이 가능하다. using System.Security.Cryptography; // HMAC 생성 함수 private string GenerateHMAC(string key, string payload) { // 키 생성 var hmac_key = Encoding.UTF8.GetBytes(key); // timestamp 생성 var timeStamp = DateTime.UtcNow; var timeSpan = (timeStamp - new DateTime(1970, 1, 1, 0, 0, 0)); var hmac_timeStamp = (long)timeSpan.TotalMilliseconds; // HMAC-SHA256 객체 생성 using (HMACSHA256 sha = new HMACSHA256(hmac_key)) { // 본문 생성 // 한글이 포함될 경우 글이 깨지는 경우가 생기기 때문에 payload를 base64로 변환 후 암호화를 진행한다. // 타임스탬프와 본문의 내용을 합하여 사용하는 경우가 일반적이다. // 타임스탬프 값을 이용해 호출, 응답 시간의 차이를 구해 invalid를 하거나 accepted를 하는 방식으로 사용가능하다. // 예시에서는 (본문 + 타임스탬프)이지만, 구글링을 통해 찾아보면 (본문 + "^" + 타임스탬프) 등의 방법을 취한다. var bytes = Encoding.UTF8.GetBytes(payload + hmac_timeStamp); string base64 = Convert.ToBase64String(bytes); var message = Encoding.UTF8.GetBytes(base64); // 암호화 var hash = sha.ComputeHash(message); // base64 컨버팅 return Convert.ToBase64String(hash); } } | cs |
Javascript Code
Javascript를 통해 HMAC SHA256 암호화를 하기 위해선 아래 두개의 라이브러리를 로드해야한다.
1 2 | <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/hmac-sha256.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/enc-base64-min.js"></script> | cs |
소스 및 예제 실행은 아래 링크를 통해 확인.
Node.js Code
nodejs의 crypto를 이용해 HMAC SHA-256 암호화를 한다.
* nodejs crypto에 대한 정의는 아래 링크를 참조
https://nodejs.org/api/crypto.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | var crypto = require('crypto'); function GenerateHMAC(key, payload) { // 암호화 객체 생성, sha256 알고리즘 선택 var hmac = crypto.createHmac('sha256', key); // 암호화할 본문 생성 var timestamp = new Date().getTime(); var message = new Buffer(payload + timestamp).toString('base64'); hmac.write(message); hmac.end(); return hmac.read(); } var hash = GenerateHMAC('hello world', 'sha256'); var encoded_hash = new Buffer(hash).toString('base64'); console.log(encoded_hash); | cs |
C#, Javascript, Node.js 예제 소스에 동일한 payload와 key, timestamp 입력시 동일한 hash값을 얻을 수 있었다.
끝.
'Programming > 기타' 카테고리의 다른 글
[C#]텔레그램 봇 만들기 (650) | 2017.01.05 |
---|---|
noVNC (597) | 2017.01.02 |