GoでSMTPを喋る
SMTPについて
SMTP
- 電子メールの送信時に使うプロトコル
- 通信内容が暗号化されず、平文のまま送信を行うため、盗聴されうる
通信内容を暗号化する方法はいくつかある
- SMTPS(SMTP over SSL/TLS)
- STARTTLS
SMTPS(SMTP over SSL/TLS)
- SMTPをSSL/TLSを用いて送信サーバーとSMTPサーバー間の通信を暗号化することを指す
- SMTPとは別のポートを用意する必要がある(465番であることが多い?)
- Amazon Simple Email Service(SES): 465
- SendGrid: 465
- Gmail: 465
STARTTLS
- 一度平文でSMTPサーバーに対して、STARTTLSに対応しているか確認を行うため、SMTPSへの対応の有無に関わらず柔軟にメールを送信することができる。
- 対応している場合: SMTPSで通信を行う(暗号化)
- 対応していない場合: SMTPで通信を行う(非暗号化)
- SMTPSとは違って専用のポートを用意する必要がない
メールを送信できることを重視するか、全ての通信が暗号化されていることを重視するかで、通信方法を選択すれば良さそう
SMTPS(SMTP over SSL/TLS)
TLSを使う方法は、TLSと同レイヤで動作するその他のプロトコルと同様であり、複数のTLSライブラリ実装でサポートされている。 TLSのSMTP拡張 (RFC 3207) で、クライアント(以下ではCとする)とサーバ(以下ではSとする)がセキュアなセッションを開始するまでのやりとりは、例えば次のようになる。
S: <TCPポート25番で接続要求を待つ>
C: <接続をオープンする>
S: 220 mail.example.org ESMTP service ready
C: EHLO client.example.org
S: 250-mail.example.org offers a warm hug of welcome
S: 250 STARTTLS
C: STARTTLS
S: 220 Go ahead
C: <TLSネゴシエーションを開始>
C & S: <TLSのネゴシエーション>
C & S: <ネゴシエーションの結果を確認>
C: EHLO client.example.org[注釈 1]
…
つまり、SMTPSにおいて送信側の手順は、
- TCP connection start
- EHLO
- STARTTLS(TLS Negotiationが行われる)
- TLS Negotiationの確認
- SMTP-AUTH(PLAIN, CRAM-MD5など)
- RCPT
- DATA
- QUIT
となりそう
6. AUTH PLAIN について(SMTP-AUTH)
- SMTP-AUTHでは、PLAIN, LOGIN, CRAM-MD5, DIGEST-MD5などといった認証メカニズムが使用される
- Goのnet/smtpでは、PLAINおよびCRAM-MD5がメソッドとしてサポートされている
- PLAIN は平文にてSMTPサーバーに対して、ユーザー名、パスワードを送信する
PLAINは、通常の平文による「[認可ID]<NULL>認証ID<NULL>パスワード」形式のユーザー認証方式である。Base64でエンコードする場合もあり、SSLなどによる暗号化の利用が前提になる。認可ID、認証IDは一般にはユーザー名を使用する。
- CRAM-MD5は、チャレンジ&レスポンス方式を用いたメカニズムであり、メッセージダイジェストとしてSMTPサーバーに対して、ユーザー名、パスワードを送信する
CRAMとは、Challenge-Response Authentication Mechanismの意味だ。接続先MTA(サーバ)からあらかじめ示された任意の文字列(Challenge)にクライアントがパスワードを含め、MD5アルゴリズムにより「メッセージダイジェスト」と呼ばれる一種のチェックサム値を取り出し、これをサーバへ送信する。サーバでも同様の検証をして、このメッセージダイジェストが等しければ、クライアントが正しいパスワードを知っている証拠だとして、ログインを許可する。この方法ではパスワード自身がネットワークに流れることがないので、安全性は高くなる。
引用元: https://atmarkit.itmedia.co.jp/ait/articles/0105/18/news002.html
つまり、md5計算コストを無視すれば、万が一SSLでの通信を解読されてもメッセージダイジェストとして送信するCRAM-MD5の方がセキュアだと言えそう