ICAP で CA のRSA秘密鍵を 512bit より長くする方法について 1999.01.08 (改版) 1999.02.22 m-sakura@ccs.mt.nec.co.jp ICAP では、CAのRSA秘密鍵の長さが 512bit です。 CA の秘密鍵は、1,024bit や2,048bit にしたいという要求は当然あります。 今回、SSLeayの一部のコマンドと組み合わせて、SSLeay で作成した1,024bit 以上の鍵を ICAP で利用する方法がわかりましたのでメモとしてまとめます。 なお、SSLeay のインストールは既にされていると想定します。 以下の説明では、SSLeay と ICAP とは、必ずしも同じホスト上にインストー ルされていないことを想定しています。 ---------------------------------------------------------------------- 1. SSLeay のインストールされているホスト上で、添付する perl スクリプト を実行する。 スクリプト中で、SSLeay コマンドのインストールされているパス変数 $ssleay_com_path を自分の環境に合わせること。 たとえば、/tmp/NEWKEYGEN という名前でスクリプトをセーブしたとして、 以下のように作業する。 ssleay_host% cd /tmp ssleay_host% chmod 755 NEWKEYGEN ssleay_host% ./NEWKEYGEN 1024 > ca.key 注) ca.key には、1,024bitのRSA鍵情報が ICAP で扱える形式で入っている。 2. ICAP のインストールされているホストに ca.key ファイルを持ってくる。 ここでは、/tmp/ca.key にセーブしたとする。 (ca.key ファイルには秘密鍵の情報が含まれるため、うかつにコピーを残 さないように注意。) 3. ICAP に秘密鍵ファイルをインストールする。 以下では、ICAP パッケージを展開しているディレクトリを $ICAP とする。 3.1 ICAP のインストールをまだしていない場合(新規) (0) install コマンドを実行する #cd $ICAP #./install (1) 2の秘密鍵ファイルを ICAP の所定の場所に移動する。 # cd $ICAP/etc # mv /tmp/ca.key ca.key # chown (ICAPの実行ユーザ) ca.key # chmod 400 ca.key (2) ICAP 初期設定メニューを1から実行する。 「3. CAの秘密鍵を作る」を除いて、 1,2,4,5,6,7,8 と実行する。 3.2 ICAP のインストールを既にしてある場合(変更) (1) ICAP の秘密鍵ファイルを変更する。 # cd $ICAP/etc # mv ca.key ca.key.org # mv ca.self ca.self.org # mv ca.cert ca.cert.org # mv /tmp/ca.key ca.key # chown (ICAPの実行ユーザ) ca.key # chmod 400 ca.key (2) (単独または階層の最上位CAである場合) CAの証明書のシリアル番号を書き換える # vi lib/icap-libx509.pl make_ca_ber 関数で、シリアル番号を 決めうちしている部分があるので以下のように置き換える (変更前) 5行目 $SerialNumber = springf("%02x", 0); (変更後) local($serial_numberfile); local($no); local($hexno); $serial_numberfile = "$ICAP_CDB/SN"; if (-e $serial_numberfile){ $no = hex(`cat $serial_numberfile`) + 1; }else{ $no = 1; } $hexno = sprintf('%lx', $no); open(W, ">$serial_numberfile") || &CGI_error("SN:$!"); exit(1) if $CGI_err; &locking(W) || &CGI_error("LOCK:$!"); exit(1) if $CGI_err; print W $hexno; &unlocking(W) || &CGI_error("UNLOCK:$!"); exit(1) if $CGI_err; close(W); $hexno = (length($hexno) % 2)? "0".$hexno: $hexno; $SerialNumber = &make_BER_integer($hexno); (3) cgi-bin/icap-start2.pl と cgi-bin/icap-start2 の最初の方 (require 'icap-llibx509.pl'; の後)に以下を追加。 require 'icap-libasn1.pl'; (4) 以下のICAP 初期設定メニューを実行する。 「4. CA名を選ぶ」←CA名が変わらなくても必ず実行する 「5. CAの公開鍵を登録する」 「6. CAのポリシーを登録する」 「7. CAの証明書を組み込む」 ---------------------------------------------------------------------- <制限事項> 今回ご紹介した方法では、 管理者向けメニュー「12. CAの鍵を変更する」を実行して 512bit を越える鍵に変更するところまではできません。 できるようにするには、 SSLeay と ICAP を同一ホストにインストールした上で、 ICAP の cgi-bin スクリプトを変更する必要があります。 ---------------------------------------------------------------------- <応用> SSLeay と ICAP が同一ホストにインストールされている場合で、 今回のスクリプトを ICAP に組み込んでしまいたいという場合は、以下のスク リプトを変更することになります。 ・初期設定メニュー「3. CAの秘密鍵を作る」への対応 $ICAP/cgi-bin/icap-start-3.pl ・管理者向けメニュー「12. CAの鍵を変更する」への対応 $ICAP/cgi-bin/icap-admin_change_key.pl 以上 ---------------------------------------------------------------------- perl スクリプト ----------ここから #! /usr/local/bin/perl # # SSLeay の genrsa コマンドでRSAの鍵対を作成し、 # ICAP の秘密鍵ファイル形式(OSISECのRSAライブラリの秘密鍵データ形式) # に合わせて出力するコマンド # # Usage: NEWKEYGEN 秘密鍵のbit数 # Example: ./NEWKEYGEN 1024 > ca.key # # SSLeay の genrsa コマンドで作成されるデータは PKCS#1 の DER形式。 # PKCS#1のパラメータ名と ICAPの秘密鍵ファイル中のパラメータ名との # 対応は以下のとおり。 # # PKCS1 ICAP key file 一般名 #----------------------------------------------------------- # n N modulus # d D privateExponent # p Q prime1 # q P prime2 # e1 d2 exponent1 # e2 d1 exponent2 # co A coefficient #----------------------------------------------------------- # # 注) ICAP では、Eの値を 0x10001 として固定しているため、 # genrsa で Eの値を必ず 0x10001 とすること。 # $ssleay_com_path = "/usr/local/ssl/bin"; $sec_bits = shift (@ARGV); if ((!$sec_bits) || ($sec_bits !~ /^\d+/)){ print "Usage: NEWKEYGEN number-of-bits\n"; exit 1; } open(GEN, "$ssleay_com_path/genrsa $sec_bits | $ssleay_com_path/rsa -text|") || die ("Can't generate key"); while (){ chop; if (/^modulus:/){ $flag = "modulus"; }elsif (/^privateExponent:/){ $flag = "privateExponent"; }elsif (/^prime1:/){ $flag = "prime1"; }elsif (/^prime2:/){ $flag = "prime2"; }elsif (/^exponent1:/){ $flag = "exponent1"; }elsif (/^exponent2:/){ $flag = "exponent2"; }elsif (/^coefficient:/){ $flag = "coefficient"; }elsif (/^\s/){ s/^\s+//; $value{$flag} .= $_; } } close(GEN); @params = ("modulus", "privateExponent", "prime1", "prime2", "exponent1", "exponent2", "coefficient"); foreach $par (@params){ $value{$par} =~ s/^00://; $value{$par} =~ s/://g; } %icap_key_params = ( "P ", "prime2", "Q ", "prime1", "A ", "coefficient", "N ", "modulus", "D ", "privateExponent", "d1 ", "exponent2", "d2 ", "exponent1", ); # # last output # print "L = $sec_bits\n"; foreach $par ("P ", "Q ", "A ", "N ", "D ", "d1 ", "d2 "){ print "$par= $value{$icap_key_params{$par}}\n"; } exit 0; ----------ここまで