S/MIME 第 4 部分:通过 SparkPost 入站中继 Webhook 轻松收集收件人公钥

在这个系列中,我们已经看到,包含 S/MIME 签名是相当直接的。发送 S/MIME 加密邮件则更复杂,因为您需要获取收件人的公钥。当您使用像 Thunderbird 这样的电子邮件客户端时,这是一回事,但应用程序生成的电子邮件流又如何运作呢?

作者

类别

电子邮件

S/MIME 第 4 部分:通过 SparkPost 入站中继 Webhook 轻松收集收件人公钥

在这个系列中,我们已经看到,包含 S/MIME 签名是相当直接的。发送 S/MIME 加密邮件则更复杂,因为您需要获取收件人的公钥。当您使用像 Thunderbird 这样的电子邮件客户端时,这是一回事,但应用程序生成的电子邮件流又如何运作呢?

作者

类别

电子邮件

S/MIME 第 4 部分:通过 SparkPost 入站中继 Webhook 轻松收集收件人公钥

在这个系列中,我们已经看到,包含 S/MIME 签名是相当直接的。发送 S/MIME 加密邮件则更复杂,因为您需要获取收件人的公钥。当您使用像 Thunderbird 这样的电子邮件客户端时,这是一回事,但应用程序生成的电子邮件流又如何运作呢?

作者

类别

电子邮件

第 1 部分,我们快速浏览了 S/MIME,查看了在各种邮件客户端中对我们消息流的签名和加密。第 2 部分 带领我们使用简单的命令行工具对电子邮件进行签名和加密,然后通过 SparkPost 发送它们。第 3 部分展示了如何将安全邮件流注入到本地平台,例如 Port25 PowerMTAMomentum

在这个系列中,我们已经看到如何相对简单地包含 S/MIME 签名。发送 S/MIME 加密邮件则更复杂,因为您需要获得收件人的公钥。使用像 Thunderbird 这样的人类邮件客户端时,这是一回事 - 但应用生成的电子邮件流如何才能做到这一点呢?


但是,请稍等 - 还有另一种方式进入魔多以获取这些密钥。您的服务可以邀请客户(当然是通过电子邮件)向您发送一封签名邮件到已知的客户服务地址。借助 SparkPost 传入中继 Webhook 的神奇力量,我们将为您提取并存储该公钥以供使用。


我们可以简单总结一下这个用例:


  • 作为消息的接收者,我通过电子邮件向您的服务提供我的个人电子邮件签名,以便将来可以以 S/MIME 加密的形式发送电子邮件给我。


从中,我们得出一些更详细的要求:


  • 我们需要一个始终在线、可靠的传入电子邮件服务来接收这些签名电子邮件。

  • 邮件格式没有特殊要求,只要必须携带 S/MIME 签名即可。

  • 因为任何人都可以尝试向该服务发送邮件,因此应该的防御性设计,例如,拒绝坏演员发送的“欺骗”消息。需要有多层检查。

  • 如果一切检查都没问题,该服务将使用著名的纯文本隐私增强邮件(PEM)格式将证书存储在文件中。


还有一些非功能性要求:


  • 机器与机器之间的 Webhook 服务仅从内部发生的响应中很难看到。该服务应提供广泛的人类可读的应用程序级日志。特别是,证书解析和检查应该被记录。

  • 我们为应用程序内部添加测试用例,使用优秀的 Pytest 框架,并在使用与 GitHub 的 Travis CI 集成时,在 check-in 上自动运行这些测试。


好的 - 让我们开始吧!


1. 解决方案概述

这是整体解决方案的外观。


2. 安装、配置和启动 Web 应用

我们将从这一部分开始,这样我们在铺设传入中继 Webhook 之前就可以对其进行全面测试。


Web 应用与第 1 - 3 部分包含在同一 GitHub 项目 中,因此如果您已经跟随了这些部分,您已经拥有它。以下是新内容:


  • 程序 readSMIMEsig.py - 读取电子邮件并解析出中间和用户证书。

  • 程序 webapp.py - 用于 SparkPost 传入中继 Webhook 的简单 Flask 兼容 Web 应用。

  • webapp.ini - 上述程序的配置文件。配置文件使相同的值能够轻松传递到命令行和 Web 应用程序。


您需要确保您的主机具有正确的 TCP 端口号,以允许来自外部世界的传入请求,这样 SparkPost 就可以将消息 POST 给您的应用。如果您托管在 AWS EC2 上,例如,您需要配置您实例的 安全组


配置和启动 Web 应用的说明在 这里 - 这相当简单。要检查您的应用是否正在运行并可以从外部世界访问,您可以使用 curl 从其他主机发送(空白)请求,例如:

curl -X POST https://app.trymsys.net:8855/

您应该看到如下响应:

{"message":"请求头中的未知 Content-Type"}

这是一件好事情 - 您的应用正在运行!


在您的主机的 webapp.log 中,您将看到类似于以下内容的输出:

2019-01-15 00:11:07,575,root,INFO,来自 38.96.5.10 的请求,scheme=https,path=/ 2019-01-15 00:11:07,575,root,INFO,| len(headers)=3,len(body)=None 2019-01-15 00:11:07,575,root,INFO,| 未知的内容类型:无


为了帮助您立即在应用程序中玩弄真实数据,您可以从项目仓库导入这个特定的 Postman 请求。这模拟了您的 SparkPost 帐户将要做的事情,即它发送一个包含特定有效证书(属于我的测试帐户)的电子邮件的 https POST 到您的应用。


您只需将请求中的目标地址(在灰色框中)更改为与您的安装匹配。如果您在 webapp.ini 中更改了 token 值,请调整 Postman 中的头部值以匹配。


如果您的应用工作正常,您将看到 Postman 中的“200 OK”响应。您的主机 webapp.log 文件将包含如下输出:

2019-01-15 00:11:48,554,root,INFO,来自 38.96.5.10 的请求,scheme=https,path=/ 2019-01-15 00:11:48,554,root,INFO,| len(headers)=10,len(body)=14778 2019-01-15 00:11:48,555,root,INFO,| msg_from=bob.lumreeker@gmail.com,rcpt_to=secureme@inbound.thetucks.com,len(email_rfc822)=9223 2019-01-15 00:11:48,599,root,INFO,| from=bob.lumreeker@gmail.com,DKIM 通过 2019-01-15 00:11:48,600,root,INFO,| content-type=multipart/signed; protocol="application/pkcs7-signature"; micalg=sha-256; boundary="------------ms010908020707040304020406",content-description=None 2019-01-15 00:11:48,600,root,INFO,| content-type=text/plain; charset=utf-8; format=flowed,content-description=None 2019-01-15 00:11:48,600,root,INFO,| content-type=application/pkcs7-signature; name="smime.p7s",content-description=S/MIME 加密签名 2019-01-15 00:11:48,600,root,INFO,| filename=smime.p7s,bytes=3998 2019-01-15 00:11:48,601,root,INFO,| 证书:主题 email_address=['bob.lumreeker@gmail.com'],not_valid_before=2018-10-03 00:00:00,not_valid_after=2019-10-03 23:59:59,hash_algorithm=sha256,key_size=2048 bytes, issuer={'countryName': 'GB', 'stateOrProvinceName': 'Greater Manchester', 'localityName': 'Salford', 'organizationName': 'COMODO CA Limited', 'commonName': 'COMODO RSA Client Authentication and Secure Email CA'} 2019-01-15 00:11:48,602,root,INFO,| 证书:主题 email_address=[],not_valid_before=2013-01-10 00:00:00,not_valid_after=2028-01-09 23:59:59,hash_algorithm=sha384,key_size=2048 bytes, issuer={'countryName': 'GB', 'stateOrProvinceName': 'Greater Manchester', 'localityName': 'Salford', 'organizationName': 'COMODO CA Limited', 'commonName': 'COMODO RSA Certification Authority'} 2019-01-15 00:11:48,616,root,INFO,| 写入文件 ./bob.lumreeker@gmail.com.crt,bytes=1870,ok=True


为了快速检查最后一行 - 如果它显示“写入文件”,那么您就可以了。其余部分是展示 DKIM 检查和证书验证过程。


3. SparkPost 传入中继 Webhook 设置

首先,我们选择一个域作为我们的传入消息地址 -  在这里,它将是 inbound.thetucks.com。请按照本指南设置您的域。以下是我详细使用的步骤:


3.1 添加 MX 记录

您需要访问您特定的互联网服务提供商账户。完成后,您可以使用 dig 检查它们 - 这是我域的命令。

dig +short MX inbound.thetucks.com

您应该看到:

10 rx3.sparkpostmail.com. 10 rx1.sparkpostmail.com. 10 rx2.sparkpostmail.com.


3.2 创建传入域

使用 SparkPost Postman API 集合,选择传入域 / 创建.. 调用。POST 请求的主体包含您的域,例如:

{    "domain": "inbound.thetucks.com" }


3.3 创建 Relay Webhook

使用相关的 Postman 调用创建传入中继 Webhook。对于我的情况,消息主体包含:

{ "name": "证书收集 Webhook", "target": "https://app.trymsys.net:8855/", "auth_token": "t0p s3cr3t t0k3n", "match": { "protocol": "SMTP", "domain": "inbound.thetucks.com" } }

如前所述,我建议 设置一个 auth_token 为您自己的秘密值,如在主机上的 webapp.ini 文件中设置的那样。

您的“目标”值需要与您将要托管 Web 应用的主机地址和 TCP 端口匹配。

您的“域”值需要与第 1 步设置的 MX 记录匹配。



就这样!管道已经完成。您现在应该能够向您的传入地址发送证书,它们将被处理并显示在您的 Web 应用程序主机上 - 在这种情况下,一个名为 bob.lumreeker@gmail.com.crt 的文件。

现在您可以使用第 2 和第 3 部分中描述的工具向 Bob 发送加密电子邮件。

您可以使用以下命令检查证书的内容:

openssl x509 -inform PEM -in bob.lumreeker\@gmail.com.crt -text -noout


4. 内部:DKIM 检查、证书验证

应用程序检查接收到的电子邮件是否具有有效的 DKIM,并检查证书本身是否有效,如此处所述。还有实现说明和进一步工作的想法。


总结……

我们已经看到如何通过向传入中继 Webhook 地址发送电子邮件轻松收集收件人的公钥。一旦完成,这些收件人就可以以 S/MIME 加密形式接收他们的消息。

这就是目前的所有内容!祝发送愉快。

Sign up

为营销、支持和财务提供的人工智能驱动平台

点击 "获取演示" 即表示您同意 Bird's

Sign up

为营销、支持和财务提供的人工智能驱动平台

点击 "获取演示" 即表示您同意 Bird's

Sign up

为营销、支持和财务提供的人工智能驱动平台

点击 "获取演示" 即表示您同意 Bird's

Channels

Grow

Engage

Automate

APIs

Resources

Company

Socials

生长

管理

自动化

生长

管理

自动化