三行まとめ
- Git Bashを使って、OpenSSLでcsrファイルを作成しようとしたけどエラーになった
- 原因はGit Bash経由で叩くOpenSSLのsubjオプション内でドットの文字解釈がうまくいってないっぽい
- PowerShellでコマンドを叩き直したらうまくいった
目次
経緯と事象
とある日、いくつかのWebサービスの証明書を更新するため、csrファイルを準備していました。
当方ではWindowsをメインで使っているため、csrファイルはGit Bashを使って作成する運用としていました。
従来の手順は、 openssl req
コマンドの対話形式でSubjectを入力し、CSRを作成していました。
最近は作業対象の証明書が多くなってきたことから、subj
オプションを用いてコマンドラインからSubjectを指定する方法に変更しました。
実際には以下のようなコマンドを叩いています。
winpty openssl req -new -key ./sample.key -out ./sample.csr -subj "/C=JP/ST=Tokyo/L=Nakano-ku/O=TEST INC./OU=DEV DIVISION/CN=sample.com"
上記コマンドを実行したところ、以下のようなエラーが表示され、csrファイルは作成されませんでした。
req: subject name is expected to be in the format /type0=value0/type1=value1/type2=... where characters may be escaped by \. This name is not in that format: ...
エラー文言をそのまま読めば、「ドット文字がエスケープされてないエラーだよ」と教えてくれているようです。
先のコマンドでドット文字を探してみると、subjオプション内の “/O=TEST INC.” の末尾にドットが存在するので、そいつがエラーの原因のように思えます。
急ぎ解決方法だけ知りたい方は、[解決] うまく行った方法 に飛んでください!
試したこと(失敗例)
エラーの忠告通り、ドット文字をエスケープしてコマンドを再実行しましたが、結局同じエラーとなりました。
困ったのでエラー文言で検索をかけると、以下のページにぶち当たりました。
私は光の速さでGoogle翻訳を実行して内容を確認しました。以下は、このページで提案された方法の試行錯誤の記録をしておきます。
だめその1:環境変数 MSYS_NO_PATHCONV
を設定する
Git Bashのパス変換を無効化する環境変数とのことです。
意味もわからず(よくない)環境変数を設定(よくない)しましたが、事象は解決しませんでした。
だめその2:区切り文字をバックスラッシュにする
前述のGitHubのページの このコメント に記載されている方法です。
もともとのコマンドでは、subjオプションの区切り文字をスラッシュで指定していましたが、それを、「最初の区切り文字をスラッシュ2つ、以降の区切り文字をバックスラッシュにする」という内容です。
これに従ってコマンドを実行すると、確かにエラーは出ない。CSRも出力されました。
winpty openssl req -new -key ./sample.key -out ./sample.csr -subj "//C=JP\ST=Tokyo\L=Nakano-ku\O=TEST INC.\OU=DEV DIVISION\CN=sample.com"
ただし、出力されたファイルの内容を CSRの中身をサイトで確認すると、Subjectがバグってました。
一見うまくいっているように見えて、本質的な解決ではなかったようです。
先のGitHubのサイトでは、このコメントをもとにして動いたって人がいたんですが、その人は本当に大丈夫でしょうか、、、確かにエラーは出ないけど、、、。
[解決] うまく行った方法
結局、元のコマンドでOpenSSLをフルパスにし、PowerShellで叩いたらエラーも表示されず、内容も期待値通りのCSRが作成できました。たぶんコマンドプロンプトでも通ると思う。
例えば以下のようなコマンドです。
C:\Users\ユーザー名\AppData\Local\Programs\Git\usr\bin\openssl.exe req -new -key ./sample.key -out ./sample.csr -subj "/C=JP/ST=Tokyo/L=Nakano-ku/O=TEST INC./OU=DEV DIVISION/CN=sample.com"
たぶん根本原因
Git Bashでは、winptyコマンドを用いることでWindows環境におけるUNIXエミュレーターとの文字コード差分を吸収し、入出力を可能にしているとのことです。
以下サイトを参考にさせていただきました。
ここからは推測ですが、Windowsとエミュレーターの値渡しの際、本来のOpenSSLコマンドが期待する形式でオプションが渡されずにエラーとなってしまったのだと思います。
余談
手元のMacで以下のコマンドを実行したら、普通に実行できました。
やっぱりwinptyが原因ぽい。
openssl req -new -key ./sample.key -out ./sample.csr -subj "/C=JP/ST=Tokyo/L=Nakano-ku/O=TEST INC./OU=DEV DIVISION/CN=sample.com"
おわりに
この件以前にも、エラーが解消したように見えるけど実は解決してなかった、、ということがあり、再確認の重要性をしみじみ実感した一件でした。
Wチェックだいじ。