한동안 바빠 오랜만에 글을 쓰는것 같다.


얼마전 프로젝트를 통해 REST 통신시 데이터 인증을 하기 위해 HMAC SHA-256 알고리즘을 사용한다는 것을 알게 되었다.

일방향 암호화라 복호화가 불가능하다. 클라이언트와 서버가 동일한 키값을 이용하여 데이터에 대한 무결성을 확인한다.


HMAC SHA-256에 대한 자세한 내용 및 이론은 아래 링크를 참조

SHA, HMAC


소스로 확인해보자.


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(197011000));
    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

소스 및 예제 실행은 아래 링크를 통해 확인.

Javascript HMAC SHA-256


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

+ Recent posts