기본 콘텐츠로 건너뛰기

글

라벨이 EVP인 게시물 표시

EVP Base64 with C++

인코딩 string encodeBase64(const unsigned char *buf, size_t blen) { auto plen = 4 * ((blen + 2) / 3); auto obuf = make_unique<unsigned char[]>(plen + 1); EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new(); EVP_EncodeInit(ctx); int olen = plen; EVP_EncodeUpdate(ctx, obuf.get(), &olen, buf, blen); int flen = 0; EVP_EncodeFinal(ctx, obuf.get() + olen, &flen); olen += flen; EVP_ENCODE_CTX_free(ctx); return string((char *)obuf.get(), olen); } 디코딩 pair<unique_ptr<unsigned char[]>, size_t> decodeBase64(const string &buf) { auto plen = 3 * buf.size() / 4; auto obuf = make_unique<unsigned char[]>(plen + 1); EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new(); EVP_DecodeInit(ctx); int olen = plen; EVP_DecodeUpdate(ctx, obuf.get(), &olen, (unsigned char *)buf.c_str(), buf.size()); int flen = 0; EVP_DecodeFinal(ctx, obuf.get() + olen, &flen); olen += flen; EVP_ENCODE_CTX_free(ctx); ret...

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...

OpenSSL 까보기 - EVP I/F에서 알고리즘 별 명세표는 어떻게 정의해놨나?

Block cipher를 Provider pattern으로 예쁘게 감싼 OpenSSL의 EVP interface를 쓰다가, 각 Cipher algorithm마다 Key, IV, Block 크기를 정해놨을껀데 어떻게 넣었을까 싶어서 소스를 까봤다. 사용 소스는 openssl-1.0.0-beta4 이다. 쉽게 찾기 위해 만만돌이 3DES를 찾아 가보자. 3DES 구현은 openssl/crypto/evp/e_des3.c에 구현하였다. 구현 방식 별로 함수를 만들고 BLOCK_CIPHER_defs라는 것에 항목을 일일이 상수로 넣었다. //...openssl/crypto/evp/e_des3.c 일부... BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64, EVP_CIPH_RAND_KEY, des_ede_init_key, NULL, EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des3_ctrl) BLOCK_CIPHER는 openssl/crypto/evp/evp_locl.h 함수에 구현한 매크로함수이다. 하는 일은 다른 매크로를 사용하지만, 최종 목적은 해당 알고리즘 명세표를 구조체 인스턴스를 하나 만들어 초기화하는 것이다. //...openssl/crypto/evp/evp_locl.h 일부... #define BLOCK_CIPHER_defs(cname, kstruct, \ nid, block_size, key_len, iv_len, cbits, flags, \ init_key, cleanup, set_asn1, get_asn1, ctrl) \ BLOCK_CIPHER_def_cbc(cname, kstruct, nid, block_size, key_len, iv_len, flags, \ ini...