OpenSSL CA および非 CA 証明書

OpenSSL CA および非 CA 証明書

自己署名 CA 証明書を生成し、中間 CA 証明書を生成することができます。

ここで、他の証明書に署名できないエンドユーザー証明書を生成しようとしました。そこで、を開いて行openssl.cnfを変更し、中間 CA を使用してを生成し、署名しました。v3_reqbasicConstraints=CA:FALSE.csr-extensions v3_req

次に、別のものに署名しようとした.csrところ、不思議なことに署名できました。試してみると、検証は正常でした。

まったく混乱していて、何をしたらよいかわかりません。何が間違っているのか、何か考えはありますか? これらは私が使用したコマンドです。

$ openssl req -x509 -extensions v3_ca -newkey rsa:2048 \
   -keyout root_ca.key -out root_ca.crt -days 365 \
   -subj /C=US/ST=abc/L=abc/O=test/OU=mine/CN=CA/[email protected] \
   -passout pass:123456

$ openssl req -new -extensions v3_ca -newkey rsa:2048 \
   -keyout s1.key -out s1.csr -days 365 \
   -subj /C=US/ST=abc/L=abc/O=test/OU=mine/CN=s1/[email protected] \
   -passout pass:123456

$ openssl ca -policy policy_anything -outdir ./ -out s1.crt \
   -cert root_ca.crt -infiles s1.csr -CAkey root_ca.key

$ openssl req -new -extensions v3_req -newkey rsa:2048 \
   -keyout client.key -out client.csr -days 365 \
   -subj /C=US/ST=abc/L=abc/O=test/OU=mine/CN=s1/[email protected] \
   -passout pass:123456

$ openssl ca -policy policy_match -outdir ./ -out client.crt -cert s1.crt \
   -infiles client.csr -CAkey s1.key

 $ openssl req -new -extensions v3_req -newkey rsa:2048 \
   -keyout client2.key -out client2.csr -days 365 \
   -subj /C=US/ST=abc/L=abc/O=test/OU=mine/CN=s1/[email protected] \
   -passout pass:123456

 $ openssl ca -policy policy_match -outdir ./ -out client2.crt \
   -cert client.crt -infiles client2.csr -CAkey client.key

 $ cat root_ca.crt s1.crt client.crt > ca.pem

 $ openssl verify -CAfile ca.pem client2.crt

これは設定ファイルです:

HOME = .
RANDFILE = $ENV::HOME/.rnd
oid_section = new_oids
[ new_oids ]
[ ca ]
default_ca = CA_default
[ CA_default ]
dir = /root/new
certs = $dir/certs
crl_dir = $dir/crl
database = $dir/index.txt
new_certs_dir = $dir/newcerts
certificate = $dir/root_ca.crt 
serial = $dir/serial 
crlnumber = /root/index.txt
crl = $dir/crl.pem 
private_key = $dir/root_ca.key 
RANDFILE = $dir/private/.rand
x509_extensions = usr_cert
name_opt = ca_default
cert_opt = ca_default
default_days = 365
default_crl_days = 30
default_md = sha1
preserve = no
policy = policy_match
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req ]
default_bits = 1024
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
attributes = req_attributes
x509_extensions = v3_ca
string_mask = nombstr
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = AU
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Some-State
localityName = Locality Name (eg, city)
0.organizationName = Organization Name (eg, company)
0.organizationName_default = Internet Widgits Pty Ltd
organizationalUnitName = Organizational Unit Name (eg, section)
commonName = Common Name (eg, YOUR name)
commonName_max = 64
emailAddress = Email Address
emailAddress_max = 64
[ req_attributes ]
challengePassword = A challenge password
challengePassword_min = 4
challengePassword_max = 20
unstructuredName = An optional company name
[ usr_cert ]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, nonRepudiation,keyEncipherment, dataEncipherment, keyAgreement
nsComment = "OpenSSL Generated Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
[ v3_req ]
basicConstraints = critical,CA:false
keyUsage = nonRepudiation
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer:always
[ v3_ca ]
subjectKeyIdentifier = hash
extendedKeyUsage = critical,serverAuth, clientAuth
basicConstraints = CA:true
keyUsage = cRLSign, keyCertSign, digitalSignature, nonRepudiation,keyEncipherment, dataEncipherment, keyAgreement, keyCertSign, cRLSign
[ crl_ext ]
authorityKeyIdentifier = keyid:always,issuer:always
[ proxy_cert_ext ]
basicConstraints = CA:FALSE
nsComment = "OpenSSL Generated Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
proxyCertInfo = critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo

答え1

を試してみましたかbasicConstraints=critical,CA:false?

PS: 'ca' ユーティリティは現在、署名に使用する CA 証明書の有効性をチェックしません。そのため、無効な CA を使用して署名しても問題ありませんが、検証ルーチンによって拒否されます。

以下は少し冗長ですが、機能するはずです。自分の設定で試してみて、問題があれば報告していただけますか?

#!/bin/sh
#SSLEAY_CONFIG="-config yourfile.cnf"
ROOTCA_SUBJ="-subj /C=US/ST=abc/L=abc/O=test/OU=mine/CN=RootCA/[email protected]"
CA_SUBJ="-subj /C=US/ST=abc/L=abc/O=test/OU=mine/CN=CA/[email protected]"
CERT_SUBJ="-subj /C=US/ST=abc/L=abc/O=test/OU=mine/CN=cert/[email protected]"
ROOTCA_PASS="pass:test"
CA_PASS="pass:test"
CERT_PASS="pass:test"
DIR="demoCA"
mkdir "$DIR" "$DIR"/certs "$DIR"/crl "$DIR"/newcerts "$DIR"/private
touch "$DIR"/index.txt
echo 01 > "$DIR"/crlnumber

# create Root CA
mkdir rootCA rootCA/certs rootCA/crl rootCA/newcerts rootCA/private
openssl req $SSLEAY_CONFIG -new -keyout rootCA/private/rootCAkey.pem -out rootCA/rootCAreq.pem $ROOTCA_SUBJ -passout "$ROOTCA_PASS"
openssl ca $SSLEAY_CONFIG -create_serial -out rootCA/rootCAcert.pem -days 1095 -batch -keyfile rootCA/private/rootCAkey.pem -passin "$ROOTCA_PASS" -selfsign -extensions v3_ca -infiles rootCA/rootCAreq.pem

# create Intermediate CA
mkdir CA CA/certs CA/crl CA/newcerts CA/private
openssl req $SSLEAY_CONFIG -new -keyout CA/private/CAkey.pem -out CA/CAreq.pem -days 365 $CA_SUBJ -passout "$CA_PASS"
openssl ca $SSLEAY_CONFIG -cert rootCA/rootCAcert.pem -keyfile rootCA/private/rootCAkey.pem -passin "$ROOTCA_PASS" -policy policy_anything -out CA/CAcert.pem -extensions v3_ca -infiles CA/CAreq.pem

# create Final Cert
mkdir cert cert/private
openssl req $SSLEAY_CONFIG -new -keyout cert/private/certkey.pem -out cert/certreq.pem -days 365 $CERT_SUBJ -passout "$CERT_PASS"
openssl ca $SSLEAY_CONFIG -cert CA/CAcert.pem -keyfile CA/private/CAkey.pem -passin "$CA_PASS" -policy policy_anything -out cert/cert.pem -infiles cert/certreq.pem
cat rootCA/rootCAcert.pem CA/CAcert.pem > myCA.pem
openssl verify -CAfile myCA.pem cert/cert.pem

を実行するとopenssl verify-CAfile信頼を意味しますこれ証明書。したがって、-CAfileルート CA とオプションで中間 CA のみを含める必要があります。そうでない場合は、常に が返されますOK。その他の証明書は、オプションを使用して追加する必要があります-untrusted

cert2.pemしたがって、署名入りの証明書を渡すと、最後の cert.pem証明書を取得すると、次の特典が得られます:

$ cat CA/CAcert.pem cert/cert.pem > notrust.pem
$ openssl verify -CAfile myCA.pem -untrusted notrust.pem cert2/cert2.pem
    cert2/cert2.pem: C = US, ST = abc, L = abc, O = test, OU = mine, CN = cert, emailAddress = [email protected]
    error 24 at 1 depth lookup:invalid CA certificate

答え2

前述のように、CA ユーティリティは、CA 証明書でなくても、任意の証明書を使用してリクエストに署名します。どうやら、一部の古いブラウザ (少なくとも Firefox バージョン 33 より前) では、このようなチェーンも受け入れられるようです。

証明書にビットがisCA設定されているかどうかを確認するには、次のコマンドを実行します。

openssl x509 -text -noout -in your_cert_file.crt

出力で、次の内容を探します。

X509v3 Basic Constraints: 
    CA:TRUE

これは CA 証明書です。非 CA 証明書には拡張機能がありますCA:FALSE(または拡張機能がまったくありません)。

注意: これらの拡張機能をリクエストに含める必要があり、リクエストに署名するときに CA がそれらを上書きしないようにする必要があります。

関連情報