カテゴリ

OpenSSL

過去の記事 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}

コメント

いただいたコメント
  1. [Blog:技術系メモ http://t.co/05Kz5Lht ] に新規投稿しました。 「 改:CSR作成方法+自己署名(オレ�... 」