참고한 사이트 를 보면 1번에선 여러가지 언어로 샘플코드들이 존재했다.
그러나 C로 짜여진 소스는 없었다.
shell로 openssl을 불러서 하는 것일 이용해 popen을 사용해서 만들었다.
동시에 popen을 했을 때 괜찮을까에 대한 문제로 소스를 짜기 시작했다.
echo -n $MESSAGE | openssl dgst -sha256 -hmac $SECRET -binary | base64
에서 -binary와 base64를 지웠을 때 데이터가 일정부분 일치한 것을 확인하고 구현할 수 있겠다는 생각이 들었다.
순서는 hmac-sha256 -> hex -> binary -> base64 이다.(ver1)
ver2는 hmac-sha256 -> base64 이다.
for구문의 행위가 bin -> hex였고 그걸 다시 hex -> bin으로 바꾸는 행위를 했던 거였다. 그래서 수정되었다.
(feat. 이사님)
첨부파일은 javascript으로 되어있다. 밑에 소스와 data와 key 값을 일치시켜서 데이터를 확인하면 된다.
gcc hmacsha256.c -lcrypto
#if 1 // openssl hmac sha256
#include <openssl/hmac.h>
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/buffer.h>
#include <stdint.h>
#include <openssl/sha.h> // ver2
#endif
#include <stdio.h>
#include <string.h>
int HMAC_SHA256(char* phskey, char* pdata, char* pkey);
int HEXCHR2BIN(const char hex, char *out);
int HEXS2BIN(const char *hex, unsigned char *out);
int BASE64_ENCODE(char* output, const unsigned char *input, int length);
int main()
{
char hskey[1024];
memset(hskey, 0x00, sizeof(hskey));
HMAC_SHA256(hskey, "data", "key");
printf("hskey [%s]\n", hskey);
return 0;
}
/*******************************************************************************
* HMAC_SHA256 (made by.. Han Chang Jo)
* phskey : 해쉬키(output) pdata : 암호화할 데이터 pkey : 암호화키
* *****************************************************************************/
int HMAC_SHA256(char* phskey, char* pdata, char* pkey)
{
unsigned char zresult[64];
int nresult_len = 32;
int ii;
char zresult_hex[64];
unsigned char zbin[1024];
size_t zbinlen;
char ztemp[5];
memset(zresult, 0x00, sizeof(zresult));
memset(zresult_hex, 0x00, sizeof(zresult_hex));
memset(zbin, 0x00, sizeof(zbin));
memcpy(zresult, HMAC(EVP_sha256(), pkey, strlen((char *)pkey), pdata, strlen((char *)pdata), NULL, NULL), sizeof(zresult));
/* zresult가 바이너리자체로 들어와서 밑에 hex2binary는 필요없는 행위다. */
/* for구문지우고 base64인코딩으로 바로 타도 잘된다 -> ver2로 구분하겠다. */
/* ver1은 주석처리 */
/* ver1
for (ii = 0; ii < 32; ii++) {
if(ii == 0)
sprintf(zresult_hex, "%02x", zresult[ii]);
else
{
memset(ztemp, 0x00, sizeof(ztemp));
sprintf(ztemp, "%02x", zresult[ii]);
strncat(zresult_hex, ztemp, strlen(ztemp));
}
}
HEXS2BIN(zresult_hex, zbin);
BASE64_ENCODE(phskey, zbin, strlen(zbin));
*/
/* ver2 */
BASE64_ENCODE(phskey, zresult, SHA256_DIGEST_LENGTH);
/* ver2 end */
return 0;
}
/*******************************************************************************
* HEX -> BINARY
* *****************************************************************************/
int HEXCHR2BIN(const char hex, char *out)
{
if (out == NULL)
return 1;
if (hex >= '0' && hex <= '9') {
*out = hex - '0';
} else if (hex >= 'A' && hex <= 'F') {
*out = hex - 'A' + 10;
} else if (hex >= 'a' && hex <= 'f') {
*out = hex - 'a' + 10;
} else {
return 1;
}
return 0;
}
int HEXS2BIN(const char *hex, unsigned char *out)
{
size_t len;
char b1;
char b2;
size_t i;
if (hex == NULL || *hex == '\0' || out == NULL)
return 1;
len = strlen(hex);
if (len % 2 != 0)
return 1;
len /= 2;
for (i=0; i<len; i++) {
if (HEXCHR2BIN(hex[i*2], &b1) || HEXCHR2BIN(hex[i*2+1], &b2)) {
return 1;
}
*(out+i)= (b1 << 4) | b2;
}
return 0;
}
/*******************************************************************************
* (BINARY) -> BASE64 - 바이너리 아니여도 괜찮습니다.
* *****************************************************************************/
int BASE64_ENCODE(char* output, const unsigned char *input, int length)
{
BIO *bmem, *b64;
BUF_MEM *bptr;
b64 = BIO_new(BIO_f_base64());
bmem = BIO_new(BIO_s_mem());
b64 = BIO_push(b64, bmem);
BIO_write(b64, input, length);
BIO_flush(b64);
BIO_get_mem_ptr(b64, &bptr);
memcpy(output, bptr->data, bptr->length-1);
BIO_free_all(b64);
return 0;
}
참고한사이트
1. shell
2. hmac sha256
https://gist.github.com/yoshiki/812d35a32bcf175f11cb952ed9d1582a
3. hex to binary
https://nachtimwald.com/2017/09/24/hex-encode-and-decode-in-c/
4. base64
https://gist.github.com/barrysteyn/7308212
'개발 업무(코딩)-개발자였을때 썼던..' 카테고리의 다른 글
코스콤 배치 작업 내역 (0) | 2023.01.09 |
---|---|
MYSQL TRIGGER(트리거) (0) | 2023.01.09 |
c-json 라이브러리에 대한 고찰과 소수점 짜르는 소스 (0) | 2023.01.09 |
C언어 HMAC SHA256 샘플코드(openssl dgst popen) (0) | 2023.01.09 |
C-JSON EXAMPLE 예제 2 - ARRAY (0) | 2023.01.09 |