1700

組み込み 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 でいくつかのエラーが発生します。

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

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

4

19 に答える 19

2729

1つのコマンドでそれを行うことができます:

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

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

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

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

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

于 2012-04-16T15:04:51.010 に答える
626

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

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

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

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

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

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


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

これは、ブラウザが事前定義されたトラスト アンカーのリストを使用してサーバー証明書を検証するためです。自己署名証明書はトラステッド アンカーに連鎖しません。

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

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

ステップ 1 -独自の機関CA: trueを作成する とは、適切なキーの使用法を使用して自己署名証明書を作成することを意味します。つまり、SubjectIssuerは同じエンティティであり、CA はBasic Constraintsで true に設定され(クリティカルとしてもマークする必要があります)、キーの使用法はkeyCertSignand crlSign(CRL を使用している場合) であり、Subject Key Identifier (SKI) はAuthority Key Identifier (AKI)と同じです。

独自の認証局になるには、「認証局で証明書署名要求に署名するにはどうすればよいですか?」を参照してください。スタック オーバーフローで。次に、ブラウザが使用する Trust Store に CA をインポートします。

手順 2 ~ 4 は、 StartcomCAcertなどの CA のサービスを登録するときに、公開サーバーに対して現在行うこととほぼ同じです。ステップ 1 と 5 により、第三者の権限を回避し、自分自身の権限として行動することができます (自分以上に信頼できる人はいますか?)。

ブラウザの警告を回避する次善の方法は、サーバーの証明書を信頼することです。ただし、Android の既定のブラウザーなど、一部のブラウザーではそれができません。したがって、プラットフォームでは決して機能しません。

ブラウザー (および他の同様のユーザー エージェント)が自己署名証明書を信頼しないという問題は、モノのインターネット (IoT) で大きな問題になるでしょう。たとえば、サーモスタットや冷蔵庫に接続してプログラムするとどうなるでしょうか? 答えは、ユーザー エクスペリエンスに関する限り、良いことは何もないということです。

W3C の WebAppSec ワーキング グループは、この問題の調査を開始しています。たとえば、Proposal: Marking HTTP As Non-Secureを参照してください。


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

以下のコマンドと構成ファイルにより、自己署名証明書が作成されます (署名要求の作成方法も示されています)。自己署名証明書に使用される 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

DNS 名を CN ではなく SAN に配置することが重要です。これは、IETF と CA/Browser Forums の両方が慣例を指定しているためです。また、CN 内の DNS 名が非推奨であることも指定しています (ただし、禁止されているわけではありません)。DNS 名を CN に入れる場合は、CA/B ポリシーの下で SAN に含める必要があります。したがって、Subject Alternate Name の使用を避けることはできません。

DNS 名を SAN に配置しない場合、証明書は、CA/Browser Forum のガイドラインに従うブラウザーやその他のユーザー エージェントでの検証に失敗します。

関連: ブラウザーは CA/Browser Forum のポリシーに従います。IETF ポリシーではありません。これが、OpenSSL (一般に IETF に従う) で作成された証明書がブラウザー (ブラウザーは CA/B に従う) で検証されない場合がある理由の 1 つです。それらは異なる標準であり、異なる発行ポリシーと異なる検証要件があります。


自己署名証明書を作成します-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 アドレスを許可していません。

于 2015-01-13T21:12:18.497 に答える
441

@diegows の回答で説明されているオプションは次のとおりです。ドキュメントから、より詳細に説明されています。

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

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

-x509

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

-newkey arg

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

-keyout filename

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

-out filename

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

-days n

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

-nodes

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

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

于 2014-04-13T01:48:24.573 に答える
170

コメントできないので、これを別の回答にします。受け入れられたワンライナーの回答にいくつかの問題が見つかりました。

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

以下は、パスフレーズを削除し、セキュリティを強化して警告を抑制し、完全な質問リストを削除するために -subj を渡すようにコメントに提案を含む簡略化されたバージョンです。

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
于 2015-08-13T09:44:52.237 に答える
73

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

受け入れられた回答と同じコマンドライン - @diegows に -sha256 を追加

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

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

2018 年 5 月の更新。多くの人がコメントで指摘したように、SHA-2 を使用しても自己署名証明書にセキュリティは追加されません。しかし、古い/安全でない暗号化ハッシュ関数を使用しないための良い習慣として、これを使用することをお勧めします. 完全な説明は、Why is it fine for certificates above the end-entity certificate to be SHA-1 based? にあります。.

于 2014-10-20T09:52:10.360 に答える
7

openssl単一のコマンドで自己署名証明書を生成できます (-newkey 秘密鍵を生成するように-x509指示し、署名要求の代わりに自己署名証明書を発行するように指示します)::

openssl req -x509 -newkey rsa:4096 \
-keyout my.key -passout pass:123456 -out my.crt \
-days 365 \
-subj /CN=localhost/O=home/C=US/emailAddress=me@mail.internal \
-addext "subjectAltName = DNS:localhost,DNS:web.internal,email:me@mail.internal" \
-addext keyUsage=digitalSignature -addext extendedKeyUsage=serverAuth

秘密鍵を生成し、別の手順で自己署名証明書を作成できます::

openssl genrsa -out my.key -passout pass:123456 2048

openssl req -x509 \
-key my.key -passin pass:123456 -out my.csr \
-days 3650 \
-subj /CN=localhost/O=home/C=US/emailAddress=me@mail.internal \
-addext "subjectAltName = DNS:localhost,DNS:web.internal,email:me@mail.internal" \
-addext keyUsage=digitalSignature -addext extendedKeyUsage=serverAuth

結果の証明書を確認します::

openssl x509 -text -noout -in my.crt

Javakeytoolは PKCS#12 ストアを作成します::

keytool -genkeypair -keystore my.p12 -alias master \
-storetype pkcs12 -keyalg RSA -keysize 2048 -validity 3650 \
-storepass 123456 \
-dname "CN=localhost,O=home,C=US" \
-ext 'san=dns:localhost,dns:web.internal,email:me@mail.internal'

自己署名証明書をエクスポートするには::

keytool -exportcert -keystore my.p12 -file my.crt \
-alias master -rfc -storepass 123456

結果の証明書を確認します::

keytool -printcert -file my.crt

certtoolfrom GnuTLS では、CLI から異なる属性を渡すことはできません。私は設定ファイルをいじるのが好きではありません((

于 2020-11-07T22:36:39.290 に答える
6

キーを生成する

が含まれている/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 '...'

    証明書ファイルが apparmors 構成に含まれていない場合、MySQL は証明書ファイルへの読み取りアクセスを拒否される可能性があります。前の手順で述べたように^、すべての証明書を.pemファイルとして/etc/mysql/apparmor によってデフォルトで承認されているディレクトリに保存します (または、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 オプションも指定されていない場合、クライアントはサーバー証明書を認証しません。


別のリンク: Secure PHP Connections to MySQL with SSLの長いチュートリアル。

于 2015-10-08T21:36:12.357 に答える
6

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

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

ただし、既知の認証局 (CA) を使用して証明書を検証することによってブラウザーが ID を検証できなかったため、警告が表示されます。

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

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

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

于 2015-04-02T06:15:31.100 に答える
0

簡単な方法で、パスワードと証明書なしで 10 年間キーを生成します。

openssl req  -x509 -nodes -new  -keyout server.key -out server.crt -days 3650 -subj "/C=/ST=/L=/O=/OU=web/CN=www.server.com"
于 2021-12-27T13:35:30.253 に答える