EVP_PKEY * を経由しない RSA * 読み込み方法
rsaCodec.cpp ではPEMファイルからRSA *を取り出すために,EVP_PKEY *で取り出した後,変換していた.
// 次2行 rsaCodec での処理 EVP_PKEY *epubKey = PEM_read_PUBKEY( fp, NULL, NULL, NULL ); RSA *rpubKey = EVP_PKEY_get1_RSA( epubKey ); // 次2行 rsaCodec での処理 EVP_PKEY *epKey = PEM_read_PrivateKey( fp, NULL, NULL, NULL ); RSA *rpKey = EVP_PKEY_get1_RSA( epKey );
これは,RSA *を返す関数が,なぜだか働かないという問題があったからだ.この問題を解決する方法が見つかったから,ここに書き留める.
openssl/ssl.h の SSL_library_init() を事前に実行しておく
これから使おうとする巻数の接頭辞が PEM_ なのにと不思議に思うが,SSL_library_init() を実行する.
- http://www.openssl.org/docs/ssl/SSL_library_init.html
- http://home.att.ne.jp/theta/diatom/ssl%283%29.html
- http://www.geocities.co.jp/SiliconValley-PaloAlto/4182/Openssl_content7.html
次,RSA * を返す関数が3つある.
- PEM_read_RSAPublicKey()
- PEM_read_RSA_PUBKEY()
- PEM_read_RSAPrivateKey()
RSAPublicKey() がうまくいかない.2007-10-15 によれば PEM ファイルの構文に依存するとある.しかし手持ちの PEM ファイルに RSA との文字列を追加してもうまくいかなかった.PEM_read_RSA_PUBKEY() と PEM_read_RSAPrivateKey() は良い.
特に書くタイミングがなかったリンク.http://ml.tietew.jp/cppll/cppll_novice/thread_articles/446
rsaCodec2.cpp
sha256c は最近のエントリに書き出している.そちらを参照されたい.
// http://www.wizard-limit.net/mt/pc/archives/001184.html // PEM_read_PrivateKeyは、SSL_library_init(); を事前に呼んでおかないと動作しないようでした。 // という情報から,この関数を事前に実行しておくとどうなるか,実験 // sha256c は rsaCodec プロジェクトのファイルにリンクしている // RSA * を返す関数は3つ. // -PEM_read_RSAPublicKey // -PEM_read_RSA_PUBKEY // -PEM_read_RSAPrivateKey // PEM_read_RSAPublicKey は NULL を返し,下2つは RSA * を返してくれた. #include <openssl/ssl.h> #include <openssl/rsa.h> #include <openssl/pem.h> #include "../rsaCodec/sha256c.h" #include <stdlib.h> // openssl/applink.c 内の fopen() への warning C4996 の抑制 #ifdef _WIN32 #ifdef WIN32 #define WIN32_PREDEFINED #else #define WIN32 #endif #pragma warning( disable: 4996 ) #endif #include <openssl/applink.c> #ifdef WIN32 #ifdef WIN32_PREDEFINED #undef WIN32_PREDEFINED #else #undef WIN32 #endif #pragma warning( default: 4996 ) #endif // warning C4996 の抑制はここまで const int RSABITNUM = 2048; const int RSABYTENUM = RSABITNUM/8; const char *pKeyFilename = "C:\\data\\PEM\\Private\\ossl100a_pKey.pem"; const char *pubKeyFilename = "C:\\data\\PEM\\Public\\ossl100a_pubKey.pem"; void showHash( unsigned char *hash, size_t sz ) { for ( size_t i = 0; i < sz; i++ ) { printf("%02x", hash[i] ); } printf("\n"); } // 公開鍵で暗号化し,秘密鍵で復号化する int main ( int argc, char *argv[] ) { SSL_library_init(); sha256c s; char *textvector = "The quick brown fox jumps over the lazy dog"; s.update( (unsigned char *)textvector, strlen(textvector) ); s.showHash(); // プレーンテキスト.暗号化対象 unsigned char *planetext = s.getHash(); // 公開鍵ファイルを読み込む FILE *fp; fopen_s( &fp, pubKeyFilename, "r"); //RSA *rpubKey = PEM_read_RSAPublicKey( fp, NULL, NULL, NULL ); RSA *rpubKey = PEM_read_RSA_PUBKEY( fp, NULL, NULL, NULL ); // 次2行 rsaCodec での処理 //EVP_PKEY *epubKey = PEM_read_PUBKEY( fp, NULL, NULL, NULL ); //RSA *rpubKey = EVP_PKEY_get1_RSA( epubKey ); RSA_print_fp( stdout, rpubKey, 0 ); // 秘密鍵ファイルを読み込む fopen_s( &fp, pKeyFilename, "r" ); RSA *rpKey = PEM_read_RSAPrivateKey( fp, NULL, NULL, NULL ); // 次2行 rsaCodec での処理 //EVP_PKEY *epKey = PEM_read_PrivateKey( fp, NULL, NULL, NULL ); //RSA *rpKey = EVP_PKEY_get1_RSA( epKey ); RSA_print_fp( stdout, rpKey, 0 ); // 暗号化後のデータ unsigned char enctext[RSABYTENUM]; // 暗号化 int enclen = RSA_public_encrypt( SHA256_DIGEST_LENGTH, planetext, enctext, rpubKey, RSA_PKCS1_OAEP_PADDING ); // 暗号化成立時 if ( enclen != -1 ) { // 暗号データ表示 showHash( enctext, enclen); // 復号化 enclen = RSA_private_decrypt( RSABYTENUM, enctext, planetext, rpKey, RSA_PKCS1_OAEP_PADDING ); if ( enclen != -1 ) { // 復号データ表示 showHash( planetext, enclen ); } } return 0; }