본문 바로가기

Tech

[OpenSSL] ECDSA Sign 과 Verify

이전 포스팅에서 만든 프로젝트에 간단한 ECDSA 방식으로 싸인하고 검증하는 코드를 만들어 보겠다.

 

 

// TestOpenSSL.cpp: 콘솔 응용 프로그램의 진입점을 정의합니다.
//

#include "stdafx.h"

#include "openssl/evp.h"
#include "openssl/err.h"
#include "openssl/ec.h"
#include "openssl/sha.h"

#ifdef _DEBUG
	#pragma comment (lib, "libcryptoMDd.lib")
	#pragma comment (lib, "libsslMDd.lib")
#else
	#pragma comment (lib, "libcryptoMD.lib")
	#pragma comment (lib, "libsslMD.lib")
#endif


void SignAndVerifyTest()
{
	SHA256_CTX		c;
	EC_KEY			*ecKey = NULL;
	int				nidEcc;
	unsigned char	m[SHA256_DIGEST_LENGTH];
	unsigned char	sig[256];					// Must greater than ECDSA_size(ecKey)
	unsigned int	lenSig;
	int				iRet;


	// Generate Hash for signing
	SHA256_Init(&c);
	SHA256_Update(&c, "This is Data for Signing.", 25);
	SHA256_Final(m, &c);
	OPENSSL_cleanse(&c, sizeof(c));

	// Set Key Type.
	nidEcc = OBJ_txt2nid("secp521r1");
	ecKey = EC_KEY_new_by_curve_name(nidEcc);
	if (ecKey == NULL)	ERR_print_errors_fp(stderr);

	// Generate Key.
	EC_KEY_generate_key(ecKey);

	// Sign Message Digest.
	ECDSA_sign(0, m, SHA256_DIGEST_LENGTH, sig, &lenSig, ecKey);
	iRet = ECDSA_verify(0, m, SHA256_DIGEST_LENGTH, sig, lenSig, ecKey);
	printf("Before Fake : Verify Result is %d \n", iRet);

	// Change Message Digest.
	m[0]++;
	iRet = ECDSA_verify(0, m, SHA256_DIGEST_LENGTH, sig, lenSig, ecKey);
	printf("After Fake  : Verify Result is %d \n", iRet);
	puts("\n------------------------------\n");

	EC_KEY_free(ecKey);
}


int main()
{
	OpenSSL_add_all_algorithms();
	ERR_load_crypto_strings();

	SignAndVerifyTest();

	ERR_print_errors_fp(stderr);

    return 0;
}

 

 

 

실행 결과다

 

 

 

ECDSA로 데이터에 사인을 하면 서명이 생성되는데 서명이나 데이터가 바뀌면 위조된 상황으로 볼 수 있다.

소스에서는 데이터에 변화를 줘서 위조 데이터를 만들어 서명을 검증해 보았다.

1바이트만 변경했는데도 Verify Result에서 0이듯이 검증이 실패한다.

 

다음 포스팅에서는 GitHub에 위 프로젝트를 올려보겠다.

OpenSSL 관련 예제 코드는 여기에 계속 추가할 예정이다.