公開鍵の秘密 -3- ― 2007/02/08 17:58
... さらにつづく。
早速 OpenSSH 4.5p1 のソースを落としてきて眺めてみた。
sshconnect2.c の userauth_pubkey() 関数あたりが、実際に公開鍵認証を実行しているクライアント側のコードのようである。
userauth_pubkey() の中盤あたりはこうなっている。
1121 if (id->key && id->key->type != KEY_RSA1) { 1122 debug("Offering public key: %s", id->filename); 1123 sent = send_pubkey_test(authctxt, id); 1124 } else if (id->key == NULL) { 1125 debug("Trying private key: %s", id->filename); 1126 id->key = load_identity_file(id->filename); 1127 if (id->key != NULL) { 1128 id->isprivate = 1; 1129 sent = sign_and_send_pubkey(authctxt, id); 1130 key_free(id->key); 1131 id->key = NULL; 1132 } 1133 }
つまり、ここまでの流れの中で id->key に値が設定されていないと、公開鍵が見つからなかったと判断して、load_identity_file()関数を呼んで秘密鍵を得る。(1126行目)。引数の id->filename は ssh コマンドを実行したときに -i オプションで渡したファイル名がセットされている。
id->key に秘密鍵を読み込んだところで、sign_and_send_pubkey() を呼び出す。この関数は同じ sshconnect2.c に定義されていて、サーバーへの接続はこの関数の中で行われる。sign_and_send_pubkey() では、
869 if (key_to_blob(id->key, &blob, &bloblen) == 0) { 870 /* we cannot handle this key */ 871 debug3("sign_and_send_pubkey: cannot handle key"); 872 return 0; 873 }
と、869行目で key_to_blob() 関数に読み込んだ秘密鍵を渡している。
key_to_blob() 関数は id->key に格納されている秘密鍵から "blob"へと変換する。blob とは「ひとかたまり」を意味する英単語で、データベースの Binary Large Object のことではない。
その key_to_blob() は key.c で定義されている。実際に秘密鍵から blob に変換する部分のコードは次の通りだ。
757 switch (key->type) { 758 case KEY_DSA: 759 buffer_put_cstring(&b, key_ssh_name(key)); 760 buffer_put_bignum2(&b, key->dsa->p); 761 buffer_put_bignum2(&b, key->dsa->q); 762 buffer_put_bignum2(&b, key->dsa->g); 763 buffer_put_bignum2(&b, key->dsa->pub_key); 764 break; 765 case KEY_RSA: 766 buffer_put_cstring(&b, key_ssh_name(key)); 767 buffer_put_bignum2(&b, key->rsa->e); 768 buffer_put_bignum2(&b, key->rsa->n); 769 break;
ここで問題となるのが 767行目と 768行目の key->rsa->e と key->rsa->n だ。RSA とはつまりは秘密鍵と公開鍵の二つの非対称鍵を使うしくみなのだが、rsa->e は encryption exponent (暗号化指数)、rsa->n は RSA moduli (OpenSSH では public moduli: 係数) を意味する。rsa->e と rsa->n の組み合わせが公開鍵となり、秘密鍵は rsa->d (decryption exponent: 復号化指数) と rsa->n の組み合わせになる。
上記の流れで行くと、userauth_pubkey() で秘密鍵を id->key にロードし、さらに key_to_blob() で id->key にセットされている秘密鍵から暗号化指数 rsa->e と係数 rsa->n を読み出している。
さて。困った。
秘密鍵がもっているのは、復号化指数 (rsa->d)と係数(rsa->n)ではないのか?
userauth_pubkey() で秘密鍵を読み出しておきながら、つづく key_to_blob() でその秘密鍵から暗号化指数 (rsa->e)を読み出せているリクツはなんだろう。
load_identity_file() で id->key になにをロードしているのか調べる必要がある。
まだつづく... が...
どうも、RSA の基本からやりなおさなければだめなようだ...
最近のコメント