[アップデート] Amazon SES で S/MIME 署名が使えるようになったので試してみた
いわさです。
S/MIME は送信者の証明書でメッセージに電子署名を付ける方式で、受信者は差出人と内容が改ざんされていないことを検証できます。
これまで Amazon SES で S/MIME 署名を付けるには、署名済みの MIME メッセージ(RAW)を送信側で組み立ててから SES に渡す必要があってちょっと面倒でした。
先日のアップデートで、SES が S/MIME 署名そのものをサポートしました。
署名用の証明書を AWS Certificate Manager に保管しておくと、SES が送信時に自動でメッセージへ署名してくれます。
早速試してみましょう。東京リージョンでも使えます。
署名用の証明書を ACM に用意する
S/MIME 署名に使う証明書の要件は、公式ドキュメントに一覧で書かれています。
送信するリージョンの ACM にあること、アイデンティティが検証済みであること、証明書の SAN(サブジェクト代替名)に差出人アドレスと一致するメールアドレスを含むこと、鍵アルゴリズムが所定のものであること、有効期限内であること、の 5 点です。
- The certificate must be in ACM in the same AWS Region where you send email.
- The email identity must be verified. Either domain verification (TXT record) or email-address verification is acceptable.
- The certificate's Subject Alternative Name (SAN) must include an RFC822Name email address that matches the From address.
- The certificate key algorithm must use one of: RSA 2048, RSA 3072, RSA 4096, EC P-256, EC P-384, or EC P-521.
- The certificate must be currently valid (not expired).
Authenticating email with S/MIME in Amazon SES
加えて、受信側のメールクライアントが証明書の発行元 CA を信頼している必要もあります。
パブリック CA の証明書は多くのクライアントでデフォルト信頼されますが、プライベート CA はデフォルトでは信頼されないと書かれていました。
この要件を満たす証明書は、ACM のパブリック証明書発行機能では作れません。
ACM が発行するパブリック証明書はドメイン検証型で、識別するのはドメイン名だけだからです。
そのため、S/MIME 証明書を発行できる認証局(社内 CA や外部の S/MIME 証明書サービスなど)で用意した証明書を、ACM にインポートして使います。
今回は動作確認が目的なので、要件を満たす自己署名証明書を用意しました。
参考までに、私が使った証明書は次のように作成したものです。
openssl req -new -x509 -newkey rsa:2048 -nodes -days 365 \
-keyout smime-key.pem -out smime-cert.pem \
-subj "/CN=hoge@mail1.tak1wa.com" \
-addext "keyUsage=critical,digitalSignature,nonRepudiation" \
-addext "extendedKeyUsage=emailProtection" \
-addext "subjectAltName=email:hoge@mail1.tak1wa.com"
差出人アドレスを subjectAltName に入れ、extendedKeyUsage に emailProtection を指定しているのがポイントです。
これを ACM にインポートしたものが以下です。

証明書を送信アイデンティティに関連付け&設定セットで S/MIME 署名を有効化
用意した証明書を、SES の送信アイデンティティに関連付けます。
アイデンティティの「認証」タブに「E メール証明書」というセクションが追加されていました。
ここの「証明書をアタッチ」から紐付けます。

アタッチ画面では、差出人アドレスと ACM の証明書を選びます。
証明書の選択欄には、先ほどの要件を満たす証明書だけが候補として出てきました。

画面上部に前提条件が書かれています。
ID では DKIM が有効かつ検証済みである必要があります。証明書には、キー使用法 Email Protection と、SAN (サブジェクト代替名) に差出人アドレスが含まれている必要があります。1 つの E メールアドレスが保持できる証明書は 1 つです。
アイデンティティ側で DKIM が有効かつ検証済みであることも条件になっていました。
アタッチすると、ステータスが「有効」になりました。

署名を有効にするのは設定セット側です。
作成画面の「セキュリティで保護されたメッセージ」で S/MIME 署名を有効にできました。

有効化すると、設定セットの詳細画面にも反映されます。

署名付きでメールを送信する
署名まわりの指定は何もせず、この設定セットを指定して普通のテキストメールを送ります。
aws sesv2 send-email \
--from-email-address "hoge@mail1.tak1wa.com" \
--destination "ToAddresses=to@example.com" \
--configuration-set-name smime-signing-hoge \
--content '{"Simple":{"Subject":{"Data":"SES S/MIME signed mail"},"Body":{"Text":{"Data":"This mail is automatically S/MIME signed by Amazon SES."}}}}'
受信したメールのソースを見てみます。
テキストメールを送っただけなら、通常はメール全体が text/plain 一つになります。
今回は全体が multipart/signed に変わり、本文に加えて署名のパートが足された形になっていました。
Content-Type: multipart/signed; protocol="application/pkcs7-signature";
micalg=sha-256; boundary="----=_Part_xxxxx"
中身は 2 つのパートに分かれています。
1 つ目が送信したそのままの本文(text/plain)、2 つ目が署名データの smime.p7s です。
------=_Part_xxxxx
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 7bit
This mail is automatically S/MIME signed by Amazon SES.
------=_Part_xxxxx
Content-Type: application/pkcs7-signature; name=smime.p7s; smime-type=signed-data
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="smime.p7s"
Content-Description: S/MIME Cryptographic Signature
(base64 の署名データは省略)
------=_Part_xxxxx--
このように本文はそのまま残し、署名だけを別のパートとして添える形になっていました。
本文と署名が分かれているので、S/MIME に対応していない受信クライアントでも本文はそのまま読めます。
なお、この受信メールでは DKIM と DMARC の認証もどちらも通っていました。
本文の改ざんを検知する S/MIME 署名と、送信ドメインの正当性を示す DKIM / DMARC は別々の仕組みなので、両方が付いた状態で届きます。
証明書を関連付けていない送信元だと拒否される
この設定セットを、証明書が関連付いていない差出人アドレスで使うとどうなるかも試してみました。
$ aws sesv2 send-email \
--from-email-address "no-cert@example.com" \
--destination "ToAddresses=to@example.com" \
--configuration-set-name smime-signing-hoge \
--content '{"Simple":{"Subject":{"Data":"no cert"},"Body":{"Text":{"Data":"no cert"}}}}'
An error occurred (MessageRejected) when calling the SendEmail operation:
No active S/MIME certificate is associated with the sending identity.
送信自体が拒否されました。
S/MIME 署名を有効にした設定セットは、差出人アドレスにアクティブな証明書が関連付いていることが前提になります。
複数のアイデンティティで設定セットを共用している場合は、関連付け漏れに気をつけたいところです。
さいごに
本日は Amazon SES が S/MIME 署名に対応したので確認してみました。
証明書を ACM に置いてアイデンティティに関連付け、設定セットで有効にするだけで、これまで送信側で署名済み RAW を組み立てていた処理を SES に任せられます。
本文は署名とは別パートに残るので、S/MIME 非対応のクライアントでもそのまま読めます。







