過去の記事 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作成方法+自己署名(オレ�... 」