근본적으로 openssl 은 C++ 기반이 아닌 'C' 언어 기반임을 유의하고 보길 바란다.
다만 해당 포스팅은 Visual Studio 2013 에서 C++ Project 로 만들었다.
우선 해당 포스팅에서 빌드방법은 생략한다.
귀찮거든....
구라는 치지 않는다.
openssl 은 빌드 후, 빌드 결과물을 참조하여 사용한다.
다만 빌드하는 링크 자료는 남겨 두겠다.
openssl 저장소
windows 에서 openssl build 방법
한국어 버전
이미 빌드가 되어 있는 파일.
만약 본인이 실제로 사업이나, 상업적으로 openssl 을 사용해야 한다면
보안과 직결된 영역이므로 가능하면 '최신버전' 을 사용하길 바란다.
포스팅 작성일 기준 LTS 버전은 '1.1.1' 버전이고 해당 사이트에서는 1.1.0 버전까지 지원한다.
특이하게
Visual Studio 2010~2015 버전 까지만 검증 되었으므로 상위 버전에서는 빌드가 안될 수 있다.
필자는 Visual Studio 2013 버전으로 진행 하였다.
1. 환경설정
설정도 귀찮은 분들은 아래 링크를 참조하면 된다.
간단하게 프로젝트를 제작하고 .cpp 파일을 하나 만든다.
기본적인 include / Linking / dll Environment Location 설정을 마치고 아래 코드를 빌드한다.
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
using namespace std;
#include <openssl/sha.h>
string sha256(const string str)
{
unsigned char hash[SHA256_DIGEST_LENGTH];
SHA256_CTX sha256;
SHA256_Init(&sha256);
SHA256_Update(&sha256, str.c_str(), str.size());
SHA256_Final(hash, &sha256);
stringstream ss;
for (int i = 0; i < SHA256_DIGEST_LENGTH; i++)
{
ss << hex << setw(2) << setfill('0') << (int)hash[i];
}
return ss.str();
}
int main() {
cout << sha256("1234567890_1") << endl;
cout << sha256("1234567890_2") << endl;
cout << sha256("1234567890_3") << endl;
cout << sha256("1234567890_4") << endl;
return 0;
}
빌드시 위와 같은 결과물이 나오면 우선적인 환경설정은 잘 되었다는 의미이다.
이제 String 배열을 간단하게 Hash 로 치환하는 법을 배웠으니,
File을 Hash 로 검증하는 코드에 대해 알아본다.
2. MD5
#include <stdio.h>
#include <openssl/md5.h>
int main()
{
unsigned char c[MD5_DIGEST_LENGTH];
char *filename="file.c";
int i;
FILE *inFile;
fopen_s (&inFile ,filename, "rb");
MD5_CTX mdContext;
int bytes;
unsigned char data[1024];
if (inFile == NULL) {
printf ("%s can't be opened.\n", filename);
return 0;
}
MD5_Init (&mdContext);
while ((bytes = fread (data, 1, 1024, inFile)) != 0)
MD5_Update (&mdContext, data, bytes);
MD5_Final (c,&mdContext);
for(i = 0; i < MD5_DIGEST_LENGTH; i++) printf("%02x", c[i]);
printf (" %s\n", filename);
fclose (inFile);
return 0;
}
3. SHA256
#include <stdio.h>
#include <openssl/sha.h>
int main()
{
unsigned char c[SHA256_DIGEST_LENGTH];
char *filename = "C:\\Users\\Cyp\\Desktop\\123.txt";
int i;
FILE *inFile;
fopen_s(&inFile, filename, "rb");
SHA256_CTX shaContext;
int bytes;
unsigned char data[1024];
if (inFile == NULL) {
printf("%s can't be opened.\n", filename);
return 0;
}
SHA256_Init(&shaContext);
while ((bytes = fread(data, 1, 1024, inFile)) != 0)
SHA256_Update(&shaContext, data, bytes);
SHA256_Final(c, &shaContext);
for (i = 0; i < SHA256_DIGEST_LENGTH; i++) printf("%02x", c[i]);
printf(" %s\n", filename);
fclose(inFile);
return 0;
}
사실 코드는 별반 다를게 없다.
openssl 은
Init → Update → Final 을 순서대로 처리한 후 해쉬 string 값을 반환한다.
1. Init (Parameter 1)
※ sha 256 의 경우 => int SHA256_Init(SHA256_CTX *c);
해당하는 알고리즘의 구조체 초기화
2. Update (parameter 1, parameter 2, parameter 3)
※ sha256 의 경우 => int SHA256_Update(SHA256_CTX *c, const void *data, size_t len);
parameter 1 = &sha256 구조체
parameter 2 = 데이터 (제공된 문자열, byte 등 (void 형임을 유의))
parameter 3 = 데이터 길이
return = 성공 : 0 , 실패 : 그외
3. Final (parameter 1, parameter 2)
※ sha 256의 경우 => int SHA256_Final(unsigned char *md, SHA256_CTX *c);
설정된 sha256 구조체를 이용해서 -> parameter 1 에 string 할당.
4. 결론
두 예제를 보면서 눈치 챗겠지만 해시 알고리즘이 바뀐다고 과정이 바뀌는게 아니다.
때문에 SHA 512 를 쓰던, SHA 384 를 쓰던, 구조체 형태만 바꿔주면 그만이다.
여담으로 MD5 의 경우에는 현재 '안전하지 않은 알고리즘' 으로 분류가 된다.
가능하면 SHA-256, SHA-512 를 사용하는것을 권장하며,
나아가 현재 새롭게 표준으로 지정된 SHA-3 사용도 고려해 보길 바란다.
(SHA-256, SHA-512 는 SHA-2 이다)
SHA 버전을 사용하는 프로그램들은 각각 다음과 같다.
SHA-1 | Git [구글이 지적하였으나, 토발즈 문제없다 답함] |
SHA-2 | BittCoin (PoW), 인터넷 뱅킹, Windows 운영체제 |
SHA-3 | [내가 아는 한 사용처 없음] |
SHA-3 의 경우는 '구조가 다르기에' 더 안전하다고 말하기 모호하다
현재 널리 사용되고 있는 SHA-2 는 구조적인 취약점이 '없기에'
굳이 넘어갈 이유가 없다.
거기에,
SHA-3 는 HW 로 구현할 때 SHA-2 대비 더 빠르지만,
SW 로 구현할때는 SHA-3 가 더 느리기 때문에
이 점역시 넘어가는데 발목을 잡는다.
여담으로 SHA-3 를 사용하고 싶다면 openssl/evp.h 파일을 참조 해 보라.
내가 가져온 빌드된 파일상에는 SHA-3 관련된 선언문이 포함되어 있지 않아서 시도해 보진 않았지만.
비슷하게 처리할 수 있을 것이다.
'Programming > C++' 카테고리의 다른 글
[C++] 인터페이스에 관한 팁 (순수가상함수) (0) | 2021.06.09 |
---|---|
[C++] 다형성 vitual 키워드에 관한 팁 (0) | 2021.06.09 |
[C++] C# 측으로 Struct 를 UDP 로 전송 (0) | 2021.04.15 |
[C++] OpenCV digit_svm 예제 간단 분석 (0) | 2021.03.31 |
[C++] TCP 통신 (0) | 2020.12.20 |