기본 콘텐츠로 건너뛰기

새로운 노트북

EVP_DigestSign/Verify 예제

비대칭 알고리즘을 이용하여, 사인/검증 하는 API를 OpenSSL 1.0.0부터 쓸 수 있다. 문제는 아직 예쁜 예제가 없다는 것. 그래서 낑낑끙끙 하며 만들어 봤다.


#include <openssl/rsa.h>
#include <openssl/evp.h>
#include <iostream>
using namespace std;

void testSignVerify(void)
{
 EVP_PKEY* pkey(/* 이미 만들어놓은 키 */);

 char src[] = "Hello, world!";

 unsigned char sign[1024] = {0x00};
 size_t signlen(sizeof(sign));

 do {
  EVP_MD_CTX md;
  EVP_MD_CTX_init(&md);
  if ( EVP_DigestSignInit(&md, nullptr, EVP_sha256(), nullptr, pkey) <= 0 )
  {
   cerr << "EVP_DigestSignInit" << endl;
   break;
  }

  if ( EVP_DigestSignUpdate(&md, src, strlen(src)) <= 0 )
  {
   cerr << "EVP_DigestSignUpdate" << endl;
   break;
  }

  if ( EVP_DigestSignFinal(&md, sign, &signlen) <= 0 )
  {
   cerr << "EVP_DigestSignFinal" << endl;
   break;
  }

  cerr << "Sign:   ";
  PWEnc::encodeHex(cerr, sign, signlen) << endl;

  EVP_MD_CTX_cleanup(&md);
 } while (false);

 do {
  EVP_MD_CTX md;
  EVP_MD_CTX_init(&md);
  if ( EVP_DigestVerifyInit(&md, nullptr, EVP_sha256(), nullptr, pkey) <= 0 )
  {
   cerr << "EVP_DigestVerifyInit" << endl;
   break;
  }

  if ( EVP_DigestVerifyUpdate(&md, src, strlen(src)) <= 0 )
  {
   cerr << "EVP_DigestVerifyUpdate" << endl;
   break;
  }

  if ( EVP_DigestVerifyFinal(&md, sign, signlen) <= 0 )
  {
   cerr << "EVP_DigestVerifyFinal" << endl;
   break;
  }

  cerr << "Verify: ";
  PWEnc::encodeHex(cerr, sign, signlen) << endl;

  EVP_MD_CTX_cleanup(&md);
 } while (false);

 cerr << endl;
}

패딩 규칙은 기본값은 PKCS#1이며, 변경하고자 할 때는 EVP_Digest(Sign|Verify)Init 함수 두번째 인자에 EVP_PKEY_CTX*의 주소를 넘겨 EVP_PKEY_CTX*를 받는다. 이것에 EVP_PKEY_CTX_set_rsa_padding 함수(실은 매크로 함수이다)로 세팅할 수 있다.


/* 생략 ... */
EVP_PKEY_CTX* pkey_ctx(nullptr);
EVP_DigestSignInit(&md, &pkey_ctx, EVP_sha256(), nullptr, pkey);
EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PSS_PADDING);
EVP_PKEY_CTX_set_rsa_pss_saltlen(pkey_ctx, 20);
/* 생략 ... */

댓글

이 블로그의 인기 게시물

Bash Array, Map 정리

Bash에서 Array, Map에 대한 정리. (매번 찾기 귀찮) 찾아보진 않았지만, Bash에서 Array든 Map이든 동일하게 Map(C++에서 Unordered Map)으로 동작하는 것 같다. 왜냐하면, Array의 Index가 연속하지 않아도 동작한다. 그저 Key가 0 이상의 정수인 Map이랑 비슷하게 동작한다. 예) 1, 2, 3, 9, 10 Array # 생성 declare -a empty_array declare -a ar=(haha hoho baba "long string haha hoho") # 접근 echo "ar[0]=${ar[0]}" echo "all as array=${ar[@]}" # 큰따옴표 안에서 각 원소를 따로따로 전달한다. echo "all as one=${ar[*]}" # 큰따옴표 안에서 각 원소를 문자열 하나로 합쳐 전달한다. echo "indexes=${!ar[@]}" echo "indexes=${!ar[*]}" echo "length=${#ar[@]}" echo "length=${#ar[*]}" echo "last=${ar[-1]}" echo "last=${ar[@]: -1}" # 콜론 뒤에 빈 칸이 꼭 필요하다. 옛 방식 # 현재 상황 declare -p ar #(출력) declare -a ar=([0]="haha" [1]="hoho" [2]="baba" [3]="long string haha hoho") ar[100]=hello # 인덱스를 건너 뛰어도 동작한다. declare -p ar #(출력) declare -a ar=([0]="haha" [1]="hoho" [2]="baba" [3]=&

설치한 패키지에서 RPM 추출하기

오래된 패키지를 관리할 저장소가 없어졌고, 기존 패키지로 다른 서버를 세팅해야할 일이 생겼다면 RPM의 리패키지 기능을 이용해보자. $ rpm -e --repackage [PACKAGE_NAME] 위와 같이 리패키지하면, /var/spool/repackage/ 에 생성한 RPM파일이 있다. :-)