OpenSSLで自己署名証明書を作成する方法


1294

組み込みLinuxデバイスにHTTPSサポートを追加しています。次の手順で自己署名証明書を生成しようとしました:

openssl req -new > cert.csr
openssl rsa -in privkey.pem -out key.pem
openssl x509 -in cert.csr -out cert.pem -req -signkey key.pem -days 1001
cat key.pem>>cert.pem

これは機能しますが、たとえばGoogle Chromeでいくつかのエラーが発生します。

これはおそらくあなたが探しているサイトではありません!
サイトのセキュリティ証明書は信頼されていません!

何か不足していますか?これは自己署名証明書を作成する正しい方法ですか?


40
自己署名証明書は、インターネットにとって安全ではないと見なされています。Firefoxはサイトを無効な証明書を持つものとして扱い、Chromeは接続がプレーンHTTPであるかのように動作します。詳細:gerv.net/security/self-signed-certs
user1202136

34
CA証明書をブラウザーにインポートして、証明書を信頼することをブラウザーに通知する必要があります-または-ブラウザーによって既に信頼されている大金の組織の1つによって署名される-または-警告を無視してクリックそれを過ぎて。私は最後のオプションが好きです。
trojanfoe 2012

12
このような「ストック」のOpenSSL設定は使用しないでください。これは、サブジェクト代替名(SAN)にDNS名を配置できないためです。alternate_namesセクションを含む構成ファイルを提供し、-configオプションでそれを渡す必要があります。また、DNS名を共通名(CN)に配置することは、IETFとCA /ブラウザフォーラムの両方で非推奨(ただし禁止されていません)です。CNのDNS名もSANに存在している必要があります。SANの使用を回避する方法はありません。以下の回答を参照してください。
jww 2015年

5
@jwwのコメントに加えて。2017年5月より、ChromeはSANのない(空の)証明書を受け入れなくなりました:「このサイトの証明書には、ドメイン名またはIPアドレスを含むサブジェクトの別名拡張が含まれていません。」
GerardJP 2017年

6
最近では、インターネット経由でポート80のFQDNからWebサーバーにアクセスできる限り、LetsEncryptを使用して無料の完全なCA証明書を取得できます(90日間有効、更新は自動化できます)。メッセージ。www.letsencrypt.com
barny

回答:


2130

これは1つのコマンドで実行できます。

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365

秘密鍵をパスフレーズで保護したくない場合は、-nodes(の略no DES)を追加することもできます。それ以外の場合は、「少なくとも4文字」のパスワードの入力を求められます。

daysパラメータ(365)を使用するには、有効期限に影響を与えるために、任意の数に置き換えることができます。その後、「国名」などの入力を求められますがEnter、デフォルトをそのまま使用することができます。

-subj '/CN=localhost'証明書の内容に関する質問を抑制するために追加localhostします(目的のドメインに置き換えます)。

自己署名入りの証明書は、以前にブラウザーにインポートしていない限り、サード・パーティーで検証されません。さらにセキュリティが必要な場合は、認証局(CA)によって署名された証明書を使用する必要があります。


8
あなたが何かを自分で確認したい場合は興味のある人のために、ここにドキュメントあります。

17
サードパーティによる署名はどのようにしてセキュリティを強化しますか?
James Mills、

201
自動化でこれを使用して他の誰のために、ここでの主題のための共通パラメータのすべてです:-subj "/C=US/ST=Oregon/L=Portland/O=Company Name/OU=Org/CN=www.example.com"
アレックスS

17
@JamesMillsつまり、考えてみてください-バンの側面に「無料のキャンディ」と書かれた怪しげな男があなたを中に入れてくれるよう誘ったら、あなたは完全に二度考えてそれについて警戒するつもりです-しかし、あなたが信頼している誰か- 本当に信頼しているような-が「まあまあ、彼は合法だ」のようなものなら、あなたはその無料のキャンディーについてすべてのことになるでしょう。
BrainSlugs83

73
-sha256SHA-256ベースの証明書の生成に使用することを忘れないでください。
Gea-Suan Lin

535

何か不足していますか?これは自己署名証明書を作成する正しい方法ですか?

自己署名証明書は簡単に作成できます。openssl reqコマンドを使用するだけです。ブラウザやコマンドラインツールなど、最も多くのクライアントが使用できるものを作成するのは難しい場合があります。

ブラウザには独自の要件があり、IETFよりも制限が厳しいため、難しいです。ブラウザーが使用する要件は、CA /ブラウザーフォーラムに文書化されています(以下の参照を参照)。制限は、(1)トラストアンカーと(2)DNS名の2つの主要な領域で発生します。

最新のブラウザー(2014/2015で使用しているウェアーズなど)は、トラストアンカーにチェーンで戻る証明書を必要としており、証明書でDNS名が特定の方法で提示されることを望んでいます。また、ブラウザは自己署名サーバー証明書に積極的に反対しています。

一部のブラウザでは、自己署名サーバー証明書を簡単にインポートできません。実際、Androidのブラウザーなど、一部のブラウザーでは使用できません。したがって、完全な解決策は、あなた自身の権威になることです。

独自の権限を持たない場合は、DNS名を正しく取得して、証明書に最大の成功の機会を与える必要があります。しかし、私はあなたがあなた自身の権威になることをお勧めします。自分の権威になるのは簡単で、すべての信頼の問題を回避します(自分より信頼できる人はいますか?)。


これはおそらくあなたが探しているサイトではありません!
サイトのセキュリティ証明書は信頼されていません!

これは、ブラウザがトラストアンカーの定義済みリストを使用してサーバー証明書を検証するためです。自己署名証明書は、信頼できるアンカーにチェーンバックしません。

これを回避する最良の方法は次のとおりです。

  1. 独自の権限を作成する(つまり、CAになる)
  2. サーバーの証明書署名要求(CSR)を作成する
  3. CAキーでサーバーのCSRに署名します
  4. サーバーにサーバー証明書をインストールする
  5. クライアントにCA証明書をインストールする

ステップ1- 独自の認証局を作成するということはCA: true、適切な鍵の使用法を備えた自己署名証明書を作成することを意味します。つまり、サブジェクト発行者は同じエンティティであり、CAは基本制約で trueに設定され(これもクリティカルとしてマークされている必要があります)、キーの使用法は(keyCertSignおよびcrlSignCRLを使用している場合)、サブジェクトキー識別子(SKI)はAuthority Key Identifierと同じ(AKI)です。

自分の認証局になるには、*を参照してください。スタックオーバーフロー。次に、ブラウザが使用するトラストストアにCAをインポートします。

手順2〜4は、StartcomCAcertなどの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アドレスを許可しません


4
alternate_namesセクションでワイルドカードを使用することは可能ですか?特にサブサブドメイン。:私はここにこの答えを参照質問持つserverfault.com/questions/711596/...
LeonardChallis

3
私は彼の具体的な質問に答えました。答えが非常に単純だったので、この長いセキュリティの説明を追加しても意味がないと思います
Diego Woitasen

14
@diegows-あなたの答えは完全でも正確でもありません。それが正しくない理由は、あなたが読みたくない長い投稿で説明されています:)
jww

1
ありがとう!あなたの投稿はとても役に立ちました。FYI私は最近ボールトで遊んでいて、それがDNS.x 127ではなくIP.x 127.0.0.1で主張されているのを発見しました...これが標準であるかどうかは確認しませんでした。
Chomeh

4
@jwwありがとうございます。あなたは、言った「(すなわち、CAになる)、独自の権限を作成します。1.」、そして、言った「クライアント上のCA証明書をインストール5.」。ルートキーが危険にさらされた場合、悪意のある人物がそのキーを使用して任意のドメインの証明書に署名し、ユーザーをだましてWebサイトにアクセスさせると、中間者攻撃を実行できるようになります。証明書ではなく中間CAにのみ署名できるようにルートCAを作成する方法はありますか?次に、名前の制約を使用して中間CAを保護できます。
Robin Zimmermann

408

ドキュメントから@diegowsの回答で詳細に説明されているオプションを以下に示します。

openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days XXX
req

PKCS#10証明書要求および証明書生成ユーティリティ。

-x509

このオプションは、証明書要求の代わりに自己署名証明書を出力します。これは通常、テスト証明書または自己署名ルートCAを生成するために使用されます。

-newkey arg

このオプションは、新しい証明書要求と新しい秘密鍵を作成します。引数は、いくつかの形式のいずれかを取ります。rsa:nbitsnbitsはビット数)は、サイズがnbitsの RSA鍵を生成します。

-keyout filename

これにより、新しく作成された秘密鍵を書き込むファイル名が与えられます。

-out filename

これは、デフォルトで書き込む出力ファイル名または標準出力を指定します。

-days n

-x509オプションが使用されている場合、これは証明書を認証する日数を指定します。デフォルトは30日です。

-nodes

このオプションを指定した場合、秘密鍵が作成されても暗号化されません。

ドキュメントは実際には上記よりも詳細です。ここで要約しました。


3
XXX元のコマンドでは、「の証明書を証明する日数」で置き換える必要があります。デフォルトは30日です。たとえば、-days XXXとなり-days 365、あなたの証明書は、365日間有効にしたい場合。詳細については、ドキュメントを参照してください
Nathan Jones

ドキュメントを追加していただきありがとうございます。このIBMリンクは、この回答と同じように思われるコマンドを
The Red Pea

314

2020年以降、次のコマンドはSANを含むすべてのニーズに対応しています。

openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes \
  -keyout example.key -out example.crt -extensions san -config \
  <(echo "[req]"; 
    echo distinguished_name=req; 
    echo "[san]"; 
    echo subjectAltName=DNS:example.com,DNS:example.net,IP:10.0.0.1
    ) \
  -subj "/CN=example.com"

OpenSSL≥1.1.1では、これは次のように短縮できます。

openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes \
  -keyout example.key -out example.crt -subj "/CN=example.com" \
  -addext "subjectAltName=DNS:example.com,DNS:example.net,IP:10.0.0.1"

それはある証明書を作成します

  • ドメインexample.comおよびexample.net(SAN)に有効
  • IPアドレス10.0.0.1(SAN)にも有効、
  • 比較的強い(2020年現在)および
  • 3650数日間有効(〜10年)。

次のファイルを作成します。

  • 秘密鍵: example.key
  • 証明書: example.crt

すべての情報はコマンドラインで提供されます。あなたを困らせるインタラクティブな入力はありません。設定ファイルはありません。すべての必要なステップは、単一のOpenSSL呼び出しによって実行されます:秘密鍵の生成から自己署名証明書まで。

備考1:暗号パラメータ

証明書は自己署名されており、ユーザーが手動で受け入れる必要があるため、短い有効期限や弱い暗号化を使用しても意味がありません。

将来的に4096は、RSA鍵にビット以上のビットを使用し、ハッシュアルゴリズムをsha256が、2020年現在、これらは正気な値です。すべての最新のブラウザでサポートされている一方で、十分に強力です。

備考#2:パラメータ " -nodes"

理論的には、-nodesパラメータを省略できます(「DES暗号化なし」を意味example.keyします)。この場合、パスワードで暗号化されます。ただし、サーバーにパスワードを保存するか、再起動するたびにパスワードを手動で入力する必要があるため、サーバーのインストールにはこれはほとんど役に立ちません。

備考#3:関連項目


1
引数/ CN = localhostがC:/ Program Files / Git / CN = localhostに展開されている原因を正確に理解できなかったため、コマンド全体をプレーンcmd.exeで実行したところ、問題なく動作しました。誰かがこれに苦労している場合に備えて。
Yuriy Pozniak

1
@FranklinYu rsa:2048は、今後10年間で十分でしょうか?それは有効期間だからです。説明したように、短い有効期限や弱い暗号を使用しても意味がありません。ほとんどの2048ビットRSA鍵の有効期間は最大で1〜3年です。OpenSSL 1.1.1については、まだsha256を残しているため、より強力なハッシュが必要な場合は変更する方がより明示的で明白です。
VOG

1
@DaveFerguson //CN=localhost代わりに作成された証明書ではありません/CN=localhostか?適切な脱出はここで役立ちますか?たとえば、で置き換えること/CN=localhostにより"/CN=localhost"、問題はきれいに解決されますか?
ヴォグ

4
多数のボイラープレートを含む長々とした構成ファイルを作成する必要なく、新しい必須のSANを使用する「ワンライナー」を作成するための1000 +1。よくやった!
Joshua Pinter

1
@cautionbugありがとうございます!私はこれを答えに編集しました。Windows / MinGWの答えは正しいですか?
VOG

143

コメントできないので、別の回答としておこう。承認されたワンライナー回答にいくつかの問題を見つけました:

  • ワンライナーのキーにはパスフレーズが含まれています。
  • ワンライナーはSHA-1を使用しており、多くのブラウザーではコンソールに警告が表示されます。

パスフレーズを削除し、セキュリティを強化して警告を抑制し、コメントに提案を含めて完全な質問リストを削除する簡略化されたバージョンを次に示します。

openssl genrsa -out server.key 2048
openssl rsa -in server.key -out server.key
openssl req -sha256 -new -key server.key -out server.csr -subj '/CN=localhost'
openssl x509 -req -sha256 -days 365 -in server.csr -signkey server.key -out server.crt

「localhost」を必要なドメインに置き換えます。OpenSSLはパスフレーズを要求するため、最初の2つのコマンドを1つずつ実行する必要があります。

2つを.pemファイルに結合するには:

cat server.crt server.key > cert.pem

6
github.com/molnarg/node-http2の開発証明書が必要でしたが、この回答が最適です。
Capaj 2015年

1
単一のファイルに証明書とキーを組み合わせること:cat server.crt server.key >foo-cert.pemopenssl-1.0.2d/demos/ssl/
18446744073709551615 2015年

この方法で生成した証明書は、まだSHA1を使用しています。
user169771

1
TKS、上の自己署名証明書を作成するために素晴らしい作品FreeBSD 10 OpenLDAP 2.4とはTLS
チアゴ・ペレイラ

2
key.pemファイルはどうですか?
quikchange 2016年

72

最近のブラウザーは、SAN(サブジェクト代替名)が欠落している場合は、整形式の自己署名証明書に対してセキュリティエラーをスローするようになりました。OpenSSLはこれを指定するコマンドラインの方法を提供しないため、多くの開発者のチュートリアルとブックマークが突然古くなっています。

再び実行する最も速い方法は、短いスタンドアロンのconfファイルです。

  1. (例:OpenSSLの設定ファイルを作成しますreq.cnf

    [req]
    distinguished_name = req_distinguished_name
    x509_extensions = v3_req
    prompt = no
    [req_distinguished_name]
    C = US
    ST = VA
    L = SomeCity
    O = MyCompany
    OU = MyDivision
    CN = www.company.com
    [v3_req]
    keyUsage = critical, digitalSignature, keyAgreement
    extendedKeyUsage = serverAuth
    subjectAltName = @alt_names
    [alt_names]
    DNS.1 = www.company.com
    DNS.2 = company.com
    DNS.3 = company.net
    
  2. この構成ファイルを参照する証明書を作成します

    openssl req -x509 -nodes -days 730 -newkey rsa:2048 \
     -keyout cert.key -out cert.pem -config req.cnf -sha256
    

https://support.citrix.com/article/CTX135602の設定例


1
エラーを引き起こしていた最後のパラメーター-extensions 'v3_req'を削除した後、それは私のために働きました。WindowsでのOpenSSLの使用。最後に、私はこの問題をなんとか修正しました!ありがとう。
CGodo 2017年

1
@Kyopaxaそうです-そのパラメーターはcnfファイルの3行目で冗長です。更新しました。
rymo

2
しっかりした方法。ありがとう。追加をお勧めし-sha256ます。
cherouvim 2017

5
コマンドラインでSANを指定できるようになりました。github.com/ openssl / openssl / pull / 4986-extension 'subjectAltName = DNS:dom.ain, DNS:oth.er'参照してください
Alexandre DuBreuil

2
このオプションが呼び出された-addextようです。
Alexandr Zarubkin

67

SHA-2ハッシュアルゴリズムを使用するには、-sha256パラメーターを追加することをお勧めします。これは、主要なブラウザーが「SHA-1証明書」を安全ではないと表示することを検討しているためです。

受け入れられた回答の同じコマンドライン-@shagoが追加された@diegows

openssl req -x509 -sha256 -newkey rsa:2048 -keyout key.pem -out cert.pem -days XXX

詳細については、Googleセキュリティブログをご覧ください。

2018年5月更新。SHA -2を使用しても自己署名証明書にセキュリティは追加されないというコメントで多くの人が指摘したとおり。しかし、私はまだそれを古い/安全でない暗号化ハッシュ関数を使用しないという良い習慣として使用することをお勧めします。完全な説明は、エンドエンティティ証明書の上の証明書がSHA-1ベースであることなぜ良いのですか?にあります。


1
自己署名キーの場合は、とにかくブラウザーエラーが生成されるため、これは特に問題ではありません
Mark

30
@マーク、重要です。SHA-2の方が安全です
マリスB. 14

1
cert.pemの名前をcert.cerに変更した後にウィンドウで証明書を開くと、指紋アルゴリズムはまだSha1ですが、署名ハッシュアルゴリズムはsha256です。
罪を犯した

2
「世界クラスの暗号化*ゼロ認証=ゼロセキュリティ」gerv.net/security/self-signed-certs
x-yuri

4
自己署名証明書で使用される署名アルゴリズムは、それが信頼できるかどうかの決定には関係がないことに注意してください。ルートCA証明書は自己署名されています。2018年5月の時点で、SHA-1で署名されたアクティブなルートCA証明書はまだ多くあります。証明書がそれ自体を信頼するかどうか、またその証明書がその信頼を検証する方法は重要ではないためです。あなたはそれがであるかについてのルート/自己署名証明書を信頼するか、そうではありません。security.stackexchange.com/questions/91913/…を
Andrew Henle

20

これは、自己署名証明書にSAN(subjectAltName)を設定するためにローカルボックスで使用するスクリプトです。

このスクリプトはドメイン名(example.com)を取得し、同じ証明書で* .example.comとexample.comのSANを生成します。以下のセクションはコメントされています。スクリプトに名前を付け(例generate-ssl.sh:)、実行権限を与えます。ファイルはスクリプトと同じディレクトリに書き込まれます。

Chrome 58以降では、SANを自己署名証明書に設定する必要があります。

#!/usr/bin/env bash

# Set the TLD domain we want to use
BASE_DOMAIN="example.com"

# Days for the cert to live
DAYS=1095

# A blank passphrase
PASSPHRASE=""

# Generated configuration file
CONFIG_FILE="config.txt"

cat > $CONFIG_FILE <<-EOF
[req]
default_bits = 2048
prompt = no
default_md = sha256
x509_extensions = v3_req
distinguished_name = dn

[dn]
C = CA
ST = BC
L = Vancouver
O = Example Corp
OU = Testing Domain
emailAddress = webmaster@$BASE_DOMAIN
CN = $BASE_DOMAIN

[v3_req]
subjectAltName = @alt_names

[alt_names]
DNS.1 = *.$BASE_DOMAIN
DNS.2 = $BASE_DOMAIN
EOF

# The file name can be anything
FILE_NAME="$BASE_DOMAIN"

# Remove previous keys
echo "Removing existing certs like $FILE_NAME.*"
chmod 770 $FILE_NAME.*
rm $FILE_NAME.*

echo "Generating certs for $BASE_DOMAIN"

# Generate our Private Key, CSR and Certificate
# Use SHA-2 as SHA-1 is unsupported from Jan 1, 2017

openssl req -new -x509 -newkey rsa:2048 -sha256 -nodes -keyout "$FILE_NAME.key" -days $DAYS -out "$FILE_NAME.crt" -passin pass:$PASSPHRASE -config "$CONFIG_FILE"

# OPTIONAL - write an info to see the details of the generated crt
openssl x509 -noout -fingerprint -text < "$FILE_NAME.crt" > "$FILE_NAME.info"

# Protect the key
chmod 400 "$FILE_NAME.key"

このスクリプトは情報ファイルも書き込むため、新しい証明書を検査して、SANが正しく設定されていることを確認できます。

                ...
                28:dd:b8:1e:34:b5:b1:44:1a:60:6d:e3:3c:5a:c4:
                da:3d
            Exponent: 65537 (0x10001)
    X509v3 extensions:
        X509v3 Subject Alternative Name: 
            DNS:*.example.com, DNS:example.com
Signature Algorithm: sha256WithRSAEncryption
     3b:35:5a:d6:9e:92:4f:fc:f4:f4:87:78:cd:c7:8d:cd:8c:cc:
     ...

Apacheを使用している場合は、次のように構成ファイルで上記の証明書を参照できます。

<VirtualHost _default_:443>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/htdocs

    SSLEngine on
    SSLCertificateFile path/to/your/example.com.crt
    SSLCertificateKeyFile path/to/your/example.com.key
</VirtualHost>

新しい証明書を有効にするには、Apache(またはNginx、IIS)サーバーを再起動することを忘れないでください。


macOS High SieraおよびChrome 58で動作します
Saqib Omer

CNが全体の設定にどのように影響するかまだわかりませんか?私はこれを実行しようとしてるlocalhostか、127.0.0.1:port#どのような対応することになるCN。このような何かのために。
DJ2

@ DJ2私はBASE_DOMAIN =“ localhost”を設定します
Drakes

9

2017ワンライナー:

openssl req \
-newkey rsa:2048 \
-x509 \
-nodes \
-keyout server.pem \
-new \
-out server.pem \
-subj /CN=localhost \
-reqexts SAN \
-extensions SAN \
-config <(cat /System/Library/OpenSSL/openssl.cnf \
    <(printf '[SAN]\nsubjectAltName=DNS:localhost')) \
-sha256 \
-days 3650

これは、別の構成ファイルがなくてもSANを提供するため、Chrome 57でも機能します。こちらからの回答です

これにより、秘密鍵と証明書の両方を含む単一の.pemファイルが作成されます。必要に応じて、それらを個別の.pemファイルに移動できます。


2
Linuxユーザーの場合、構成のパスを変更する必要があります。例:現在のUbuntuでの/etc/ssl/openssl.conf動作
2018

openssl.cnfをする場所を指定する必要はありませんワンライナーは、以下を参照してくださいstackoverflow.com/a/41366949/19163
VOG

7

コメントできないので、別の回答を追加します。NGINXの自己署名証明書を作成しようとしましたが、それは簡単でしたが、Chromeのホワイトリストに追加したいときに問題が発生しました。そして私の解決策は、ルート証明書を作成し、それによって子証明書に署名することでした。

だから一歩一歩。ファイルconfig_ssl_ca.cnfを作成します。構成 ファイルにはオプションbasicConstraints = CA:trueがあります。これは、この証明書がルートであることを意味します。

一度作成すると再利用できるため、これは良い方法です。

[ req ]
default_bits = 2048

prompt = no
distinguished_name=req_distinguished_name
req_extensions = v3_req

[ req_distinguished_name ]
countryName=UA
stateOrProvinceName=root region
localityName=root city
organizationName=root organisation
organizationalUnitName=roote department
commonName=root
emailAddress=root_email@root.localhost

[ alternate_names ]
DNS.1        = market.localhost
DNS.2        = www.market.localhost
DNS.3        = mail.market.localhost
DNS.4        = ftp.market.localhost

[ v3_req ]
keyUsage=digitalSignature
basicConstraints=CA:true
subjectKeyIdentifier = hash
subjectAltName = @alternate_names

子証明書の次の構成ファイル。

[ req ]
default_bits = 2048

prompt = no
distinguished_name=req_distinguished_name
req_extensions = v3_req

[ req_distinguished_name ]
countryName=UA
stateOrProvinceName=Kyiv region
localityName=Kyiv
organizationName=market place
organizationalUnitName=market place department
commonName=FirstName LastName
emailAddress=email@market.localhost

[ alternate_names ]
DNS.1        = market.localhost
DNS.2        = www.market.localhost
DNS.3        = mail.market.localhost
DNS.4        = ftp.market.localhost

[ v3_req ]
keyUsage=digitalSignature
basicConstraints=CA:false
subjectAltName = @alternate_names
subjectKeyIdentifier = hash

最初のステップ-ルートキーと証明書を作成する

openssl genrsa -out ca.key 2048
openssl req -new -x509 -key ca.key -out ca.crt -days 365 -config config_ssl_ca.cnf

2番目のステップでは、子キーとファイルCSR-証明書署名要求を作成します。アイデアはルートで子証明書に署名して正しい証明書を取得するためです

openssl genrsa -out market.key 2048
openssl req -new -sha256 -key market.key -config config_ssl.cnf -out market.csr

Linuxターミナルを開き、次のコマンドを実行します。echo 0

echo 1 > ca.srl
touch index.txt

ca.srlの六角で次に使用するシリアル番号を含むテキストファイル。必須。このファイルが存在し、有効なシリアル番号が含まれている必要があります。

最後のステップ、もう1つの構成ファイルを作成し、config_ca.cnfという名前を付けます

# we use 'ca' as the default section because we're usign the ca command
[ ca ]
default_ca = my_ca

[ my_ca ]
#  a text file containing the next serial number to use in hex. Mandatory.
#  This file must be present and contain a valid serial number.
serial = ./ca.srl

# the text database file to use. Mandatory. This file must be present though
# initially it will be empty.
database = ./index.txt

# specifies the directory where new certificates will be placed. Mandatory.
new_certs_dir = ./

# the file containing the CA certificate. Mandatory
certificate = ./ca.crt

# the file contaning the CA private key. Mandatory
private_key = ./ca.key

# the message digest algorithm. Remember to not use MD5
default_md = sha256

# for how many days will the signed certificate be valid
default_days = 365

# a section with a set of variables corresponding to DN fields
policy = my_policy

# MOST IMPORTANT PART OF THIS CONFIG
copy_extensions = copy

[ my_policy ]
# if the value is "match" then the field value must match the same field in the
# CA certificate. If the value is "supplied" then it must be present.
# Optional means it may be present. Any fields not mentioned are silently
# deleted.
countryName = match
stateOrProvinceName = supplied
organizationName = supplied
commonName = supplied
organizationalUnitName = optional
commonName = supplied

ルートによって子証明書に署名するために、なぜもう1つの構成を作成する必要があるのか​​、と質問されるかもしれません。子証明書にはSANブロック(サブジェクトの別名)が必要なので、答えは簡単です。「openssl x509」ユーティリティで子証明書に署名すると、ルート証明書は子証明書のSANフィールドを削除します。したがって、SANフィールドの削除を回避するために、「openssl x509」の代わりに「openssl ca」を使用します。新しい設定ファイルを作成し、すべての拡張フィールドcopy_extensions = copyをコピーするように指示します

openssl ca -config config_ca.cnf -out market.crt -in market.csr

プログラムは2つの質問をします:1.証明書に署名しますか?「Y」と発声します。2。1件の証明書リクエストのうち1件が認定され、コミットしますか?「Y」と言います

ターミナルでは、「データベース」という単語の付いた文を見ることができます。これは、「touch」コマンドで作成したファイルindex.txtを意味します。「openssl ca」ユーティリティで作成したすべての証明書のすべての情報が含まれます。証明書が有効であることを確認するには:

openssl rsa -in market.key -check

CRTの内部を見たい場合:

openssl x509 -in market.crt -text -noout

CSRの内部を確認したい場合:

openssl req -in market.csr -noout -text 

2
このプロセスは複雑に見えますが、このドメインは.devドメインに必要なものです。このドメインは自己署名証明書をサポートしておらず、ChromeとFirefoxはHSTSを強制しているためです。私が行ったのは、CAを作成し、証明書を作成し、それを私のCAで署名し、最後にブラウザーで私のCAを信頼するという、次の手順に従います。ありがとう。
bajicdusko

1
あなたは、すごい伝説です。私のホームラボはありがとう!
antyawn

6

一般的な手順は正しいです。コマンドの構文は次のとおりです。

openssl req -new -key {private key file} -out {output file}

ただし、ブラウザは既知の認証局(CA)で証明書を検証して身元を確認できなかったため、警告が表示されます。

これは自己署名証明書であるため、CAはなく、警告を無視して続行できます。公衆インターネット上の誰もが認識できる実際の証明書を取得したい場合、手順は以下のとおりです。

  1. 秘密鍵を生成する
  2. その秘密鍵を使用してCSRファイルを作成します
  3. CSRをCAに提出する(Verisignなど)
  4. CAから受け取った証明書をWebサーバーにインストールする
  5. 証明書のタイプに応じて、他の証明書を認証チェーンに追加します

詳細については、接続の保護:OpenSSLを使用したセキュリティ証明書の作成の投稿を参照してください。


6

ワンライナーFTW。シンプルに保つのが好きです。必要なすべての引数を含む1つのコマンドを使用しないのはなぜですか?これは私の好みです-これはx509証明書とそのPEMキーを作成します:

openssl req -x509 \
 -nodes -days 365 -newkey rsa:4096 \
 -keyout self.key.pem \
 -out self-x509.crt \
 -subj "/C=US/ST=WA/L=Seattle/CN=example.com/emailAddress=someEmail@gmail.com"

この単一のコマンドには、証明書の詳細に対して通常提供するすべての回答が含まれています。このようにして、パラメーターを設定してコマンドを実行し、出力を取得して、コーヒーを飲みます。

>>詳細はこちら<<


1
SANを除くすべての議論... @vogの答えはそれもカバーしています(そしてこれよりも前にあります)(ただし、これにはより完全な「Subject」フィールドが入力されています...)(1年間の有効期限の大ファンでもありません)
ゲルトファンデ

6

ワンライナーバージョン2017:

CentOS:

openssl req -x509 -nodes -sha256 -newkey rsa:2048 \
-keyout localhost.key -out localhost.crt \
-days 3650 \
-subj "CN=localhost" \
-reqexts SAN -extensions SAN \
-config <(cat /etc/pki/tls/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=IP:127.0.0.1,DNS:localhost"))

Ubuntu:

openssl req -x509 -nodes -sha256 -newkey rsa:2048 \
-keyout localhost.key -out localhost.crt \
-days 3650 \
-subj "/CN=localhost" \
-reqexts SAN -extensions SAN \
-config <(cat /etc/ssl/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=IP:127.0.0.1,DNS:localhost"))

編集:Ubuntuの 'subj'オプションにスラッシュを追加。


3

キーを生成する

が含まれている/etc/mysqlため、証明書の保存に使用してい/etc/apparmor.d/usr.sbin.mysqldます/etc/mysql/*.pem r

sudo su -
cd /etc/mysql
openssl genrsa -out ca-key.pem 2048;
openssl req -new -x509 -nodes -days 1000 -key ca-key.pem -out ca-cert.pem;
openssl req -newkey rsa:2048 -days 1000 -nodes -keyout server-key.pem -out server-req.pem;
openssl x509 -req -in server-req.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem;
openssl req -newkey rsa:2048 -days 1000 -nodes -keyout client-key.pem -out client-req.pem;
openssl x509 -req -in client-req.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem;

構成を追加

/etc/mysql/my.cnf

[client]
ssl-ca=/etc/mysql/ca-cert.pem
ssl-cert=/etc/mysql/client-cert.pem
ssl-key=/etc/mysql/client-key.pem

[mysqld]
ssl-ca=/etc/mysql/ca-cert.pem
ssl-cert=/etc/mysql/server-cert.pem
ssl-key=/etc/mysql/server-key.pem

私のセットアップでは、Ubuntuサーバーが次のログに記録しました: /var/log/mysql/error.log

フォローアップノート:

  • SSL error: Unable to get certificate from '...'

    MySQLがapparmors構成にない場合、証明書ファイルへの読み取りアクセスが拒否される可能性があります。前のステップで述べたように、デフォルトでapparmorによって承認されて.pemいる/etc/mysql/ディレクトリにすべての証明書をファイルとして保存します(またはapparmor / SELinuxを変更して、保存した場所にアクセスできるようにします)。

  • SSL error: Unable to get private key

    MySQLサーバーのバージョンがデフォルトのrsa:2048フォーマットをサポートしていない可能性があります

    生成さrsa:2048れたプレーンに変換rsa

    openssl rsa -in server-key.pem -out server-key.pem
    openssl rsa -in client-key.pem -out client-key.pem
    
  • ローカルサーバーがSSLをサポートしているかどうかを確認します

    mysql -u root -p
    mysql> show variables like "%ssl%";
    +---------------+----------------------------+
    | Variable_name | Value                      |
    +---------------+----------------------------+
    | have_openssl  | YES                        |
    | have_ssl      | YES                        |
    | ssl_ca        | /etc/mysql/ca-cert.pem     |
    | ssl_capath    |                            |
    | ssl_cert      | /etc/mysql/server-cert.pem |
    | ssl_cipher    |                            |
    | ssl_key       | /etc/mysql/server-key.pem  |
    +---------------+----------------------------+
    
  • データベースへの接続がSSL暗号化されていることの確認

    接続を確認しています

    MySQLインスタンスにログインしたら、クエリを発行できます。

    show status like 'Ssl_cipher';
    

    接続が暗号化されていない場合、結果は空白になります。

    mysql> show status like 'Ssl_cipher';
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | Ssl_cipher    |       |
    +---------------+-------+
    1 row in set (0.00 sec)
    

    それ以外の場合は、使用中の暗号にゼロ以外の長さの文字列が表示されます。

    mysql> show status like 'Ssl_cipher';
    +---------------+--------------------+
    | Variable_name | Value              |
    +---------------+--------------------+
    | Ssl_cipher    | DHE-RSA-AES256-SHA |
    +---------------+--------------------+
    1 row in set (0.00 sec)
    
  • 特定のユーザーの接続にsslを要求する( 'require ssl'):

    • SSL

    アカウントにSSL暗号化接続のみを許可するようサーバーに指示します。

    GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
      REQUIRE SSL;
    

    接続するには、クライアントは--ssl-caオプションを指定してサーバー証明書を認証する必要があり、さらに--ssl-keyおよび--ssl-certオプションを指定することもできます。--ssl-caオプションも--ssl-capathオプションも指定されていない場合、クライアントはサーバー証明書を認証しません。


代替リンク:SSLを使用したMySQLへのセキュアなPHP接続の長いチュートリアル。


-1; これは、主に尋ねられた質問に接するものであり、引用がどこから来ているのかを明らかにするという悪い仕事をします。
マークアメリー

これは、プロビジョニングCA、CAによって署名されたサーバー/クライアント証明書を示し、apparmorのあるホストでmysqldがそれらを読み取るように構成します。これは、ca、サーバー、クライアントを同じマシンでホストし、mysqldプロセスにそのcaの権限を危険にさらすという、あまり役に立たないケースの例です。この設定は、テスト環境でssl構成をテストする以外に意味がありません。内部CAを運用するには、openssl help.ubuntu.com/community/GnuTLSではなくgnuttlsツールチェーンを使用し、mysqls + apparmorのケースを回避する前にtlsを十分に理解することをお勧めします
ThorSummoner

3

詳細に説明したように、自己署名証明書 はインターネットに対して信頼されていません自己署名証明書を多くのブラウザに追加できますが、すべてのブラウザに追加できるわけではありません。または、独自の認証局になることもできます

証明機関から署名付き証明書を取得したくない主な理由はコストです。シマンテックは、証明書に対して年間995〜1,999ドルを請求します。内部ネットワーク向けの証明書の場合、シマンテックは年間399ドルを請求します。クレジットカードでの支払いを処理している場合や、収益性の高い会社の利益センターで働いている場合、そのコストは簡単に正当化できます。インターネット上で作成している個人的なプロジェクト、または最小限の予算で運営されている非営利プロジェクト、または組織のコストセンターで働いている場合、コストセンターは常により多くのことを試みます。少ないと。

代替は、使用することですcertbotを(参照certbotについて)。Certbotは、WebサーバーのSSL / TLS証明書をフェッチして展開する、使いやすい自動クライアントです。

certbotを設定すると、Let's Encrypt認証局によって発行された証明書を作成して維持できるようになります。

私は週末に私の組織のためにこれを行いました。サーバー(Ubuntu 16.04)にcertbotに必要なパッケージをインストールし、certbotをセットアップして有効にするために必要なコマンドを実行しました。certbotのDNSプラグインが必要になる可能性があります -現在DigitalOceanを使用していますが、間もなく別のサービスに移行する可能性があります。

指示のいくつかは完全に正しくなく、Googleで理解するのに少し突っ込んで時間をかけたことに注意してください。最初はかなりの時間がかかりましたが、今では数分でできると思います。

DigitalOceanの場合、DigitalOcean資格情報のINIファイルへのパスを入力するように求められたとき、私が苦労した領域の1つがありました。スクリプトが参照しているのは、[ アプリケーションとAPI]ページとそのページの[トークン/キー]タブです。DigitalOceanのAPIの個人用アクセストークン(読み取りと書き込み)を持っているか生成する必要があります。これは65文字の16進数文字列です。次に、この文字列を、certbotを実行しているWebサーバー上のファイルに配置する必要があります。そのファイルには、最初の行にコメントを含めることができます(コメントは#で始まります)。seccond行は次のとおりです。

dns_digitalocean_token = 0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff

DigitalOceanのAPIの読み取り+書き込みトークンを設定する方法を見つけたら、certbotを使用してワイルドカード証明書を設定するのは非常に簡単でした。ワイルドカード証明書を設定する必要はないことに注意してください。代わりに、証明書を適用したい各ドメインとサブドメインを指定できます。DigitalOceanからの個人アクセストークンを含む資格情報INIファイルを必要としたのは、ワイルドカード証明書でした。

公開鍵証明書(ID証明書またはSSL証明書とも呼ばれます)は有効期限が切れており、更新が必要です。したがって、証明書を定期的(繰り返し)に更新する必要があります。certbotのドキュメントでは、証明書の更新について説明しています

私の計画は、opensslコマンドを使用して証明書の有効期限を取得し、有効期限が切れるまで30日以内に更新をトリガーするスクリプトを作成することです。次に、このスクリプトをcronに追加して、1日に1回実行します。

証明書の有効期限を読み取るコマンドは次のとおりです。

root@prod-host:~# /usr/bin/openssl x509 -enddate -noout -in path-to-certificate-pem-file
notAfter=May 25 19:24:12 2019 GMT
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.