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とかは書いておかないと、後で見たときに何がなんだかわからないなあ・・・。

カテゴリ

トラックバック(0)

このブログ記事を参照しているブログ一覧: 暗号化について少し(その2)

このブログ記事に対するトラックバックURL: https://www.wizard-limit.net/cgi-bin/mt/mt-tb.cgi/1083

コメントする

このブログ記事について

このページは、falseが2006年10月21日 01:45に書いたブログ記事です。

ひとつ前のブログ記事は「razor-agentsでproxy越え」です。

次のブログ記事は「mt-blacklist修正」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

広告

Powered by Movable Type 6.1.1