過去の記事 CSR作成方法+自己署名(オレオレ証明書) とほぼ同じ内容の再整理です。
いつもの決め打ちシェルスクリプトです。
対話的な入力部分で expect というコマンドを利用しているので、環境によってはインストールが必要かもしれません。
# ディスティングイッシュネーム情報 あたりがデフォルト値なので、いつも同じ値を利用するならここを編集しておくと、いちいちオプションで指定する必要がなくなり便利です。
秘密鍵のパスフレーズははずした状態で作成完了します。
#! /bin/sh # 利用する openssl コマンドのパス OPENSSL=/usr/local/ssl/bin/openssl # 作成したキーなどのディレクトリ # 実際には [OUTDIR]/[YYYYMMDD]/[FQDN]_[HHMMSS].key :秘密鍵 # [OUTDIR]/[YYYYMMDD]/[FQDN]_[HHMMSS].csr :CSR # [OUTDIR]/[YYYYMMDD]/[FQDN]_[HHMMSS].crt :署名済み公開鍵(SSL証明書) OUTDIR=$(dirname $0)/$(date +"%Y%m%d") [ ! -e ${OUTDIR} ] && mkdir -p ${OUTDIR} # ランダムファイル名 RNDFILE=${OUTDIR}/rnd.txt # 作成モード(実行時オプション [-K|-C|-S]) RM=(dummy onlykey keycsr selfsigned) RUNMODE="" # キー長(実行時オプション [-b]) KL=(dummy 1024 2048) KEYLEN="2048" # 自己署名証明書の有効期間(日)(実行時オプション [-d]) DAYS=365 # ================================================================== # ディスティングイッシュネーム情報 # FQDN 以外はオプションで指定がない限りこの値を利用 # FQDN は入力またはオプション指定必須 # ================================================================== # 国(実行時オプション [-c]) CN=JP # 都道府県(実行時オプション [-s]) ST=Tokyo # 市区町村(実行時オプション [-l]) LN=Minato-ku # 組織名(会社名など)(実行時オプション [-o]) ON="My Company Ltd" # 部署名など(省略可)(実行時オプション [-u]) UN="" # コモンネーム(別途指定)(実行時オプション [-f]) FQDN="" # ================================================================== # ランダムファイルを作成し、各ファイル名生成 create_rnd() { echo "---------------------" echo "実行コマンド: ${OPENSSL} sha1 * > ${RNDFILE}" echo "---------------------" ${OPENSSL} sha1 * > ${RNDFILE} local KEYTIME=$(date +"%H%M%S") PRIVKEY=${OUTDIR}/${FQDN}_${KEYTIME}.key CSRFILE=${OUTDIR}/${FQDN}_${KEYTIME}.csr CRTFILE=${OUTDIR}/${FQDN}_${KEYTIME}.crt } # ランダムファイル削除 delete_rnd() { echo "---------------------" echo "実行コマンド: rm -rf ${RNDFILE}" echo "---------------------" rm -rf ${RNDFILE} } # 秘密鍵作成 create_priv_key() { local PASSPHRS="dummypassphrasedummypassphrase" # ランダムファイル作成、ファイル名生成 create_rnd # 秘密鍵作成 echo "---------------------" echo "実行コマンド: ${OPENSSL} genrsa -des3 -out ${PRIVKEY} -rand ${RNDFILE} ${KEYLEN}" echo "---------------------" expect -c " spawn ${OPENSSL} genrsa -des3 -out ${PRIVKEY} -rand ${RNDFILE} ${KEYLEN} expect \"Enter pass phrase for ${PRIVKEY}:\" send \"${PASSPHRS}\n\" expect \"Verifying - Enter pass phrase for ${PRIVKEY}:\" send \"${PASSPHRS}\n\" interact " # パスフレーズはずし echo "---------------------" echo "実行コマンド: ${OPENSSL} rsa -in ${PRIVKEY} -out ${PRIVKEY}" echo "---------------------" expect -c " spawn ${OPENSSL} rsa -in ${PRIVKEY} -out ${PRIVKEY} expect \"Enter pass phrase for ${PRIVKEY}:\" send \"${PASSPHRS}\n\" interact " # ランダムファイル削除 delete_rnd } # CSR作成 create_csr() { echo "---------------------" echo "実行コマンド: ${OPENSSL} req -new -key ${PRIVKEY} -out ${CSRFILE}" echo "---------------------" expect -c " spawn ${OPENSSL} req -new -key ${PRIVKEY} -out ${CSRFILE} expect \"Country Name (2 letter code)*:\" send \"${CN}\n\" expect \"State or Province Name (full name)*:\" send \"${ST}\n\" expect \"Locality Name (eg, city)*:\" send \"${LN}\n\" expect \"Organization Name (eg, company)*:\" send \"${ON}\n\" expect \"Organizational Unit Name*:\" send \"${UN}\n\" expect \"Common Name*:\" send \"${FQDN}\n\" expect \"Email Address*:\" send \"\n\" expect \"A challenge password*:\" send \"\n\" expect \"An optional company name*:\" send \"\n\" interact " } sign() { echo "---------------------" echo "実行コマンド: ${OPENSSL} x509 -in ${CSRFILE} -out ${CRTFILE} -req -signkey ${PRIVKEY} -days ${DAYS}" echo "---------------------" ${OPENSSL} x509 -in ${CSRFILE} -out ${CRTFILE} -req -signkey ${PRIVKEY} -days ${DAYS} } # ------------------------------------------------------------------------- # 作成モードオプション関連 # ------------------------------------------------------------------------- # 作成モードの対話的指定 run_mode() { local TMP echo "--------------------------------------------" echo "処理モードを選択してください。" echo "[1] 秘密鍵のみ作成" echo "[2] 秘密鍵とCSRを作成" echo "[3] 自己署名証明書(オレオレ証明書)作成" echo "" echo -n "[ 1 or 2 or 3 ]? > " read TMP if [ ${TMP} = "1" -o ${TMP} = "2" -o ${TMP} = "3" ] then RUNMODE=${RM[${TMP}]} else run_mode fi } # 作成モードのオプション指定時のチェック MODECHK() { if [ "${RUNMODE}" = "" ]; then RUNMODE=${RM[$1]} else # 作成モードのオプション指定時のエラー echo "オプション -K, -C, -S はいずれか1つのみ指定できます。" exit 1 fi } # ------------------------------------------------------------------------- # FQDN関連 # ------------------------------------------------------------------------- FQDNCHK() { local TMP echo -n "コモンネーム(FQDN)を入力してください。: " read TMP if [ "${TMP}" = "" ]; then FQDNCHK else FQDN="${TMP}" fi } # ------------------------------------------------------------------------- # キー長関連 # ------------------------------------------------------------------------- key_length() { local TMP echo "キー長を選択してください。" echo "[1] 1024 bit" echo "[2] 2048 bit" echo "" echo -n "[ 1 or 2 or 3 ]? > " read TMP if [ ${TMP} = "1" -o ${TMP} = "2"] then KEYLEN=${KL[${TMP}]} else key_length fi } # ------------------------------------------------------------------------- # 以下 メイン # ------------------------------------------------------------------------- onlykey() { echo "--------------------------------------------" echo "[1] 秘密鍵のみ作成" echo "--------------------------------------------" create_priv_key } keycsr() { echo "--------------------------------------------" echo "[2] 秘密鍵とCSRを作成" echo "--------------------------------------------" create_priv_key create_csr } selfsigned() { echo "--------------------------------------------" echo "[3] 自己署名証明書(オレオレ証明書)作成" echo "--------------------------------------------" create_priv_key create_csr sign } # ヘルプ usage() { echo -e "" echo -e "--------------------------------------------------------------------------" echo -e "[注意事項]" echo -e "--------------------------------------------------------------------------" echo -e "作成モードの指定は必須です。" echo -e "-K | -C | -S オプションのいずれかで指定がない場合、対話的に入力します。" echo -e "" echo -e "全ての作成モードでFQDNの指定は必須です。" echo -e "-f オプションで指定がない場合、対話的に入力します。" echo -e "" echo -e "その他のオプションは、オプションによる指定がない場合は、" echo -e "必要に応じてデフォルト値が利用されます。" echo -e "" echo -e "--------------------------------------------------------------------------" echo -e "[オプション]" echo -e "--------------------------------------------------------------------------" echo -e "\t-h: ヘルプの表示(この画面を表示します)" echo -e "" echo -e "作成モードの指定(いずれか1つの指定のみ有効)" echo -e "\t-K: 秘密鍵のみ作成" echo -e "\t-C: 秘密鍵とCSRを作成" echo -e "\t-S: 秘密鍵とCSR、自己署名証明書を作成" echo -e "" echo -e "CSRのディスティングイッシュネーム" echo -e "\t-c [2文字]: 国名(JP など) 省略時:${CN}" echo -e "\t-s [文字列]: 都道府県名(Tokyo など) 省略時:${ST}" echo -e "\t-l [文字列]: 市区町村(Minato-kuなど) 省略時:${LN}" echo -e "\t-o [文字列]: 組織名・会社名 省略時:${ON}" echo -e "\t-u [文字列]: ユニット名(部署名やサーバ名など区分のためのもの。省略可) 省略時:${UN}" echo -e "\t-f [文字列]: コモンネーム(FQDN)" echo -e "" echo -e "キーペア作成時の設定" echo -e "\t-b [1024 または 2048]: キー長の指定 省略時:${KEYLEN}" echo -e "\t-d [数値]: 自己署名時の証明書有効期間(日) 省略時:${DAYS}" echo -e "" echo -e "--------------------------------------------------------------------------" echo -e "[コマンド使用例]" echo -e "--------------------------------------------------------------------------" echo -e "秘密鍵、CSR、自己署名証明書の作成" echo -e "\t(スクリプト名) -S -c JP -s Tokyo -l Minato-ku -o \"Company Name\" -f www.example.com -b 2048 -d 365" echo -e "" echo -e "" echo -e "" echo -e "" echo -e "" } # コマンドオプション処理 while getopts hKCSb:c:d:f:l:o:s:u: opt do case ${opt} in h) # ヘルプ usage exit 0 ;; K) # 秘密鍵のみ作成 MODECHK 1 ;; C) # 秘密鍵+CSR作成 MODECHK 2 ;; S) # 秘密鍵+CSR+自己証明証明書作成 MODECHK 3 ;; c) # 国 if [ ${#OPTARG} = 2 ]; then CN=${OPTARG} else # CSRの国名のオプション指定時のエラー echo "国名(-c)は文字列2文字のみ指定できます。" exit 1 fi ;; s) # 都道府県 ST="${OPTARG}" ;; l) # 市区町村 LN="${OPTARG}" ;; o) # 組織名 ON="${OPTARG}" ;; u) # 単位名(部署名やサーバ名など区分のためのもの。省略可) UN="${OPTARG}" ;; f) # コモンネーム FQDN="${OPTARG}" ;; b) # キー長 if [ "${OPTARG}" = "1024" -o "${OPTARG}" = "2048" ]; then KEYLEN=${OPTARG} else # キー長のオプション指定時のエラー echo "キー長(-l)オプションには 1024 または 2048 のみ指定できます。" exit 1 fi ;; d) # 自己署名時の証明書有効期間(日) # 引数が数値かチェック expr 1 + "${OPTARG}" >/dev/null 2>&1 case $? in 0 | 1 ) DAYS="${OPTARG}" ;; * ) # 証明書有効期間のオプション指定時のエラー echo "有効期間(-d)は数値のみ指定できます。" exit 1;; esac ;; \?) echo "指定したオプションが無効です。" usage exit 1;; esac done [ "${RUNMODE}" = "" ] && run_mode [ "${FQDN}" = "" ] && FQDNCHK ${RUNMODE}
[Blog:技術系メモ http://t.co/05Kz5Lht ] に新規投稿しました。 「 改:CSR作成方法+自己署名(オレ�... 」