web-dev-qa-db-ja.com

クライアント証明書の検証を理解するのに役立ちます

特定のコンピュータのみがアクセスできるAPIを作成しています。通信は、サーバーとクライアント間のSSLを介して行われます。クライアントがアクセスできることを確認するために、サーバーによって署名された各クライアントの証明書を作成したいと思います。サーバーによって署名された証明書を提供しないクライアントは、アクセスを拒否する必要があります。

GoDaddyからのSSL証明書とキーを持っています。この情報を使用してクライアント証明書を作成できるはずだと思いましたが、どこを見ても、特定のサーバーの証明書/キーではなく、クライアント証明書に署名するために(GoDaddyからの)CA証明書が必要なようです。

GoDaddyに行ってすべてのクライアントの新しい証明書を取得する必要があるのは奇妙に思えるため、これは私には意味がありません。これは事実ではなく、何か間違ったことをしている、または完全に理解していないと思います。

だから-どのようにしてサーバー証明書/パスワードで署名されたクライアント証明書を作成できますか?

サーバー証明書からクライアント証明書を生成するコマンド(opensslを使用しています)を提供できれば、それも非常にありがたいです。

ありがとう!

20
zsalzbank

クライアント証明書に署名するには、管理するCA証明書が必要です。グローバルに信頼されたCA証明書は、インターネットの他の部分にとってセキュリティ上の危険性があるため、ほとんどの場合、支払いは問題外です。したがって、これらのケースでは、独自のCAを作成し、独自のサーバーとクライアントの証明書を作成する必要があります。

それでは、これらすべての証明書の生成に使用する基本的なopenssl.confファイルから始めましょう。

[ ca ]
default_ca  = CA_default                # The default ca section

[ CA_default ]
certs          = certs                  # Where the issued certs are kept
crl_dir        = crl                    # Where the issued crl are kept
database       = database.txt           # database index file.
new_certs_dir  = certs                  # default place for new certs.
certificate    = cacert.pem             # The CA certificate
serial         = serial.txt             # The current serial number
crl            = crl.pem                # The current CRL
private_key    = private\cakey.pem      # The private key
RANDFILE       = private\private.rnd    # private random number file

x509_extensions  = v3_usr               # The extentions to add to the cert
default_days     = 365
default_crl_days = 30                   # how long before next CRL
default_md       = sha256               # which md to use.
preserve         = no                   # keep passed DN ordering
policy           = policy_match
email_in_dn      = 

[ policy_match ]
commonName      = supplied

[ req ]
default_bits        = 2048
default_keyfile     = privkey.pem
distinguished_name  = req_distinguished_name
x509_extensions     = v3_ca

[ v3_ca ]
basicConstraints     = CA:TRUE
subjectKeyIdentifier = hash

[ v3_usr ]
basicConstraints     = CA:FALSE
subjectKeyIdentifier = hash

[ server ]
basicConstraints       = CA:FALSE
nsCertType             = server
nsComment              = "Server Certificate"
subjectKeyIdentifier   = hash
authorityKeyIdentifier = keyid,issuer:always
extendedKeyUsage       = serverAuth
keyUsage               = digitalSignature, keyEncipherment

[ client ]
basicConstraints       = CA:FALSE
nsCertType             = client
nsComment              = "Client Certificate"
subjectKeyIdentifier   = hash
authorityKeyIdentifier = keyid,issuer:always
extendedKeyUsage       = clientAuth
keyUsage               = digitalSignature

[ req_distinguished_name ]

この構成ファイルは、バッチスクリプトから証明書を自動生成するために作成されます。さらに制御または命名オプションが必要な場合は、状況に合わせて調整する必要があります。

したがって、CAを生成するには、CAを作成するディレクトリに移動し、openssl.confをそこに配置して、次のようにします。

PASSWORD="PUT_YOUR_CA_PASSWORD_HERE"

# Make the config CA specific
cat openssl.conf > use.conf
echo "CN=PUT_CA_NAME_HERE" >> use.conf

# Create the necessary files
mkdir keys requests certs 
touch database.txt
echo 01 > serial.txt

# Generate your CA key (Use appropriate bit size here for your situation)
openssl genrsa -aes256 -out keys/ca.key -passout pass:$PASSWORD 2048

# Generate your CA req
openssl req -config use.conf -new -key keys/ca.key -out requests/ca.req -passin pass:$PASSWORD

# Make your self-signed CA certificate
openssl ca  -config use.conf -selfsign -keyfile keys/ca.key -out certs/ca.crt -in requests/ca.req -extensions v3_ca -passin pass:$PASSWORD -batch

# Cleanup
rm requests/ca.req use.conf

次にserver証明書を生成します(例:Webサーバー用):

PASSWORD="PUT_YOUR_CA_PASSWORD_HERE"
NAME="PUT_THE_NAME_OF_SERVER_TO_GENERATE_HERE"

# Make the config Server specific
cat openssl.conf > use.conf
echo "CN=$NAME" >> use.conf

openssl req -new -nodes -extensions server -out "requests/$NAME.req" -keyout "$NAME.key" -config use.conf -passin pass:$PASSWORD )
openssl ca -batch -extensions server -keyfile keys/ca.key -cert certs/ca.crt -config use.conf -out "certs/$NAME.crt" -passin pass:$PASSWORD -infiles "requests/$NAME.req"

# Cleanup
rm "requests/$NAME.req" use.conf

client証明書を生成するには:

PASSWORD="PUT_YOUR_CA_PASSWORD_HERE"
NAME="PUT_THE_NAME_OF_CLIENT_TO_GENERATE_HERE"

# Make the config Client specific
cat openssl.conf > use.conf
echo "CN=$NAME" >> use.conf

openssl req -new -nodes -extensions client -out "requests/$NAME.req" -keyout "$NAME.key" -config use.conf -passin pass:$PASSWORD )
openssl ca -batch -extensions client -keyfile keys/ca.key -cert certs/ca.crt -config use.conf -out "certs/$NAME.crt" -passin pass:$PASSWORD -infiles "requests/$NAME.req"

# Cleanup
rm "requests/$NAME.req" use.conf

クライアントとサーバーの鍵と証明書の生成の唯一の違いは、盗まれたクライアント証明書を使用してサーバーを再生し、他のクライアントをだましてそれに接続することもできます(これは、アプリケーションがクライアントをサポートしている場合にのみ機能します)証明書のサーバーエクステンション)。

19
Paul

認証局は、証明書を発行するエンティティです。 (クライアントに)証明書を発行するため、CAになりたい。

証明書の検証を試みる人は、CAキーを信頼する必要があります(つまり、[アプリオリ信頼:ソフトウェアまたはオペレーティングシステムでCA公開キーがハードコーディングされていると考えてください)。この場合、サーバーで証明書を検証する必要があるため、サーバーはCA公開鍵のコピーを保持する必要があります。

GoDaddyのような既存のCAは、公開鍵のコピーをすべてのWebブラウザーに取得することに成功しました-そのCAはeverybodyによって信頼されています。それを達成するために、彼らはブラウザーベンダー(Microsoftなど)に信頼でき、真剣であることを証明する必要がありました(秘密キーはバンカーにあり、すべての手順があり、運用の継続性を確保するための十分な財務バックアップがあります...)そしてそれは高価でした、それが彼らがあなたに無料で(または安いものでさえ)サブCAパワーを与えない理由です。ただし、この状況では、CAキーが全世界で知られているかどうかは気にしません。必要なのは、サーバー(完全に制御する)が信頼するCAだけです。自分で管理するCAは問題ありません。

[〜#〜] ejbca [〜#〜] は、使いやすい無料のオープンソースCA実装です。または、 OpenSSL の周りにいくつかのスクリプトを一緒に投げることもできます。

注:証明書はauthentication用であり、authorization用ではありません。ユーザーを識別するためのものです。サーバーで2つの役割を分離することをお勧めします。

  • 証明書をクライアントXに発行するときは、証明書に「X」という名前を付けます。
  • "許可され​​たクライアント"(名前順)のテーブルをサーバー上に保持します。
  • クライアントが接続したら、証明書を検証してから、証明書からクライアント名を抽出し、許可されたクライアントのテーブルで名前を確認します。

この分離は、特定のクライアントのアクセス権を取り消したい日に非常に役立ちます。

10
Thomas Pornin

私の知る限り、GoDaddyから購入したSSLを使用して有効なクライアント証明書を作成することはできません。その背後にある理由は、GoDaddyからのCA証明書の秘密鍵に関係しているため、正当な理由で公開されません。

ここで、すべてのコンピュータを管理下に置くことが最も簡単で安価な場合は、独自のCA証明書を生成してクライアントに署名することになります。個々のコンピューターのそれぞれの信頼されたルートストアにCAを追加します。

CAを取得して、CAになることを許可する証明書に署名することができますが、これらの証明書は、「見積もりを依頼する」のように安くはありません。

私が信じるツールが必要なら [〜#〜] xca [〜#〜] はあなたのためのGUIです。

1
Travis Pessetto