PEM_read_PrivateKeyは、SSL_library_init(); を事前に呼んでおかないと動作しないようでした。yさんから、上記のコメントをいただきました。ありがとうございます。
追試してみた結果、SSL_library_init()を呼ぶことで、PEM_read_PrivateKey()の第三引数が有効になるようです。
そこで、プログラムを以下のように変えたところ、無事に -des3 つきで作成したキーが読めるようになりました。
# 自分で書いておいてなんなんですが、前のエントリーが何を見て書いたか覚えていないので、opensslの関数の説明がどこを見れば良いのか全然わかりません。manでも出ないし。
とりあえず、第4引数に直接パスワードを渡すか、第3引数のコールバック関数でbufにパスワードを書いて、パスワードの文字数を返してやれば良いようです。
#include <openssl/ssl.h> int cb(char *buf, int size, int rwflag, void *userdata) { printf("enter passphrase> "); scanf("%s", buf); return strlen(buf); } int main(int argc, char *argv[]) { FILE *keyfp, *orig, *enc, *dec; EVP_PKEY *private; RSA *rsa; char *orig_buf; char *crypted_buf; char *decrypted_buf; int crypted_len; int decrypted_len; int size; int read_len; time_t t1, t2, t3; SSL_library_init(); ERR_load_crypto_strings(); keyfp = fopen(argv[1], "r"); if (keyfp == NULL) { fprintf(stderr, "ファイルが開けません: %s\n", argv[1]); return 1; } private = PEM_read_PrivateKey(keyfp, NULL, cb, NULL); if (private == NULL) { fprintf(stderr, "PEM_read_PrivateKey:%s\n", ERR_error_string(ERR_get_er\ ror(), NULL)); return 1; } fclose(keyfp); rsa = EVP_PKEY_get1_RSA(private); if (rsa == NULL) { fprintf(stderr, "EVP_PKEY_get1_RSA:%s\n", ERR_error_string(ERR_get_erro\ r(), NULL)); return 1; } RSA_print_fp(stdout, rsa, 0); printf("RSA_size: %d\n", RSA_size(rsa)); orig = fopen(argv[2], "r"); if (orig == NULL) { fprintf(stderr, "ファイルが開けません: %s\n", argv[2]); return 1; } enc = fopen(argv[3], "w"); if (enc == NULL) { fprintf(stderr, "ファイルが開けません: %s\n", argv[3]); return 1; } size = RSA_size(rsa); orig_buf = malloc(size); crypted_buf = malloc(size); decrypted_buf = malloc(size); t1 = time(NULL); while (read_len = fread(orig_buf, 1, size - 11, orig)) { crypted_len = RSA_private_encrypt(read_len, orig_buf, crypted_buf, rsa,\ RSA_PKCS1_PADDING); if (crypted_len == -1) { fprintf(stderr, "RSA_private_encrypt:%s\n", ERR_error_string(ERR_ge\ t_error(), NULL)); return 1; } fwrite(crypted_buf, 1, crypted_len, enc); } fclose(orig); fclose(enc); t2 = time(NULL); printf("encrypt: %d\n", t2 - t1); enc = fopen(argv[3], "r"); if (enc == NULL) { fprintf(stderr, "ファイルが開けません: %s\n", argv[3]); return 1; } dec = fopen(argv[4], "w"); if (dec == NULL) { fprintf(stderr, "ファイルが開けません: %s\n", argv[4]); return 1; } while (read_len = fread(crypted_buf, 1, size, enc)) { decrypted_len = RSA_public_decrypt(read_len, crypted_buf, decrypted_buf\ , rsa, RSA_PKCS1_PADDING); if (decrypted_len == -1) { fprintf(stderr, "RSA_public_decrypt:%s\n", ERR_error_string(ERR_get\ _error(), NULL)); return 1; } fwrite(decrypted_buf, 1, decrypted_len, dec); } fclose(enc); fclose(dec); t3 = time(NULL); printf("decrypt: %d\n", t3 - t2); EVP_PKEY_free(private); RSA_free(rsa); return 0; }コールバックはもろ手抜きなので、scanfは使ってるし、パスワードそのまま画面に出るしって感じですが、まあサンプルと言うことで。
しかし、参考URLとかは書いておかないと、後で見たときに何がなんだかわからないなあ・・・。
カテゴリ
FreeBSDトラックバック(0)
このブログ記事を参照しているブログ一覧: 暗号化について少し(その2)
このブログ記事に対するトラックバックURL: https://www.wizard-limit.net/cgi-bin/mt/mt-tb.cgi/1083
コメントする