何か不足していますか?これは自己署名証明書を作成する正しい方法ですか?
自己署名証明書は簡単に作成できます。openssl req
コマンドを使用するだけです。ブラウザやコマンドラインツールなど、最も多くのクライアントが使用できるものを作成するのは難しい場合があります。
ブラウザには独自の要件があり、IETFよりも制限が厳しいため、難しいです。ブラウザーが使用する要件は、CA /ブラウザーフォーラムに文書化されています(以下の参照を参照)。制限は、(1)トラストアンカーと(2)DNS名の2つの主要な領域で発生します。
最新のブラウザー(2014/2015で使用しているウェアーズなど)は、トラストアンカーにチェーンで戻る証明書を必要としており、証明書でDNS名が特定の方法で提示されることを望んでいます。また、ブラウザは自己署名サーバー証明書に積極的に反対しています。
一部のブラウザでは、自己署名サーバー証明書を簡単にインポートできません。実際、Androidのブラウザーなど、一部のブラウザーでは使用できません。したがって、完全な解決策は、あなた自身の権威になることです。
独自の権限を持たない場合は、DNS名を正しく取得して、証明書に最大の成功の機会を与える必要があります。しかし、私はあなたがあなた自身の権威になることをお勧めします。自分の権威になるのは簡単で、すべての信頼の問題を回避します(自分より信頼できる人はいますか?)。
これはおそらくあなたが探しているサイトではありません!
サイトのセキュリティ証明書は信頼されていません!
これは、ブラウザがトラストアンカーの定義済みリストを使用してサーバー証明書を検証するためです。自己署名証明書は、信頼できるアンカーにチェーンバックしません。
これを回避する最良の方法は次のとおりです。
- 独自の権限を作成する(つまり、CAになる)
- サーバーの証明書署名要求(CSR)を作成する
- CAキーでサーバーのCSRに署名します
- サーバーにサーバー証明書をインストールする
- クライアントにCA証明書をインストールする
ステップ1- 独自の認証局を作成するということはCA: true
、適切な鍵の使用法を備えた自己署名証明書を作成することを意味します。つまり、サブジェクトと発行者は同じエンティティであり、CAは基本制約で trueに設定され(これもクリティカルとしてマークされている必要があります)、キーの使用法は(keyCertSign
およびcrlSign
CRLを使用している場合)、サブジェクトキー識別子(SKI)はAuthority Key Identifierと同じ(AKI)です。
自分の認証局になるには、*を参照してください。スタックオーバーフロー。次に、ブラウザが使用するトラストストアにCAをインポートします。
手順2〜4は、StartcomやCAcertなどのCAのサービスに参加するときに、一般に公開されているサーバーに対しておおよそ何を行うかです。手順1と5を使用すると、サードパーティの権限を回避し、自分自身の権限(自分より信頼できる人)として機能できます。
ブラウザの警告を回避する次善の方法は、サーバーの証明書を信頼することです。ただし、Androidのデフォルトのブラウザーなど、一部のブラウザーでは許可されていません。そのため、このプラットフォームでは機能しません。
ブラウザー(および他の同様のユーザーエージェント)が自己署名証明書を信頼しないという問題は、モノのインターネット(IoT)で大きな問題になるでしょう。たとえば、サーモスタットまたは冷蔵庫に接続してプログラムするとどうなりますか?答えは、ユーザーエクスペリエンスに関する限り、何も良いことではありません。
W3CのWebAppSecワーキンググループがこの問題を検討し始めています。たとえば、「プロポーザル:HTTPを非セキュアとしてマークする」を参照してください。
OpenSSLで自己署名証明書を作成する方法
以下のコマンドと構成ファイルは、自己署名証明書を作成します(署名要求の作成方法も示します)。これらは、1つの点で他の回答とは異なります。自己署名証明書に使用されるDNS名は、共通名(CN)ではなく、サブジェクト代替名(SAN)にあります。
DNS名は、行を含む構成ファイルを介してSANに配置されますsubjectAltName = @alternate_names
(コマンドラインを使用して行う方法はありません)。次にalternate_names
、構成ファイルにセクションがあります(好みに合わせてこれを調整する必要があります)。
[ alternate_names ]
DNS.1 = example.com
DNS.2 = www.example.com
DNS.3 = mail.example.com
DNS.4 = ftp.example.com
# Add these if you need them. But usually you don't want them or
# need them in production. You may need them for development.
# DNS.5 = localhost
# DNS.6 = localhost.localdomain
# IP.1 = 127.0.0.1
# IP.2 = ::1
IETFとCA /ブラウザフォーラムの両方でプラクティスが指定されているため、CNではなくSANにDNS名を配置することが重要です。また、CN内のDNS名が廃止されることを指定しています(ただし、禁止されていません)。DNS名をCNに入れる場合は、CA / Bポリシーの下でSANに含める必要があります。したがって、サブジェクトの別名の使用を避けることはできません。
DNS名をSANに配置しない場合、証明書はCAおよびブラウザーフォーラムのガイドラインに準拠するブラウザーやその他のユーザーエージェントで検証できません。
関連:ブラウザーはCA /ブラウザーフォーラムポリシーに従います。IETFポリシーではありません。これが、OpenSSLで作成された証明書(通常はIETFに準拠)がブラウザーで検証されない理由の1つです(ブラウザーはCA / Bに準拠します)。それらは異なる標準であり、異なる発行ポリシーと異なる検証要件があります。
自己署名証明書を作成します(-x509
オプションの追加に注意してください):
openssl req -config example-com.conf -new -x509 -sha256 -newkey rsa:2048 -nodes \
-keyout example-com.key.pem -days 365 -out example-com.cert.pem
署名リクエストを作成します(-x509
オプションがないことに注意してください):
openssl req -config example-com.conf -new -sha256 -newkey rsa:2048 -nodes \
-keyout example-com.key.pem -days 365 -out example-com.req.pem
自己署名証明書を印刷します。
openssl x509 -in example-com.cert.pem -text -noout
署名リクエストを印刷します。
openssl req -in example-com.req.pem -text -noout
構成ファイル(-config
オプション経由で渡される)
[ req ]
default_bits = 2048
default_keyfile = server-key.pem
distinguished_name = subject
req_extensions = req_ext
x509_extensions = x509_ext
string_mask = utf8only
# The Subject DN can be formed using X501 or RFC 4514 (see RFC 4519 for a description).
# Its sort of a mashup. For example, RFC 4514 does not provide emailAddress.
[ subject ]
countryName = Country Name (2 letter code)
countryName_default = US
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = NY
localityName = Locality Name (eg, city)
localityName_default = New York
organizationName = Organization Name (eg, company)
organizationName_default = Example, LLC
# Use a friendly name here because it's presented to the user. The server's DNS
# names are placed in Subject Alternate Names. Plus, DNS names here is deprecated
# by both IETF and CA/Browser Forums. If you place a DNS name here, then you
# must include the DNS name in the SAN too (otherwise, Chrome and others that
# strictly follow the CA/Browser Baseline Requirements will fail).
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_default = Example Company
emailAddress = Email Address
emailAddress_default = test@example.com
# Section x509_ext is used when generating a self-signed certificate. I.e., openssl req -x509 ...
[ x509_ext ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
# You only need digitalSignature below. *If* you don't allow
# RSA Key transport (i.e., you use ephemeral cipher suites), then
# omit keyEncipherment because that's key transport.
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
subjectAltName = @alternate_names
nsComment = "OpenSSL Generated Certificate"
# RFC 5280, Section 4.2.1.12 makes EKU optional
# CA/Browser Baseline Requirements, Appendix (B)(3)(G) makes me confused
# In either case, you probably only need serverAuth.
# extendedKeyUsage = serverAuth, clientAuth
# Section req_ext is used when generating a certificate signing request. I.e., openssl req ...
[ req_ext ]
subjectKeyIdentifier = hash
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
subjectAltName = @alternate_names
nsComment = "OpenSSL Generated Certificate"
# RFC 5280, Section 4.2.1.12 makes EKU optional
# CA/Browser Baseline Requirements, Appendix (B)(3)(G) makes me confused
# In either case, you probably only need serverAuth.
# extendedKeyUsage = serverAuth, clientAuth
[ alternate_names ]
DNS.1 = example.com
DNS.2 = www.example.com
DNS.3 = mail.example.com
DNS.4 = ftp.example.com
# Add these if you need them. But usually you don't want them or
# need them in production. You may need them for development.
# DNS.5 = localhost
# DNS.6 = localhost.localdomain
# DNS.7 = 127.0.0.1
# IPv6 localhost
# DNS.8 = ::1
Chromeでは次の操作が必要になる場合があります。それ以外の場合、Chromeは一般名が無効であると警告するERR_CERT_COMMON_NAME_INVALID
場合があります()。この場合、SANのIPアドレスとCNの関係がわかりません。
# IPv4 localhost
# IP.1 = 127.0.0.1
# IPv6 localhost
# IP.2 = ::1
X.509 / PKIX証明書のDNS名の処理に関しては、他にもルールがあります。ルールについては、次のドキュメントを参照してください。
RFC 6797およびRFC 7469は、他のRFCおよびCA / Bドキュメントよりも制限が厳しいため、リストされています。RFC 6797および7469 も IPアドレスを許可しません。