CertReq で作成した CSR の文字化けを回避する

Pocket

Windows Server の certreq.exe を使って、 https 等を目的に サーバー証明書署名要求 (CSR) を作成した際に、 その CSR や署名後の CER で、 サブジェクト字が文字化けしてしまう場合がある。

 

この問題は、 certreq.exe にて、テキストファイル (.inf ファイル) から CSR を作成した場合に発生する。

そしてこれは、 .inf ファイルを BOM付き UTF-16 LE で保存すれば解決する。
(BOM付き/BOMなし の UTF-8 には対応していない)


Windows のメモ帳であれば、 文字コードを Unicode に設定すれば、 OK だ。

対処法は単純だが、原因が少しややこしかったので、少し深堀りしてみる。

CSR が文字化けする要因

そもそも、文字化けする要因は以下の3カ所あった。

  1. .inf ファイルが ASCII (Shift_JIS) で保存すると Unicode の情報が失われる
  2. certreq.exe が .inf ファイルの文字コードの解決に失敗する
  3. X.509 の文字列のエンコードが UTF-8 が指定されていない

(1) はまぁわかりやすいだろう。
テルグ文字や絵文字など、 Shift_JIS に存在しない Unicode の文字が文字化けするのは、これが原因だ。

ところが、 古い Windows Server (2012 あたりとか) だったり、 .inf の内容によっては、 非 Shift_JIS 文字だけでなく、 非Ascii 文字 (上のスクショで言うと "京都府" のあたり) も文字化けする場合がある。
これは (1) だけでは説明がつかない。

(2) については、 .inf ファイルが Shift_JIS や UTF-8 で保存されていると、 certreq.exe が文字コードの解決を誤ってしまう場合があるのが原因だ。
おそらく、 OS のロケールなどを見て、 BOM付き UTF-16 LE ではないファイルが .inf ファイルに渡されたときの挙動が決まるのだと思われる。

この問題も、 .inf ファイルを .inf ファイルを BOM付き UTF-16 LE で保存すれば、文字の解釈が明確になるので、文字化けしなくなる。

なお、 (3) については、現行のサポート中の OS では気にする必要はないだろう。 古い OS だと、 HTTPS サーバー証明書の規格である X.509 で、扱う文字列を UTF-8 で記述するバージョンに対応していない可能性がある。

サーバー証明書のサブジェクトに顔文字を入れる

試しに、 以下のような内容の request.inf ファイルを、 BOM付き UTF-16 LE で保存して、 certreq.exe で CSR ファイルを作成してみよう。

[NewRequest]
Subject = "CN=(´◉◞౪◟◉); OU=🥺; O=aquasoftware.net; L=京都市; ST=京都府; C=JP; E=hoge@example.com"
X500nameflags = "CERT_NAME_STR_SEMICOLON_FLAG"
KeyLength = 3072
KeySpec = AT_KEYEXCHANGE
KeyUsage = "CERT_DIGITAL_SIGNATURE_KEY_USAGE | CERT_KEY_ENCIPHERMENT_KEY_USAGE"
HashAlgorithm = sha256
MachineKeySet = True
ProviderName = "Microsoft RSA SChannel Cryptographic Provider"
ProviderType = 12
RequestType = CMC

[EnhancedKeyUsageExtension]
OID=1.3.6.1.5.5.7.3.1

[Extensions]
2.5.29.17="{text}"
_continue_ = "DNS=aaa.example.com&"
_continue_ = "DNS=bbb.example.com&"
_continue_ = "IPAddress=192.0.2.1&"
_continue_ = "IPAddress=192.0.2.2"
PS> certreq.exe -new .\request.inf .\csr.req

CertReq: 要求が作成されました

.inf ファイルの書き方については、 certreq | Microsoft Docs のドキュメントを参照のこと。
いくつか特徴的な部分について解説しておくと、

  • Subject 内のパラメーターに "," が使えるよう、 X500nameflagsCERT_NAME_STR_SEMICOLON_FLAG を指定して、区切りを ";" に変更している。
  • OID=1.3.6.1.5.5.7.3.1 の部分では、「拡張キー使用法」に「サーバー認証」の仕組みを与えている。
  • [Extensions]2.5.29.17=... の部分では、 SubjectAltName (SAN) に、 DNS や IpAddress を指定している。 SAN の指定がないと、 Chrome で証明書エラーになってしまうため。

これを CA で署名してもらってサーバー証明書として使えば、サーバー証明書内で絵文字ですら使えるようになる。

コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください