OpenSSL ECDSAでの自己認証局作成

#はじめに
自己認証局を自身で作成することで、電子署名の仕組みをおさらいする。
IoTで注目されているECDSA形式での自己認証局の作成を目指す。

#環境
CentOS7 3.10.0-957.5.1.el7.x86_64
OpenSSL 1.0.2k-fips  26 Jan 2017

#自己認証局の作成
まず、ECDSAのどのカーブを選択するか決定。

```
openssl ecparam -list_curves
  secp256k1 : SECG curve over a 256 bit prime field
  secp384r1 : NIST/SECG curve over a 384 bit prime field
  secp521r1 : NIST/SECG curve over a 521 bit prime field
  prime256v1: X9.62/SECG curve over a 256 bit prime field
```
今回は、prime256v1を選択。

以下のようにディレクトリを整える。

```
mkdir /etc/pki/AWS
cd /etc/pki/AWS
mkdir certs
mkdir private
mkdir crl
mkdir newcerts
mkdir revoke

chmod 700 private
echo "01" > serial

touch index.txt

```
以下のようなディレクトリ構造となる。

```
/etc/pki/AWS
|--certs
|--crl
|--index.txt
|--newcerts
|--private
|--revoke
|--serial
```

openssl.cnfをコピーしてカスタマイズをかける。

```
cp /etc/pki/tls/openssl.cnf /etc/pki/AWS/

cd /etc/pki/AWS
cp openssl.cnf openssl-aws.cnf
vi openssl-aws.cnf

```

openssl-aws.cnfを下記のようにカスタマイズ。変更点のみ。


```
[ CA_default ]

dir             = /etc/pki/AWS          # Where everything is kept
...
default_days    = 3650                  # how long to certify for
default_crl_days= 365                    # how long before next CRL

[ req ]
string_mask = nombstr

[ req_distinguished_name ]
countryName                     = Country Name (2 letter code)
countryName_default             = JP
countryName_min                 = 2
countryName_max                 = 2

stateOrProvinceName             = State or Province Name (full name)
stateOrProvinceName_default     = Tokyo

localityName                    = Locality Name (eg, city)
localityName_default            = <任意>

0.organizationName              = Organization Name (eg, company)
0.organizationName_default      = <任意>

[ svr_cert ]

# These extensions are added when 'ca' signs a request.

# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.

basicConstraints=CA:FALSE

# Here are some examples of the usage of nsCertType. If it is omitted
# the certificate can be used for anything *except* object signing.

# This is OK for an SSL server.
nsCertType                      = server

# This is typical in keyUsage for a client certificate.
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth

# This will be displayed in Netscape's comment listbox.
nsComment                       = "OpenSSL Generated Certificate"

# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer

# This stuff is for subjectAltName and issuerAltname.
# Import the email address.
# subjectAltName=email:copy
# An alternative to produce certificates that aren't
# deprecated according to PKIX.
subjectAltName= @alt_names

#CRL,OCSPを利用する場合
crlDistributionPoints = URI:http://example.com/revoke.crl
authorityInfoAccess = OCSP;URI:http://example.com

[ alt_names ]
#SAN対策
DNS.1 = example.com
DNS.2 = *.example.com

[ usr_cert ]
extendedKeyUsage = clientAuth, emailProtection
nsComment                       = "OpenSSL Generated Certificate"
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid, issuer

#CRL,OCSPを利用する場合
crlDistributionPoints = URI:http://example.com/revoke.crl
authorityInfoAccess = OCSP;URI:http://example.com

#OCSP用
[ ocsp ]
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, digitalSignature, keyEncipherment, nonRepudiation
extendedKeyUsage = critical, OCSPSigning

[ v3_ca ]
# Key usage: this is typical for a CA certificate. However since it will
# prevent it being used as an test self-signed certificate it is best
# left out by default.
keyUsage = digitalSignature, cRLSign, keyCertSign


[ ICA ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always, issuer
basicConstraints = CA:TRUE, pathlen:0
keyUsage = digitalSignature, cRLSign, keyCertSign

```

CA秘密鍵を作成

```
openssl ecparam -genkey -name prime256v1 -out private/cakey.pem
```

CA秘密鍵からCA証明書を作成

```
openssl req -new -x509 -key private/cakey.pem -sha256 -days 3650 -config openssl-aws.cnf -extensions v3_ca -out cacert.pem
```

中間認証局証明書の秘密鍵とCSRを作成

```
openssl req -new -newkey ec:<(openssl ecparam -name prime256v1) -keyout private/icacert.key -sha256 -config openssl-aws.cnf -out icacert.csr
```

中間認証局証明書のCSRをCAで署名

```
openssl ca -in icacert.csr -out icacert.pem -days 3650 -md sha256 -extensions ICA -config openssl-aws.cnf
```