AWS CloudHSMで秘密鍵のインポートとエクスポートしてみた

マネージドでハードウェアレベルの鍵の管理ができるぞ
2022.07.14

秘密鍵の管理どうしようかな

こんにちは、のんピ(@non____97)です。

皆さんは秘密鍵の管理をどうしようかなと思ったことはありますか? 私はあります。

IAM Roles Anywhereを使うにあたって秘密鍵の管理が重要になります。

...ということで、AWSの最強の鍵管理マネージドサービスであるAWS CloudHSMを使ってみようと思います。

CloudHSMのユースケースにも秘密鍵の管理が例として紹介されています。

** 発行認証局 (CA) 向けのプライベートキーの保護 ** 公開鍵基盤 (PKI) では、認証局 (CA) がデジタル認証を発行する信頼されたエンティティです。このようなデジタル認証は、個人または組織を識別するために使用されます。AWS CloudHSM を使用すると、プライベートキーを保存し、自社の認証を発行する発行 CA として安全に機能することができるよう、認証リクエストに署名することができます。

AWS CloudHSM(法令遵守のためのハードウェアベースキーストレージ)| AWS

今回は、実際にAWS公式ドキュメントに沿って秘密鍵をAWS CloudHSMにインポートとエクスポートしてみます。

CloudHSMの作成

クラスターの作成

まず、CloudHSMのクラスターを作成します。

CloudHSMのコンソールからクラスターの作成をクリックします。

クラスターの作成

VPCとサブネットを指定して、続行をクリックします。

クラスター設定

バックアップは保持期間は7日にして、続行をクリックします。

バックアップ保持

Nameタグを設定して確認をクリックします。

タグの設定

設定内容を確認してクラスターの作成をクリックします。

確認

クラスターの作成が開始すると状態がCreate in progressになります。

Create in progress

5分ほど待つとクラスターの状態がUninitializedになります。

Uninitialized

HSMの作成

次にHSMの作成をします。

作成したクラスターを選択してアクション-初期化をクリックします。

初期化

HSMのサブネットを選択して作成をクリックします。

クラスターでの HSM の作成

最初の HSM は、[クラスターID] で作成中ですとメッセージが表示されるので、10分弱待ちます。

最初の HSM は、cluster-ieh7u5cvyuq で作成中です

HSMの作成が完了するとCSRや各種証明書をダウンロードするように促されます。

証明書署名リクエストのダウンロード

移行の作業はEC2インスタンスから行います。

クラスターの初期化

クラスターの初期化を行います。

まず、Amazon Linux 2のEC2インスタンスからCSRをダウンロードします。各種証明書はクラスターの初期化に必要ありませんが勢いでダウンロードしました。

# クラスターの情報の確認
$ aws cloudhsmv2 describe-clusters --region us-east-1
{
    "Clusters": [
        {
            "CreateTimestamp": 1657686168.881,
            "HsmType": "hsm1.medium",
            "BackupPolicy": "DEFAULT",
            "SubnetMapping": {
                "us-east-1b": "subnet-0355def964cb72d89",
                "us-east-1a": "subnet-00b2246e7a23ec379"
            },
            "ClusterId": "cluster-ieh7u5cvyuq",
            "SecurityGroup": "sg-08ffee5d82ec89edf",
            "VpcId": "vpc-0e0796981cea634c1",
            "State": "UNINITIALIZED",
            "Hsms": [
                {
                    "StateMessage": "HSM created.",
                    "AvailabilityZone": "us-east-1a",
                    "EniId": "eni-00b552867cd5de7db",
                    "HsmId": "hsm-55zvxfeyecy",
                    "ClusterId": "cluster-ieh7u5cvyuq",
                    "EniIp": "172.31.40.54",
                    "State": "ACTIVE",
                    "SubnetId": "subnet-00b2246e7a23ec379"
                }
            ],
            "Certificates": {
                "ClusterCsr": "-----BEGIN CERTIFICATE REQUEST-----\nMIIC0DCCAbgCAQAwgYoxRDAJBgNVBAYTAlVTMAkGA1UECAwCQ0EwDQYDVQQKDAZD\nYXZpdW0wDQYDVQQLDAZOM0ZJUFMwDgYDVQQHDAdTYW5Kb3NlMUIwQAYDVQQDDDlI\nU006RTZFRTk5N0FFNkFFOTYyQjdGN0IxMTlENTNGRjk1OlBBUlROOjksIGZvciBG\nSVBTIG1vZGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCdXxLf4CzO\naTYCOzjLk9AK72E4doAJRtJRdkUEFF6cYML612zh9IrC9qYbBYbVtOxbv2b0Alr6\nyVq5A1xHYRE3la3Wnn6OMtJ308tka3xnc1gbZby5AmbsQ66P6F8gfF5YPuMgbWq7\n27rjHxXt9v3QnT9L4HN270Qd6HqL35DvlHOKrseCu51nkk0MKQkx8znt/2ve00wC\nCIJznKU5q29vXiVIInjy10SGRnxXt8RjymiLI+Etd8fqM7mZVbfwwqgBhwUOhcMi\nUt2MH6Dwyw4a5x+2SU5CoVmFSPT8FziECJOlH4rbHZmPGBhlp1SwL36Vfk4Auxx3\nivj2061IEL9pAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAnPn/SvpS53jL8ek9\nDwyBG02yEAhxaSJeY+50hg+C8mEa7ECBn7CnFukn8rD0M4Tem1klaOem3X/7r9w4\nvCzWN0DJ1MPnT/Qh+i/3Lc4y/0/GZPd5nJrNshBUVos5MvQ4DGPMdtTc8ncKKFFo\nfItB48+6lGyv+Q8mcZRcbbdbS5X10sOKY2wQ3aKFOP5uqaeEDV9LtyAYxTu+kK8I\n5bFpykJ00AzzLGkD1PESu4s8WmEp7YNmm6qKrj6rnR9Paz99nGg4lVWNZXGCZoSe\n2QHtwi9wtyri/Ha4CEY/xjFxNjL4M0hcxFx/pjNbtw/pfyu7T1QMIgf1UO/lJUYx\nkHoBRw==\n-----END CERTIFICATE REQUEST-----\n",
                "AwsHardwareCertificate": "-----BEGIN CERTIFICATE-----\nMIIDozCCAougAwIBAgIFAONpW/QwDQYJKoZIhvcNAQELBQAwgYcxCzAJBgNVBAYT\nAlVTMREwDwYDVQQIDAhWaXJnaW5pYTEQMA4GA1UEBwwHSGVybmRvbjEhMB8GA1UE\nCgwYQW1hem9uIFdlYiBTZXJ2aWNlcyBJTkMuMREwDwYDVQQLDAhDbG91ZEhTTTEd\nMBsGA1UEAwwUQVdTIENsb3VkSFNNIFJvb3QgRzEwHhcNMTkxMjAyMTA0NzIzWhcN\nMjkxMTI5MTA0NzIzWjB2MUQwCQYDVQQGEwJVUzAJBgNVBAgMAkNBMA0GA1UECgwG\nQ2F2aXVtMA0GA1UECwwGTjNGSVBTMA4GA1UEBwwHU2FuSm9zZTEuMCwGA1UEAwwl\nSFNNOjUuMkcxOTE3LUlDTTAwMDQ1NiwgZm9yIEZJUFMgbW9kZTCCASIwDQYJKoZI\nhvcNAQEBBQADggEPADCCAQoCggEBAKbYKpM3TitmNauI2vV1QsfaE7lDhTkHqdNs\n55j6xxbYQVJpU+fNHT1IKFTXUJUSwwxpHcgPozvisYCeBb5Qw/YvlthhtgkHhb/q\njphvFYHOzIbSV519Vh8eWZ7keiopxbqQzCRfxJKqK8uiSKh53UMhg3P7btQEhdjc\nydlI4CEXbBz12AMycyRFUxnopQJksWRJU5ZSGWIRp9e3bcqMTbmw5D/4jH0vkxXg\nmyT8kFjdMu8fxckpN2Fg4MJnjkWqrrrK4nSg6Xo4ntPwQKT+xbdXM9g9jTNck4ah\nJVbQvok1SrrTFPeT4U9W9m4oVa3hLQU7UhaalqUwB0jBD7ktGv0CAwEAAaMmMCQw\nDgYDVR0PAQH/BAQDAgIEMBIGA1UdEwEB/wQIMAYBAf8CAQAwDQYJKoZIhvcNAQEL\nBQADggEBADJfBWkNidTg+h2eo0bTtW4hHHKMuJKxsXH1hQZI0yY1EWVFr+NHr2OE\nAQ6QTpihrxTyFX7oElz2IL1zYQYqCKEI4xyww/dgKL+5GnXkR1Tzh7ySKahscYON\nuMShzqIdXtlqy/12sOTxLXDewCxOqwvU4Bk11WyK6wgR1J1Ppvuwf3tmPuJgB8zp\n4I04/xo3Vh+1AfMJ3h0HmNaBIBc+Ox8z4pJAPFucZaxXm73nPPuZvDtDwcUcwXcU\npMk9oNWzIJnggjeF6PULzWR6MW/+5tX+KEHkGn97CpOumN9KVTmAVrkpDFdcnc7+\n4LcRYJzcfz5JXsXiVTE790lzwI1cffk=\n-----END CERTIFICATE-----\n",
                "ManufacturerHardwareCertificate": "-----BEGIN CERTIFICATE-----\nMIIDqTCCApGgAwIBAgIBATANBgkqhkiG9w0BAQsFADCBkTELMAkGA1UEBhMCVVMx\nEzARBgNVBAgMCkNhbGlmb3JuaWExETAPBgNVBAcMCFNhbiBKb3NlMRUwEwYDVQQK\nDAxDYXZpdW0sIEluYy4xFzAVBgNVBAsMDkxpcXVpZFNlY3VyaXR5MSowKAYDVQQD\nDCFsb2NhbGNhLmxpcXVpZHNlY3VyaXR5LmNhdml1bS5jb20wHhcNMTkwNzIyMTcz\nODE3WhcNMjkwNzE5MTczODE3WjB2MUQwCQYDVQQGEwJVUzAJBgNVBAgMAkNBMA0G\nA1UECgwGQ2F2aXVtMA0GA1UECwwGTjNGSVBTMA4GA1UEBwwHU2FuSm9zZTEuMCwG\nA1UEAwwlSFNNOjUuMkcxOTE3LUlDTTAwMDQ1NiwgZm9yIEZJUFMgbW9kZTCCASIw\nDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKbYKpM3TitmNauI2vV1QsfaE7lD\nhTkHqdNs55j6xxbYQVJpU+fNHT1IKFTXUJUSwwxpHcgPozvisYCeBb5Qw/Yvlthh\ntgkHhb/qjphvFYHOzIbSV519Vh8eWZ7keiopxbqQzCRfxJKqK8uiSKh53UMhg3P7\nbtQEhdjcydlI4CEXbBz12AMycyRFUxnopQJksWRJU5ZSGWIRp9e3bcqMTbmw5D/4\njH0vkxXgmyT8kFjdMu8fxckpN2Fg4MJnjkWqrrrK4nSg6Xo4ntPwQKT+xbdXM9g9\njTNck4ahJVbQvok1SrrTFPeT4U9W9m4oVa3hLQU7UhaalqUwB0jBD7ktGv0CAwEA\nAaMmMCQwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAgQwDQYJKoZI\nhvcNAQELBQADggEBAGMlNJ2a2rEscGEmtFnMnV3a9GBQWGqI0uGZOXNvxMAektjr\naleFe96azvOsyjfc8/hXk93dw2ACl8lqUsp+UaB9iSiAHMLfE0nznO3MU1pu5QWT\niRUTsXDvQX3PWhiCUW8RJq8uOSjfy46l8nJUa9rm3k5rw10fvEJcepmtj698ZG/I\nILiugByFzHvLMiSgFe2teGuIlg5fjFXX9Vwzh8rGLIWXYH4aO0QHz7b+FZw1NLnS\n6lUuwR/qbwsSdIMUiGTOP4Lv/Pt6GXws4ndDrac8U/qfQBvJ8LS7yxMOuKZJ065V\nhiRPoGHX5FV81jLDEgOoRHQSymG0/QmyNiZ/NbA=\n-----END CERTIFICATE-----\n",
                "HsmCertificate": "-----BEGIN CERTIFICATE-----\nMIIDejCCAmKgAwIBAgIBCTANBgkqhkiG9w0BAQsFADB2MUQwCQYDVQQGEwJVUzAJ\nBgNVBAgMAkNBMA0GA1UECgwGQ2F2aXVtMA0GA1UECwwGTjNGSVBTMA4GA1UEBwwH\nU2FuSm9zZTEuMCwGA1UEAwwlSFNNOjUuMkcxOTE3LUlDTTAwMDQ1NiwgZm9yIEZJ\nUFMgbW9kZTAeFw0yMjA3MTMwNDMyNDhaFw0zMjA3MTAwNDMyNDhaMIGKMUQwCQYD\nVQQGEwJVUzAJBgNVBAgMAkNBMA0GA1UECgwGQ2F2aXVtMA0GA1UECwwGTjNGSVBT\nMA4GA1UEBwwHU2FuSm9zZTFCMEAGA1UEAww5SFNNOkU2RUU5OTdBRTZBRTk2MkI3\nRjdCMTE5RDUzRkY5NTpQQVJUTjo5LCBmb3IgRklQUyBtb2RlMIIBIjANBgkqhkiG\n9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnV8S3+Aszmk2Ajs4y5PQCu9hOHaACUbSUXZF\nBBRenGDC+tds4fSKwvamGwWG1bTsW79m9AJa+slauQNcR2ERN5Wt1p5+jjLSd9PL\nZGt8Z3NYG2W8uQJm7EOuj+hfIHxeWD7jIG1qu9u64x8V7fb90J0/S+Bzdu9EHeh6\ni9+Q75Rziq7HgrudZ5JNDCkJMfM57f9r3tNMAgiCc5ylOatvb14lSCJ48tdEhkZ8\nV7fEY8poiyPhLXfH6jO5mVW38MKoAYcFDoXDIlLdjB+g8MsOGucftklOQqFZhUj0\n/Bc4hAiTpR+K2x2ZjxgYZadUsC9+lX5OALscd4r49tOtSBC/aQIDAQABMA0GCSqG\nSIb3DQEBCwUAA4IBAQBxPapwvFDlH+geZmy2AicLPlMuAlfVt4p/TBqrpXbtqnAM\njjKHqWL1V4T/Y4hM4Yz8CGaz1nmc4QIaXSqnvOhqdJWVbcFAaCwpbgeCJzSIvEy/\ncwVFM/LJxeUYYMt57DHp2CSiMvdn3s9kunHbE/tBuVO8CZWJ8zznRk34a5DvRiwn\nBPBqQqS4nMypKat43Mio724yNEIX6HJ4BN3jrFkmzCVZjk76ywrcuCYRY/Yq35C7\nq/fkT1fvReeGttYlLRgUbaV7xBm3GDx95EwZOPVYSx551YqsDQKZfjZwMHRKmi8l\n/cg6APqOpZ7FUy2OQ0boby8/GVidhlE8f5xqKFBX\n-----END CERTIFICATE-----\n"
            },
            "TagList": [
                {
                    "Value": "iam-roles-anywhere-cloudhsm-cluster",
                    "Key": "Name"
                }
            ]
        }
    ]
}

# クラスターIDの取得
$ cluster_id=$(aws cloudhsmv2 describe-clusters \
    --query 'Clusters[].ClusterId' \
    --output text \
    --region us-east-1
)

# クラスターIDの表示
$ echo "$cluster_id"
cluster-ieh7u5cvyuq

# CSRファイルの作成
$ aws cloudhsmv2 describe-clusters \
    --filters clusterIds="$cluster_id" \
    --output text \
    --query 'Clusters[].Certificates.ClusterCsr' \
    --region us-east-1 \
  > "$cluster_id"_ClusterCsr.csr

# HSM証明書ファイルの作成
$ aws cloudhsmv2 describe-clusters \
    --filters clusterIds="$cluster_id" \
    --output text \
    --query 'Clusters[].Certificates.HsmCertificate' \
    --region us-east-1 \
  > "$cluster_id"_HsmCertificate.crt

#  AWSハードウェア証明書ファイルの作成
$ aws cloudhsmv2 describe-clusters \
    --filters clusterIds="$cluster_id" \
    --output text \
    --query 'Clusters[].Certificates.AwsHardwareCertificate' \
    --region us-east-1 \
  > "$cluster_id"_AwsHardwareCertificate.crt

# 製造元のハードウェア証明書ファイルの作成
$ aws cloudhsmv2 describe-clusters \
    --filters clusterIds="$cluster_id" \
    --output text \
    --query 'Clusters[].Certificates.ManufacturerHardwareCertificate' \
    --region us-east-1 \
  > "$cluster_id"_ManufacturerHardwareCertificate.crt

# CSRと各種証明書のファイルが作成されたか確認
$ ls -l "$cluster_id"*
-rw-r--r-- 1 ssm-user ssm-user 1323 Jul 13 04:50 cluster-ieh7u5cvyuq_AwsHardwareCertificate.crt
-rw-r--r-- 1 ssm-user ssm-user 1055 Jul 13 04:50 cluster-ieh7u5cvyuq_ClusterCsr.csr
-rw-r--r-- 1 ssm-user ssm-user 1266 Jul 13 04:50 cluster-ieh7u5cvyuq_HsmCertificate.crt
-rw-r--r-- 1 ssm-user ssm-user 1331 Jul 13 04:50 cluster-ieh7u5cvyuq_ManufacturerHardwareCertificate.crt

次に、CA証明書の発行に使用する秘密鍵を作成します。

# CA証明書の発行に使用する秘密鍵を作成
$ openssl genrsa -aes256 -out customerCA.key 2048
Generating RSA private key, 2048 bit long modulus
..+++
..........+++
e is 65537 (0x10001)
Enter pass phrase for customerCA.key:
Verifying - Enter pass phrase for customerCA.key:

# CA証明書の発行に使用する秘密鍵の確認
$ cat customerCA.key
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,8C8E8A81DA409CCC22E383AFD278C9DE

.
.
(中略)
.
.
-----END RSA PRIVATE KEY-----

次に、CA証明書を発行します。作成したCA証明書をIAM Roles Anywhereの信頼アンカーに登録する場合は、/etc/pki/tls/openssl.cnfv3_caセクションのkeyUsageを編集します。

# /etc/pki/tls/openssl.cnf の編集
$ sudo vi /etc/pki/tls/openssl.cnf

# 編集内容の確認
$ cat /etc/pki/tls/openssl.cnf

.
.
(中略)
.
.
[ v3_ca ]


# Extensions for a typical CA


# PKIX recommendation.

subjectKeyIdentifier=hash

authorityKeyIdentifier=keyid:always,issuer

# This is what PKIX recommends but some broken software chokes on critical
# extensions.
#basicConstraints = critical,CA:true
# So we do this instead.
basicConstraints = CA:true

# 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 = cRLSign, keyCertSign, digitalSignature

# Some might want this also
# nsCertType = sslCA, emailCA

# Include email address in subject alt name: another PKIX recommendation
# subjectAltName=email:copy
# Copy issuer details
# issuerAltName=issuer:copy

# DER hex encoding of an extension: beware experts only!
# obj=DER:02:03
# Where 'obj' is a standard or added object
# You can even override a supported extension:
# basicConstraints= critical, DER:30:03:01:01:FF

CA証明書を発行します。

# CA証明書の発行
$ openssl req -new -x509 -days 7 -key customerCA.key -out customerCA.crt
Enter pass phrase for customerCA.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:JP
State or Province Name (full name) []:Tokyo
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:iam-roles-anywhere-ca
Email Address []:

# CA証明書の確認
$ cat customerCA.crt
-----BEGIN CERTIFICATE-----
MIIDxDCCAqygAwIBAgIJAK01tFvzwG7qMA0GCSqGSIb3DQEBCwUAMHIxCzAJBgNV
BAYTAkpQMQ4wDAYDVQQIDAVUb2t5bzEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5MRww
GgYDVQQKDBNEZWZhdWx0IENvbXBhbnkgTHRkMR4wHAYDVQQDDBVpYW0tcm9sZXMt
.
.
(中略)
.
.
S/lTQW7NE8vk3J/Tkwn9EGZngwA0I041cl+k1MwdLREo6Ej+HhTVQQXqU7XxFXsS
I3E/V2AlYgmBal85CFHt5nJdwKlqUIhzjNA4hZKvu8N0M/wxshNlSe5Tmh03xgR+
/7L86BUcE/GY3Od8L7gFhlUN6wbddQyhfawf45AJQTJzClgawIOHEL7x1XTKj67o
jjRuiBs71NI=
-----END CERTIFICATE-----

# CA証明書の署名を確認
$ openssl x509 -text -noout -in customerCA.crt
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            ad:35:b4:5b:f3:c0:6e:ea
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=JP, ST=Tokyo, L=Default City, O=Default Company Ltd, CN=iam-roles-anywhere-ca
        Validity
            Not Before: Jul 13 05:04:46 2022 GMT
            Not After : Jul 20 05:04:46 2022 GMT
        Subject: C=JP, ST=Tokyo, L=Default City, O=Default Company Ltd, CN=iam-roles-anywhere-ca
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:bd:1d:39:66:2a:a6:57:03:e4:64:71:f3:1a:b5:
                    3f:aa:13:e4:37:c7:84:3c:62:aa:ca:50:c2:7f:37:
                    8e:6c:3e:19:29:82:e1:78:f8:fb:cd:7f:55:1c:4c:
                    9b:d7:75:3a:54:f8:dd:be:16:b6:ea:3e:09:d8:f0:
                    9d:ba:4d:39:1d:39:e4:a0:e8:bf:36:5e:c6:47:b3:
                    fa:25:c0:97:84:01:04:6e:fc:0b:23:1c:fc:1e:94:
                    fe:a6:9f:9a:46:b9:98:f1:71:09:02:d6:09:57:60:
                    e6:aa:45:0a:b5:84:49:18:3a:7b:57:ab:d1:ba:7d:
                    01:a0:5a:cf:a5:66:7e:b4:61:e1:1f:35:d8:31:61:
                    4a:d7:25:03:8d:d3:0e:66:25:bd:3d:d3:c5:81:a8:
                    25:db:0e:7c:c9:ad:0a:26:17:64:16:90:a5:66:11:
                    85:fc:b6:12:68:38:58:8f:d2:ab:8b:27:27:d9:0b:
                    71:83:50:3a:31:ab:70:eb:52:89:b2:17:c7:32:f3:
                    f9:17:e6:23:4c:a8:d3:ca:af:8e:d9:d4:2d:a7:f4:
                    bb:cc:5c:bf:2a:53:d5:ff:ee:b2:d7:57:e0:d4:b3:
                    a2:aa:c8:0a:1a:eb:9b:b6:7e:d3:f0:b1:c7:27:5a:
                    69:50:83:33:6e:7e:73:8d:7d:a7:e3:e9:9b:8a:ce:
                    cc:0d
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Subject Key Identifier:
                95:79:57:E2:6F:9D:EE:71:1B:E5:69:CC:70:BF:A4:06:68:B9:37:03
            X509v3 Authority Key Identifier:
                keyid:95:79:57:E2:6F:9D:EE:71:1B:E5:69:CC:70:BF:A4:06:68:B9:37:03

            X509v3 Basic Constraints:
                CA:TRUE
            X509v3 Key Usage:
                Digital Signature, Certificate Sign, CRL Sign
    Signature Algorithm: sha256WithRSAEncryption
         a1:de:0f:f1:15:1f:48:0b:62:03:76:df:f3:f5:c1:de:25:bc:
         72:ba:0d:96:5d:e0:6f:95:d0:1f:67:ed:45:73:39:1b:f1:1a:
         aa:6e:b6:55:0b:79:32:a2:18:3a:69:e4:4e:fc:35:19:15:f1:
         6b:72:cb:a0:8e:9b:13:58:a6:d6:f5:06:9c:bc:df:ac:e8:73:
         1c:db:ad:d9:0d:6a:15:67:66:26:28:ad:62:e9:cd:b5:e0:0a:
         51:6d:c7:7e:45:49:40:e0:af:06:8a:68:9d:9e:4b:f9:53:41:
         6e:cd:13:cb:e4:dc:9f:d3:93:09:fd:10:66:67:83:00:34:23:
         4e:35:72:5f:a4:d4:cc:1d:2d:11:28:e8:48:fe:1e:14:d5:41:
         05:ea:53:b5:f1:15:7b:12:23:71:3f:57:60:25:62:09:81:6a:
         5f:39:08:51:ed:e6:72:5d:c0:a9:6a:50:88:73:8c:d0:38:85:
         92:af:bb:c3:74:33:fc:31:b2:13:65:49:ee:53:9a:1d:37:c6:
         04:7e:ff:b2:fc:e8:15:1c:13:f1:98:dc:e7:7c:2f:b8:05:86:
         55:0d:eb:06:dd:75:0c:a1:7d:ac:1f:e3:90:09:41:32:73:0a:
         58:1a:c0:83:87:10:be:f1:d5:74:ca:8f:ae:e8:8e:34:6e:88:
         1b:3b:d4:d2

発行したCA証明書をIAM Roles Anywhereの信頼アンカーに登録できることを確認しておきます。

信頼アンカー

作成したCA証明書でダウンロードしたCSRに署名して、クラスター証明書を発行します。

# クラスター証明書の発行
$ openssl x509 -req -days 7 -in "$cluster_id"_ClusterCsr.csr \
                              -CA customerCA.crt \
                              -CAkey customerCA.key \
                              -CAcreateserial \
                              -out "$cluster_id"_CustomerHsmCertificate.crt
Signature ok
subject=/C=US/ST=CA/O=Cavium/OU=N3FIPS/L=SanJose/CN=HSM:E6EE997AE6AE962B7F7B119D53FF95:PARTN:9, for FIPS mode
Getting CA Private Key
Enter pass phrase for customerCA.key:

# クラスター証明書の確認
$ cat cluster-ieh7u5cvyuq_CustomerHsmCertificate.crt
-----BEGIN CERTIFICATE-----
MIIDeTCCAmECCQCDtGuCxiYhVDANBgkqhkiG9w0BAQsFADByMQswCQYDVQQGEwJK
UDEOMAwGA1UECAwFVG9reW8xFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UE
CgwTRGVmYXVsdCBDb21wYW55IEx0ZDEeMBwGA1UEAwwVaWFtLXJvbGVzLWFueXdo
.
.
(中略)
.
.
FDPR0AKlsMIumTBGLzmxF653RnvxvpiKS1bJ47/XHP5zgy3H3TBhkYIU9Bjm1xGd
uF66u38Fl8n5lVfWZ9AYPk0miNvuAgEOZYfE8GqxF3N0O6+8vZSCkkgLbSMPtI9E
X9XIjwtdOugbkrL0MZ/uFR1sXZiFtSKyWwhbIyGGwDmivMPOhZRIpPRr2bHKKRV5
cSTqO1yOv5zKIlw00LgvhwbuCWg6ZjzHAnXjcZE=
-----END CERTIFICATE-----

# クラスター証明書のSubjectを確認
$ openssl x509 -text -noout -in cluster-ieh7u5cvyuq_CustomerHsmCertificate.crt
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
            83:b4:6b:82:c6:26:21:54
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=JP, ST=Tokyo, L=Default City, O=Default Company Ltd, CN=iam-roles-anywhere-ca
        Validity
            Not Before: Jul 13 05:12:38 2022 GMT
            Not After : Jul 20 05:12:38 2022 GMT
        Subject: C=US, ST=CA, O=Cavium, OU=N3FIPS, L=SanJose, CN=HSM:E6EE997AE6AE962B7F7B119D53FF95:PARTN:9, for FIPS mode
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:9d:5f:12:df:e0:2c:ce:69:36:02:3b:38:cb:93:
                    d0:0a:ef:61:38:76:80:09:46:d2:51:76:45:04:14:
                    5e:9c:60:c2:fa:d7:6c:e1:f4:8a:c2:f6:a6:1b:05:
                    86:d5:b4:ec:5b:bf:66:f4:02:5a:fa:c9:5a:b9:03:
                    5c:47:61:11:37:95:ad:d6:9e:7e:8e:32:d2:77:d3:
                    cb:64:6b:7c:67:73:58:1b:65:bc:b9:02:66:ec:43:
                    ae:8f:e8:5f:20:7c:5e:58:3e:e3:20:6d:6a:bb:db:
                    ba:e3:1f:15:ed:f6:fd:d0:9d:3f:4b:e0:73:76:ef:
                    44:1d:e8:7a:8b:df:90:ef:94:73:8a:ae:c7:82:bb:
                    9d:67:92:4d:0c:29:09:31:f3:39:ed:ff:6b:de:d3:
                    4c:02:08:82:73:9c:a5:39:ab:6f:6f:5e:25:48:22:
                    78:f2:d7:44:86:46:7c:57:b7:c4:63:ca:68:8b:23:
                    e1:2d:77:c7:ea:33:b9:99:55:b7:f0:c2:a8:01:87:
                    05:0e:85:c3:22:52:dd:8c:1f:a0:f0:cb:0e:1a:e7:
                    1f:b6:49:4e:42:a1:59:85:48:f4:fc:17:38:84:08:
                    93:a5:1f:8a:db:1d:99:8f:18:18:65:a7:54:b0:2f:
                    7e:95:7e:4e:00:bb:1c:77:8a:f8:f6:d3:ad:48:10:
                    bf:69
                Exponent: 65537 (0x10001)
    Signature Algorithm: sha256WithRSAEncryption
         00:be:b8:fe:81:46:50:42:95:da:d9:a8:7c:2d:46:67:ec:61:
         42:38:c5:38:5c:10:53:e4:48:24:2b:15:35:72:40:d2:a7:67:
         6c:99:1b:af:3d:ae:14:59:83:ce:d7:de:ac:b1:f0:fb:c8:ab:
         4e:50:58:5f:2c:89:09:6a:1a:77:be:87:47:43:7e:4d:ff:56:
         a9:c1:ab:3f:35:aa:91:d5:80:b8:89:14:33:d1:d0:02:a5:b0:
         c2:2e:99:30:46:2f:39:b1:17:ae:77:46:7b:f1:be:98:8a:4b:
         56:c9:e3:bf:d7:1c:fe:73:83:2d:c7:dd:30:61:91:82:14:f4:
         18:e6:d7:11:9d:b8:5e:ba:bb:7f:05:97:c9:f9:95:57:d6:67:
         d0:18:3e:4d:26:88:db:ee:02:01:0e:65:87:c4:f0:6a:b1:17:
         73:74:3b:af:bc:bd:94:82:92:48:0b:6d:23:0f:b4:8f:44:5f:
         d5:c8:8f:0b:5d:3a:e8:1b:92:b2:f4:31:9f:ee:15:1d:6c:5d:
         98:85:b5:22:b2:5b:08:5b:23:21:86:c0:39:a2:bc:c3:ce:85:
         94:48:a4:f4:6b:d9:b1:ca:29:15:79:71:24:ea:3b:5c:8e:bf:
         9c:ca:22:5c:34:d0:b8:2f:87:06:ee:09:68:3a:66:3c:c7:02:
         75:e3:71:91
$

発行したクラスター証明書のSubjectから、確かにHSMクラスターの証明書であることが分かります。

用意したCA証明書とクラスター証明書を使ってクラスターを初期化します。

$ aws cloudhsmv2 initialize-cluster \
    --cluster-id "$cluster_id" \
    --signed-cert file://"$cluster_id"_CustomerHsmCertificate.crt \
    --trust-anchor file://customerCA.crt \
    --region us-east-1
{
    "StateMessage": "Cluster is initializing. State will change to INITIALIZED upon completion.",
    "State": "INITIALIZE_IN_PROGRESS"
}

クラスターの状態がINITIALIZE_IN_PROGRESSになったようです。

マネジメントコンソールからもクラスターの状態がInitialize in progressになっています。

Initialize in progress

3分ほど待つとクラスターの状態がInitializedになりました。

Initialized

クラスターのアクティブ化

次に、クラスターをアクティブにしてあげます。

事前準備として、AWS CloudHSMクライアントをインストールします。

# AWS CloudHSMクライアントのRPMをダウンロード
$ wget https://s3.amazonaws.com/cloudhsmv2-software/CloudHsmClient/EL7/cloudhsm-client-latest.el7.x86_64.rpm
--2022-07-13 05:23:06--  https://s3.amazonaws.com/cloudhsmv2-software/CloudHsmClient/EL7/cloudhsm-client-latest.el7.x86_64.rpm
Resolving s3.amazonaws.com (s3.amazonaws.com)... 52.216.40.24
Connecting to s3.amazonaws.com (s3.amazonaws.com)|52.216.40.24|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1878962 (1.8M) [binary/octet-stream]
Saving to: ‘cloudhsm-client-latest.el7.x86_64.rpm’

100%[===================================================================================================================================>] 1,878,962   --.-K/s   in 0.01s

2022-07-13 05:23:06 (124 MB/s) - ‘cloudhsm-client-latest.el7.x86_64.rpm’ saved [1878962/1878962]

# AWS CloudHSMクライアントのインストール
$ sudo yum install ./cloudhsm-client-latest.el7.x86_64.rpm
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
Examining ./cloudhsm-client-latest.el7.x86_64.rpm: cloudhsm-client-3.4.4-1.el7.x86_64
Marking ./cloudhsm-client-latest.el7.x86_64.rpm to be installed
Resolving Dependencies
--> Running transaction check
---> Package cloudhsm-client.x86_64 0:3.4.4-1.el7 will be installed
--> Processing Dependency: libncurses.so.5()(64bit) for package: cloudhsm-client-3.4.4-1.el7.x86_64
amzn2-core                                                                                                                                            | 3.7 kB  00:00:00
--> Running transaction check
---> Package ncurses-compat-libs.x86_64 0:6.0-8.20170212.amzn2.1.3 will be installed
--> Finished Dependency Resolution

Dependencies Resolved

=============================================================================================================================================================================
 Package                                Arch                      Version                                        Repository                                             Size
=============================================================================================================================================================================
Installing:
 cloudhsm-client                        x86_64                    3.4.4-1.el7                                    /cloudhsm-client-latest.el7.x86_64                    5.0 M
Installing for dependencies:
 ncurses-compat-libs                    x86_64                    6.0-8.20170212.amzn2.1.3                       amzn2-core                                            308 k

Transaction Summary
=============================================================================================================================================================================
Install  1 Package (+1 Dependent package)

Total size: 5.3 M
Total download size: 308 k
Installed size: 5.9 M
Is this ok [y/d/N]: y
Downloading packages:
ncurses-compat-libs-6.0-8.20170212.amzn2.1.3.x86_64.rpm                                                                                               | 308 kB  00:00:00
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Installing : ncurses-compat-libs-6.0-8.20170212.amzn2.1.3.x86_64                                                                                                       1/2
  Installing : cloudhsm-client-3.4.4-1.el7.x86_64                                                                                                                        2/2
  Verifying  : ncurses-compat-libs-6.0-8.20170212.amzn2.1.3.x86_64                                                                                                       1/2
  Verifying  : cloudhsm-client-3.4.4-1.el7.x86_64                                                                                                                        2/2

Installed:
  cloudhsm-client.x86_64 0:3.4.4-1.el7

Dependency Installed:
  ncurses-compat-libs.x86_64 0:6.0-8.20170212.amzn2.1.3

Complete!

CloudHSMクライアントを使用するにはCA証明書を/opt/cloudhsm/etc/に移動させる必要があるので、移動させておきます。

# CA証明書の移動
$ sudo mv customerCA.crt /opt/cloudhsm/etc/customerCA.crt

# CA証明書が指定のディレクトリに移動したことを確認
$ ls -l /opt/cloudhsm/etc/
total 28
drwxr-xr-x 2 root     root       42 Jul 13 05:23 certs
-rwxr-xr-x 1 root     root     1342 Dec 30  2021 client.crt
-rwxr-xr-x 1 root     root     1704 Dec 30  2021 client.key
-rw-r--r-- 1 root     root     1156 Jul 13 05:26 cloudhsm_client.cfg
-rw-r--r-- 1 root     root     1179 Dec 30  2021 cloudhsm_client.cfg.old
-rw-r--r-- 1 root     root      704 Jul 13 05:26 cloudhsm_mgmt_util.cfg
-rw-r--r-- 1 root     root      600 Dec 30  2021 cloudhsm_mgmt_util.cfg.old
-rw-r--r-- 1 ssm-user ssm-user 1367 Jul 13 05:04 customerCA.crt

証明書を移動させないと、CloudHSM管理ユーティリティ(CMU)起動時に以下のようなエラーが出力されます。

$ /opt/cloudhsm/bin/cloudhsm_mgmt_util /opt/cloudhsm/etc/cloudhsm_mgmt_util.cfg
Ignoring E2E enable flag in the configuration file

Connecting to the server(s), it may take time
depending on the server(s) load, please wait...

Connecting to server '172.31.40.54': hostname '172.31.40.54', port 2225...
Connected to server '172.31.40.54': hostname '172.31.40.54', port 2225.
/opt/cloudhsm/etc/customerCA.crt,
partition owner certificate not exist at given path
Server 0(172.31.40.54) is in unencrypted mode now...
running in limited commands mode
Error: partition owner certificate doesn't exist at given path.
Failed to create client ssl ctx
E2E Session failed: E2E setup failed
Enabling E2E failed

証明書を移動させたらCloudHSMクライアントの設定ファイルを更新し、HSMのIPアドレスを指定します。

$ sudo /opt/cloudhsm/bin/configure -a 172.31.40.54
Updating server config in /opt/cloudhsm/etc/cloudhsm_client.cfg
Updating server config in /opt/cloudhsm/etc/cloudhsm_mgmt_util.cfg

CloudHSM管理ユーティリティ(CMU)でHSMに接続し、PreCrypto Officer (PRECO)の認証情報を使用してHSM にログインします。

HSMのユーザーの詳細は以下AWS公式ドキュメントをご確認ください。

$ /opt/cloudhsm/bin/cloudhsm_mgmt_util /opt/cloudhsm/etc/cloudhsm_mgmt_util.cfg
Ignoring E2E enable flag in the configuration file

Connecting to the server(s), it may take time
depending on the server(s) load, please wait...

Connecting to server '172.31.40.54': hostname '172.31.40.54', port 2225...
Connected to server '172.31.40.54': hostname '172.31.40.54', port 2225.
E2E enabled on server 0(172.31.40.54)
aws-cloudhsm>

現在のユーザー一覧を確認します。

aws-cloudhsm>listUsers
Users on server 0(172.31.40.54):
Number of users found:2

    User Id             User Type       User Name                          MofnPubKey    LoginFailureCnt         2FA
         1              PRECO           admin                                    NO               0               NO
         2              AU              app_user                                 NO               0               NO

PRECOユーザーとしてHSMにログインし、PRECOユーザーのパスワードを変更します。

# PRECOユーザーとしてHSMにログイン
aws-cloudhsm>loginHSM PRECO admin password
loginHSM success on server 0(172.31.40.54)

# PRECOユーザーのパスワードを変更
aws-cloudhsm>changePswd PRECO admin fbAGRQ@NP!dY4LHDK7HK!*UYnbxKc6gu
*************************CAUTION********************************
This is a CRITICAL operation, should be done on all nodes in the
cluster. AWS does NOT synchronize these changes automatically with the
nodes on which this operation is not executed or failed, please
ensure this operation is executed on all nodes in the cluster.
****************************************************************

Do you want to continue(y/n)?y
Changing password for admin(PRECO) on 1 nodes
changePswd success on server 0(172.31.40.54)

# PRECO から CO に変わったことを確認
aws-cloudhsm>listUsers
Users on server 0(172.31.40.54):
Number of users found:2

    User Id             User Type       User Name                          MofnPubKey    LoginFailureCnt         2FA
         1              CO              admin                                    NO               0               NO
         2              AU              app_user                                 NO               0               NO

ユーザーのタイプがPRECOからCOに変更されていることを確認できました。

このタイミングでマネジメントコンソールからクラスターの状態を確認すると、Activeになっていました。

Active

キーペアの生成

試しにHSM上でキーペアを作成してみます。

キーペアの作成などキーの管理はCrypto user(CU)でなければできません。

現在CUはいないので事前準備としてCUを作成します。CMUからCOとしてログインし、新しくCUを作成します。

# COとしてログイン
aws-cloudhsm>loginHSM CO admin fbAGRQ@NP!dY4LHDK7HK!*UYnbxKc6gu
loginHSM success on server 0(172.31.40.54)

# CUを作成
aws-cloudhsm>createUser CU crypto_user cYoav.j8ZG87D!NmFvU.sjVATb8RwE4r
*************************CAUTION********************************
This is a CRITICAL operation, should be done on all nodes in the
cluster. AWS does NOT synchronize these changes automatically with the
nodes on which this operation is not executed or failed, please
ensure this operation is executed on all nodes in the cluster.
****************************************************************

Do you want to continue(y/n)?y
Creating User crypto_user(CU) on 1 nodes
createUser success on server 0(172.31.40.54)

# CUが作成されたことを確認
aws-cloudhsm>listUsers
Users on server 0(172.31.40.54):
Number of users found:3

    User Id             User Type       User Name                          MofnPubKey    LoginFailureCnt         2FA
         1              CO              admin                                    NO               0               NO
         2              AU              app_user                                 NO               0               NO
         3              CU              crypto_user                              NO               0               NO

キー管理ユーティリティ(KMU)でキーペアを作成します。

# KMUのサービスを起動
$ sudo service cloudhsm-client start
Redirecting to /bin/systemctl start cloudhsm-client.service

# KMUでHSMに接続
$ /opt/cloudhsm/bin/key_mgmt_util

        Cfm3Initialize() returned app id : 01008000

        session_handle 1008002

        Current FIPS mode is: 00000002


Help Commands Available:

Syntax: <command> -h


   Command               Description
   =======               ===========

   exit                   Exits this application
   help                   Displays this information

        Configuration and Admin Commands
   getHSMInfo             Gets the HSM Information
   getPartitionInfo       Gets the Partition Information
   listUsers              Lists all users of a partition
   loginStatus            Gets the Login Information
   loginHSM               Login to the HSM
   logoutHSM              Logout from the HSM

        M of N commands
   getToken               Initiate an MxN service and get Token
   delToken               delete Token(s)
   approveToken           Approves an MxN service
   listTokens             List all Tokens in the current partition

        Key Generation Commands

        Asymmetric Keys:
   genRSAKeyPair          Generates an RSA Key Pair
   genDSAKeyPair          Generates a DSA Key Pair
   genECCKeyPair          Generates an ECC Key Pair

        Symmetric Keys:
   genPBEKey              Generates a PBE DES3 key
   genSymKey              Generates a Symmetric keys

        Key Import/Export Commands
   createPublicKey        Creates an RSA public key
   importPubKey           Imports RSA/DSA/EC Public key
   exportPubKey           Exports RSA/DSA/EC Public key
   importPrivateKey       Imports RSA/DSA/EC private key
   exportPrivateKey       Exports RSA/DSA/EC private key
   imSymKey               Imports a Symmetric key
   exSymKey               Exports a Symmetric key
   wrapKey                Wraps a key from HSM using the specified handle
   unWrapKey              UnWraps a key into HSM using the specified handle

        Key Management Commands
   deleteKey              Delete Key
   setAttribute           Sets an attribute of an object
   getKeyInfo             Get Key Info about shared users/sessions
   findKey                Find Key
   findSingleKey          Find single Key
   getAttribute           Reads an attribute from an object

        Certificate Setup Commands
   getCert                Gets Partition Certificates stored on HSM

        Key Transfer Commands
   insertMaskedObject     Inserts a masked object
   extractMaskedObject    Extracts a masked object

        Management Crypto Commands
   sign                   Generates a signature
   verify                 Verifies a signature
   aesWrapUnwrap          Does PKCS5 Padded AES Wrap/Unwrap

        Helper Commands
   Error2String           Converts Error codes to Strings
                          save key handle in fake PEM format
   getCaviumPrivKey       Saves an RSA private key handle
                          in fake PEM format
   IsValidKeyHandlefile   Checks if private key file has
                          an HSM key handle or a real key
   listAttributes         List all attributes for getAttributes
   listECCCurveIds        List HSM supported ECC CurveIds


# 事前に作成したCUでログイン
Command:  loginHSM -u CU -s crypto_user -p cYoav.j8ZG87D!NmFvU.sjVATb8RwE4r

        Cfm3LoginHSM returned: 0x00 : HSM Return: SUCCESS

        Cluster Status:
        Node id 0 status: 0x00000000 : HSM Return: SUCCESS

# キーが空であることを確認
Command:  findKey

        Total number of keys present: 0

        Cluster Status:
        Node id 0 status: 0x00000000 : HSM Return: SUCCESS

        Cfm3FindKey returned: 0x00 : HSM Return: SUCCESS

# RSAのキーペアを作成
Command:  genRSAKeyPair -m 2048 -e 65537 -l rsa_test

        Cfm3GenerateKeyPair returned: 0x00 : HSM Return: SUCCESS

        Cfm3GenerateKeyPair:    public key handle: 6    private key handle: 7

        Cluster Status:
        Node id 0 status: 0x00000000 : HSM Return: SUCCESS

# キーが2つあることを確認
Command:  findKey

        Total number of keys present: 2

        Number of matching keys from start index 0::1

        Handles of matching keys:
        6, 7

        Cluster Status:
        Node id 0 status: 0x00000000 : HSM Return: SUCCESS

        Cfm3FindKey returned: 0x00 : HSM Return: SUCCESS

公開鍵のキーハンドルが6、秘密鍵のキーハンドルがとしてHSMに追加されました。

作成したキーペアの情報をダウンロードして確認してみます。

# 出力できるキーペアの情報を確認
Command:  listAttributes


Description
===========
The following are all of the possible attribute values for getAttributes.

      OBJ_ATTR_CLASS                  = 0
      OBJ_ATTR_TOKEN                  = 1
      OBJ_ATTR_PRIVATE                = 2
      OBJ_ATTR_LABEL                  = 3
      OBJ_ATTR_TRUSTED                = 134
      OBJ_ATTR_KEY_TYPE               = 256
      OBJ_ATTR_ID                     = 258
      OBJ_ATTR_SENSITIVE              = 259
      OBJ_ATTR_ENCRYPT                = 260
      OBJ_ATTR_DECRYPT                = 261
      OBJ_ATTR_WRAP                   = 262
      OBJ_ATTR_UNWRAP                 = 263
      OBJ_ATTR_SIGN                   = 264
      OBJ_ATTR_VERIFY                 = 266
      OBJ_ATTR_DERIVE                 = 268
      OBJ_ATTR_LOCAL                  = 355
      OBJ_ATTR_MODULUS                = 288
      OBJ_ATTR_MODULUS_BITS           = 289
      OBJ_ATTR_PUBLIC_EXPONENT        = 290
      OBJ_ATTR_VALUE_LEN              = 353
      OBJ_ATTR_EXTRACTABLE            = 354
      OBJ_ATTR_NEVER_EXTRACTABLE      = 356
      OBJ_ATTR_ALWAYS_SENSITIVE       = 357
      OBJ_ATTR_DESTROYABLE            = 370
      OBJ_ATTR_KCV                    = 371
      OBJ_ATTR_WRAP_WITH_TRUSTED      = 528
      OBJ_ATTR_WRAP_TEMPLATE          = 1073742353
      OBJ_ATTR_UNWRAP_TEMPLATE        = 1073742354
      OBJ_ATTR_ALL                    = 512

# 秘密鍵の情報をダウンロード
Command:  getAttribute -o 7 -a 512 -out privatekey_attr.txt

Attribute size: 813, count: 27
Written to: privatekey_attr.txt file

        Cfm3GetAttribute returned: 0x00 : HSM Return: SUCCESS

# 公開鍵の情報をダウンロード
Command:  getAttribute -o 6 -a 512 -out publickey_attr.txt

Attribute size: 801, count: 26
Written to: publickey_attr.txt file

        Cfm3GetAttribute returned: 0x00 : HSM Return: SUCCESS

ダウンロードした情報を確認してみます。

# 秘密鍵の情報を確認
$ cat privatekey_attr.txt
OBJ_ATTR_CLASS
0x03
OBJ_ATTR_KEY_TYPE
0x00
OBJ_ATTR_TOKEN
0x01
OBJ_ATTR_PRIVATE
0x01
OBJ_ATTR_ENCRYPT
0x00
OBJ_ATTR_DECRYPT
0x01
OBJ_ATTR_WRAP
0x00
OBJ_ATTR_UNWRAP
0x01
OBJ_ATTR_SIGN
0x01
OBJ_ATTR_VERIFY
0x00
OBJ_ATTR_LOCAL
0x01
OBJ_ATTR_SENSITIVE
0x01
OBJ_ATTR_EXTRACTABLE
0x01
OBJ_ATTR_LABEL
rsa_test
OBJ_ATTR_ID

OBJ_ATTR_VALUE_LEN
0x000004c1
OBJ_ATTR_KCV
0xfee3ab
OBJ_ATTR_MODULUS
0x9d2a1a1a40cf302ec30691caed87cadfdf4551cf0b717f88f1c790b4483754493eb47f4837c1657ef1732aab6826fc916cb8acaa9443541f42a598e14488821d63c02d9a1aac160465ac7e3db354e9292d80269c85c18af39072fa81b1240546099eb412cb678365b70ab0b029db47430e82b5f9ca8ed8f140b1812aa1a6c1a2486b5c385dc3019ce66a66f93814586270c7342fe2a424511f4a87570c5157cd4b6fd9447325e8a6693720b41601a336abe6efd3d6a8f2133edbd599f90d3c78afe2125917dba02aeb3890dc5575adfcaaf9c83568a890b811437e4effc8c23415632afff884a9dd21d489ee14b3644e600f0833ac6f53d71eea7e7fe8c5cdd3
OBJ_ATTR_MODULUS_BITS
0x00000800
OBJ_ATTR_PUBLIC_EXPONENT
0x010001
OBJ_ATTR_VENDOR_DEFINED
0x00000280
OBJ_ATTR_TRUSTED
0x00
OBJ_ATTR_WRAP_WITH_TRUSTED
0x00
OBJ_ATTR_DERIVE
0x00
OBJ_ATTR_ALWAYS_SENSITIVE
0x01
OBJ_ATTR_NEVER_EXTRACTABLE
0x00
OBJ_ATTR_DESTROYABLE
0x01

# 公開鍵の情報を確認
$ cat publickey_attr.txt
OBJ_ATTR_CLASS
0x02
OBJ_ATTR_KEY_TYPE
0x00
OBJ_ATTR_TOKEN
0x01
OBJ_ATTR_PRIVATE
0x01
OBJ_ATTR_ENCRYPT
0x01
OBJ_ATTR_DECRYPT
0x00
OBJ_ATTR_WRAP
0x01
OBJ_ATTR_UNWRAP
0x00
OBJ_ATTR_SIGN
0x00
OBJ_ATTR_VERIFY
0x01
OBJ_ATTR_LOCAL
0x01
OBJ_ATTR_SENSITIVE
0x00
OBJ_ATTR_EXTRACTABLE
0x01
OBJ_ATTR_LABEL
rsa_test
OBJ_ATTR_ID

OBJ_ATTR_VALUE_LEN
0x00000200
OBJ_ATTR_KCV
0xfee3ab
OBJ_ATTR_MODULUS
0x9d2a1a1a40cf302ec30691caed87cadfdf4551cf0b717f88f1c790b4483754493eb47f4837c1657ef1732aab6826fc916cb8acaa9443541f42a598e14488821d63c02d9a1aac160465ac7e3db354e9292d80269c85c18af39072fa81b1240546099eb412cb678365b70ab0b029db47430e82b5f9ca8ed8f140b1812aa1a6c1a2486b5c385dc3019ce66a66f93814586270c7342fe2a424511f4a87570c5157cd4b6fd9447325e8a6693720b41601a336abe6efd3d6a8f2133edbd599f90d3c78afe2125917dba02aeb3890dc5575adfcaaf9c83568a890b811437e4effc8c23415632afff884a9dd21d489ee14b3644e600f0833ac6f53d71eea7e7fe8c5cdd3
OBJ_ATTR_MODULUS_BITS
0x00000800
OBJ_ATTR_PUBLIC_EXPONENT
0x010001
OBJ_ATTR_TRUSTED
0x00
OBJ_ATTR_WRAP_WITH_TRUSTED
0x00
OBJ_ATTR_DERIVE
0x00
OBJ_ATTR_ALWAYS_SENSITIVE
0x00
OBJ_ATTR_NEVER_EXTRACTABLE
0x00
OBJ_ATTR_DESTROYABLE
0x01

キー属性リファレンスと照らし合わせながら表示された情報を確認していきます。

OBJ_ATTR_CLASSからどちらが公開鍵か秘密鍵か確認できます。また、OBJ_ATTR_ENCRYPTOBJ_ATTR_WRAPからデータもしくはキーの暗号化に使用できるかが確認できます。

秘密鍵のインポート

それでは秘密鍵をHSMにインポートしてみます。

例によって秘密鍵がパスフレーズで暗号化されたままだと、インポート時にfailed to read private key from fileとエラーになります。

Command:  importPrivateKey -f customerCA.key -l customer-ca-key -w 8
failed to read private key from file

秘密鍵のパスフレーズを解除しておきます。

# 秘密鍵のパスフレーズを解除
$ sudo openssl rsa -in customerCA.key -out decrypted_customerCA.key
Enter pass phrase for customerCA.key:
writing RSA key

# 秘密鍵のパスフレーズが解除されたことを確認
$ cat decrypted_customerCA.key
-----BEGIN RSA PRIVATE KEY-----
.
.
(中略)
.
.
-----END RSA PRIVATE KEY-----

KMUを使ってCUでログインし、秘密鍵をimportPrivateKeyでインポートします。

秘密鍵をインポートする際にはAESキー(ラップキー)を使用して暗号化(ラップ)する必要があります。そのためgenSymKeyでインポート前にこのセッションでのみ有効なAESキーを生成しています。

# CUでログイン
Command:  loginHSM -u CU -s crypto_user -p cYoav.j8ZG87D!NmFvU.sjVATb8RwE4r

        Cfm3LoginHSM returned: 0x00 : HSM Return: SUCCESS

        Cluster Status:
        Node id 0 status: 0x00000000 : HSM Return: SUCCESS

# 秘密鍵をインポートする際のAESキーを生成
Command:  genSymKey -t 31 -s 16 -sess -l import-wrapping-key

        Cfm3GenerateSymmetricKey returned: 0x00 : HSM Return: SUCCESS

        Symmetric Key Created.  Key Handle: 8

        Cluster Status:
        Node id 0 status: 0x00000000 : HSM Return: SUCCESS

# 秘密鍵をインポート
Command:  importPrivateKey -f decrypted_customerCA.key -l customer-ca-key -w 8
BER encoded key length is 1219

        Cfm3ImportWrapKey returned: 0x00 : HSM Return: SUCCESS

        Cfm3CreateUnwrapTemplate2 returned: 0x00 : HSM Return: SUCCESS

        Cfm3ImportUnWrapKey: 0x00 : HSM Return: SUCCESS

        Private Key Imported.  Key Handle: 9

        Cluster Status:
        Node id 0 status: 0x00000000 : HSM Return: SUCCESS

秘密鍵のインポートができました。

秘密鍵のエクスポート

最後に秘密鍵をexportPrivateKeyでエクスポートをします。

エクスポートする際もAESキーを使用して暗号化する必要があります。

Command:  exportPrivateKey -k 9 -w 8 -out export_decrypted_customerCA.key

        Cfm3ExportWrapKey returned: 0x00 : HSM Return: SUCCESS

        Cfm3ExportUnwrapKey returned: 0x00 : HSM Return: SUCCESS

PEM formatted private key is written to export_decrypted_customerCA.key

エクスポートされた秘密鍵を確認してみます。

$ cat export_decrypted_customerCA.key
-----BEGIN PRIVATE KEY-----
.
.
(中略)
.
.
-----END PRIVATE KEY-----

どうやらエクスポートした秘密鍵はRSA形式になっていないようです。

エクスポートした秘密鍵RSA形式に変換して、インポートした秘密鍵と比較してみます。

# エクスポートした秘密鍵RSA形式に変換
$ openssl rsa -in export_decrypted_customerCA.key -check -out rsa_export_decrypted_customerCA.key
writing RSA key

# インポート/エクスポートした秘密鍵を比較
$ diff -u decrypted_customerCA.key rsa_export_decrypted_customerCA.key
--- decrypted_customerCA.key    2022-07-13 06:50:24.934448694 +0000
+++ rsa_export_decrypted_customerCA.key 2022-07-13 07:50:35.763903985 +0000
@@ -1,3 +1,4 @@
+RSA key ok
 -----BEGIN RSA PRIVATE KEY-----

RSA形式に変更した際にRSA key okと追加されましたが、それ以外はインポート/エクスポートした秘密鍵が一致しました。

マネージドでハードウェアレベルの鍵の管理ができる

AWS CloudHSMで秘密鍵のインポートとエクスポートしてみました。

今までHSMを触った経験がなければ少し慣れるのに時間がかかりそうですが、マネージドでハードウェアレベルの鍵の管理ができるのはありがたいですね。

この記事が誰かの助けになれば幸いです。

以上、AWS事業本部 コンサルティング部の のんピ(@non____97)でした!