パスワードを忘れた? アカウント作成
6425198 journal
ソフトウェア

dodaの日記: 非互換な DSA 鍵

日記 by doda

気がついたら前回の日記から半年経っている…たまには何か書かないと…
という事で、最近はまった問題を一つ。

最近の Tera Term で生成した 2048 ビットの DSA 鍵が ssh 公開鍵認証で使えないという指摘があった。
試してみると、確かに使えない。
使えると言っている 4.64 で生成した鍵と比べると、16/32 バイトサイズが大きくなっている。
これは組み合わせて使うダイジェスト関数が SHA-1 から SHA2-256 になったっぽいなと当たりを付けて、OpenSSL の CHANGES を見ると、

Add support for dsa-with-SHA224 and dsa-with-SHA256.

という記述を発見。この影響で SHA2-256 を使うようになったっぽいなあとソースを確認したら、crypto/dsa/dsa_gen.c で

    const EVP_MD *evpmd;
    size_t qbits = bits >= 2048 ? 256 : 160;
 
    if (bits >= 2048)
        {
        qbits = 256;
        evpmd = EVP_sha256();
        }
    else
        {
        qbits = 160;
        evpmd = EVP_sha1();
        }
 
    return dsa_builtin_paramgen(ret, bits, qbits, evpmd,
        seed_in, seed_len, NULL, counter_ret, h_ret, cb);
    }

というように鍵長が 2048 ビット以上の時は EVP_sha256() を使うようになっていた。
この部分、OpenSSL 0.9.8x では EVP_sha1() を使うようになっている。
# 正確には dsa_builtin_paramgen() には qbits, evpmd を渡さず、dsa_builtin_paramge() の中で常に EVP_sha1() を使うようになっている。

以前書いたけれど、DSA を定義している FIPS 186-3 では、鍵長と使用するダイジェスト関数の出力長の組み合わせとして (1024, 160), (2048, 224), (2048, 256), (3072, 256) の四つが許されている。
なので、上記の変更は FIPS 186-3 の為となるのだが、SSH プロトコルとの整合性で問題になる。

SSH プロトコルで DSA 関連を定義しているのは RFC 4253 なのだが、この中では DSA と組み合わせて利用するダイジェスト関数は SHA-1 に決め打ちされている。
なので、SHA2-256 を使った鍵は当然使えない。

以前はどうだったかというと、2048 ビット以上でも SHA-1 を使った鍵を生成していた。
これは FIPS 186-3 (および FIPS 186-2) に準拠していない正しくない鍵なのだが、OpenSSH では使えていた。

何時からこの使えない鍵を生成するようになったかというと、OpenSSL 1.0.0 を使うようになった 2010/05/31 の Tera Term 4.66 からという事になる。
つまり、2 年以上気付いていなかったという事に… orz
まあ、SSH 的に正しい DSA 鍵は 1024 ビットという話になるので、サポート外の鍵までは保証出来ないという事になるんだけれど。

状況は判ったけれど、どう対応するかというのも問題である。候補としては、

  1. DSA 鍵の生成では 1024 ビットのみを許す。
  2. なんとかして以前と同じ SHA-1 な鍵を生成する。
  3. サポート外の鍵なので、対処無し。

が挙げられる。
使いようの無い鍵を生成している現状から 3 は無いので、可能ならば 2、それが駄目ならば 1 にしようという話に現状なっている。

それではどうすれば 2048 ビット以上でも SHA-1 な鍵が生成できるか検討して

  1. OpenSSL 0.9.8 系を使うようにする。
  2. OpenSSL の該当部分に手を入れる。
  3. ttssh 内部で該当の部分相当の処理を行う。

の三つの案が出たが、どれもイマイチに思う。

1 は、今更 0.9.8 系に戻すのもなあという思いが強い。0.9.8 系がいつまでサポートされるのかも知らないし。

2 は前述の部分にちょこっと手を入れて、常に qbits=160, evpmd=EVP_sha1() になるようにすればいいのだが、
OpenSSL を更新する時に毎回パッチをあてなければいけないのが面倒。パッチをあてわすれて問題が再発とかありそうだし。

3 は OpenSSL 内部向けの関数(dsa_builtin_paramge()) を呼ぶ必要が有るのが問題。
関数の仕様が変えられたりする可能性があるわけで。実際、0.9.8 系とは引数が違うし。

という事で、DSA 鍵は 1024 ビットのみ許可という事になるのかなあ。

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
typodupeerror

普通のやつらの下を行け -- バッドノウハウ専門家

読み込み中...