在这一版中,我们将会:
安装一些简单的命令行工具来签署和加密电子邮件
获取您的发件人密钥/证书以进行签署
通过 SparkPost 发送一封签名的消息,并查看收到的消息
可选:获取收件人证书以进行加密
通过 SparkPost 发送一封已签名和加密的消息,并查看收到的消息
尝试一个方便的独立工具“mimeshow”来查看电子邮件文件内部。
好的 – 让我们开始吧!
1. 安装工具
演示工具在 GitHub 这里,附带安装说明。您可能会注意到“构建通过”标志 – Travis 和 pytest 会自动检查构建状态。请注意,这些工具并没有受到 SparkPost 的官方支持,但我已经努力使它们健壮且易于使用。
如果您对 Python 和 pip 有一些了解,安装应该感觉相当熟悉。Pipfile 会自动处理外部依赖项。一旦完成,您可以通过运行以下命令检查所有内容是否已安装:
./sparkpostSMIME.py -h
您应该会看到友好的帮助文本。接下来,我们需要……
2. 获取您的发件人密钥/证书以进行签署
如果您已经拥有用于发送身份的密钥文件,您可以跳过。否则,这里有两个选项供选择:
a) 自签名测试密钥/证书(不具有外部有效性)
如果您只是测试,可以使用 Linux 上的命令行工具 openssl 为电子邮件地址生成“自签名”证书和密钥,遵循 此过程。在该过程结束时,您将拥有一个 smime.p12 文件。将此文件重命名以匹配您的发送身份,包括 @ 符号,例如,alice@example.com.p12 。
或者
b) 具有外部有效性的密钥/证书
如果您想获得能够签署的外部有效密钥/证书,可以从提供商列表中选择 这里。我发现 Comodo 工作良好(非商业用途免费),而且比上面的自签程序更简单。遵循注册流程,接收您的验证邮件,确保在 Firefox 中打开链接。转到 Firefox 首选项/隐私和安全。滚动到证书/查看证书:
选择您的证书,并使用“备份”选项将其保存为 PKCS12 格式的文件(在文件名后添加文件扩展名 .p12),其中包含私钥和公有证书链。
提供一个密码以保护 .p12 文件:
生成单独的公有(.crt)和私有(.pem)密钥文件
无论您使用 a) 还是 b),现在您将拥有一个 .p12 文件,用于您的发件人身份。这是一个重要的进步 – 现在去拿杯咖啡吧!
现在我们需要生成像这样的单独公有和私有密钥文件 – 替换为您自己的电子邮件地址。 (Mac OSX 和 Linux):
openssl pkcs12 -in alice\@example.com.p12 -clcerts -nokeys -out alice\@example.com.crt openssl pkcs12 -in alice\@example.com.p12 -nocerts -nodes -out alice\@example.com.pem
您需要输入之前提供的密码。请注意,这些反斜杠 \ 用于转义 @ 符号 – 不是分隔目录路径的名称(在 Mac OSX 和 Linux 上,用正斜杠 / 分隔)。
如果您使用 Windows,有一些 openssl 实现可用,例如内置在 Git 命令行工具 中的 MINGW64,不过我发现它通常会锁定。您可能会发现更容易更快地在 Linux 上完成此操作,然后将文件复制过来。那些相同的 Git 工具在 Windows 上带有一个很好的 ssh 客户端,您可以用它登录到 Linux 机器,例如 Amazon EC2 实例。
2.1 签名消息
在 tests 目录中已经有一个 dummy 密钥/证书以及邮箱源文件用于 alice@example.com,因此即使您没有自己的密钥,也可以得到一些输出。只需键入以下内容:
cd tests ../sparkpostSMIME.py example_email1.eml --sign
您将得到:
收件人: Bob <bob@example.com> 发件人: Alice <alice@example.com> 主题: 一条消息 MIME-Version: 1.0 Content-Type: application/x-pkcs7-mime; smime-type=signed-data; name="smime.p7m" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7m" MIIKXAYJKoZIhvcNAQcCoIIKTTCCCkkCAQExDzANBglghkgBZQMEAgEFADCCAQoGCSqGSIb3DQEH AaCB/ASB+VRvOiBCb2IgPGJvYkBleGFtcGxlLmNvbT4NCkZyb206IEFsaWNlIDxhbGljZUBleGFt : :
您无法通过 SparkPost 从 example.com 发送电子邮件,除非您拥有该域,因此下一步是使用您自己的密钥并从您自己的域发送一条已签名的消息。
3. 通过 SparkPost 发送签名消息
现在,让我们使用一个真正的发送域,根据 SparkPost 新用户指南 设置。我们在当前目录中拥有发送者证书和密钥文件:
steve@thetucks.com.crt steve@thetucks.com.pem
文件 tests/declaration.eml 包含在项目中。它只是一个文本文件,因此您可以自定义发件人:地址以适应您自己的发送域,并且收件人:地址以适应您的测试收件人。文件的开头看起来像这样:
收件人: Bob <bob.lumreeker@gmail.com> 发件人: Steve <steve@thetucks.com> 主题: 这是我们的声明 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Content-Language: en-GB 当人类事件的进程变得必要时……
设置您的 API 密钥:
export SPARKPOST_API_KEY=<<在这里输入您的 API 密钥>>
发送电子邮件:
./sparkpostSMIME.py tests/declaration.eml --sign --send_api
你会看到:
打开到 https://api.sparkpost.com/api/v1 的连接 发送 tests/declaration.eml 发件人: Steve <steve@thetucks.com> 收件人: Bob <bob.lumreeker@gmail.com> OK - 在 1.15 秒内
一秒钟后,该电子邮件就会到达 Bob 的收件箱。Thunderbird 在信封上显示一个红点,表示有效的发件人签名。
成功!喝完那杯咖啡,您应得的。如果您遇到问题,请检查电子邮件文件中的发件人地址是否与您的 .crt 和 .pem 文件的名称匹配。
4. 加密消息
要加密一条消息,您需要接收者的公钥证书。这是一个看起来像这样的文本文件:
袋属性 friendlyName: s COMODO CA Limited ID #2 localKeyID: 32 84 AB 9C 56 5C 80 C6 89 4D 40 46 DD D4 7C 71 E8 CD ED C1 subject=/emailAddress=bob.lumreeker@gmail.com issuer=/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Client Authentication 和安全电子邮件 CA -----BEGIN CERTIFICATE----- 这里看起来像随机字符 -----END CERTIFICATE-----
tests 目录中有一个 dummy 收件人证书用于 bob@example.com,因此您可以在拥有真实证书之前进行练习:
cd tests ../sparkpostSMIME.py example_email1.eml --sign --encrypt
您将看到:
收件人: Bob <bob@example.com> 发件人: Alice <alice@example.com> 主题: 一条消息 MIME-Version: 1.0 Content-Type: application/pkcs7-mime; smime-type=enveloped-data; name=smime.p7m Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename=smime.p7m MIIRwQYJKoZIhvcNAQcDoIIRsjCCEa4CAQAxggKlMIICoQIBADCBijCBhDELMAkG :
您会注意到输出的长度远远长于加密消息,因为它除了加密的消息本身外,还携带了很多 额外信息。
4.1 通过 SparkPost 发送加密的签名消息
让我们向一个真实的电子邮件地址发送加密消息。您可以按照与之前相同的过程(自签名或提供商如 Comodo)获取您自己的收件人地址的公钥/证书。您只需要 .crt 文件 – 收件人不需要给您他们的私钥(.p12 和 .pem 文件)。
我有文件 bob.lumreeker@gmail.com.crt 作为我的目标收件人 – 匹配我文件中的发件人地址。
这是发送的命令:
./sparkpostSMIME.py tests/declaration.eml --sign --encrypt --send_api
我看到:
打开到 https://api.sparkpost.com/api/v1 的连接 发送 tests/declaration.eml 发件人: Steve <steve@thetucks.com> 收件人: Bob <bob.lumreeker@gmail.com> OK - 在 1.168 秒内
邮件在 Thunderbird 中显示“红点”签名图标和“锁”加密图标。
您可以轻松发送复杂的基于 HTML 的电子邮件,包括链接和图像,如第一部分中所示。一些客户端(如 Thunderbird)在加密的 S/MIME 消息中会要求权限来显示外部链接和图像,但仅签名的消息在包括 Thunderbird 和 Gmail 的客户端中显示良好:
请注意下拉菜单显示“已验证电子邮件地址”。
进一步思考与需要注意的事项
此工具采取了一种超级简单的方法来提取必要的密钥 – 它仅查找当前目录中的命名文件。可以轻松添加更复杂的安排,例如将所有密钥保存在数据库中,但我希望代码尽可能简单。
您可以使用 Cc:和 Bcc:添加其他收件人,它们将被投递;这可能对归档目的有用。已签名的消息可以由其他收件人接收并完整显示,包括签名。该工具从已投递的消息中删除 Bcc:标头(就像桌面邮件客户端所做的那样)。
为确保消息在 SparkPost 中保持不变(这可能会破坏签名),该工具设置 API 选项为“事务性”邮件,并禁用打开和点击追踪。
如果您使用加密,请记住,该工具会提取单个收件人地址。只有当其他收件人拥有目标收件人的私钥时,他们才可以解码消息体。如果您仅使用次要收件人作为交付记录,那可能没问题。
已签名、已密封交付……我属于你
这就是我们如何通过 SparkPost 签署、密封和交付 S/MIME 消息的快速概述。温馨提醒:演示项目在 GitHub 这里,我努力使其易于安装和使用。
附加功能:使用“mimeshow”显示 MIME 部件
RFC822 MIME 多部分文件内部结构对于人类来说是相当复杂的。该项目包括一个独立工具,使其更容易,称为 mimeshow。
这可以处理您拥有的任何电子邮件文件(不仅限于 S/MIME 文件),并显示内部结构。以下是一个示例:
./mimeshow.py testcases/img_and_attachment.eml
您将看到:
收件人 Bob <bob.lumreeker@gmail.com> 发件人 Steve <steve@thetucks.com> 主题 测试附件等 MIME-Version 1.0 Content-Type multipart/mixed; boundary="------------7D48652042860D0098C65210" Content-Language en-GB Content-Type multipart/alternative; boundary="------------58C0BF87598336550D70EB95" Content-Type text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding 7bit Content-Transfer-Encoding quoted-printable Content-Type text/html; charset="utf-8" Content-Type application/pdf; name="sparkpost-datasheet-tam-technical-account-management.pdf" Content-Transfer-Encoding base64 Content-Disposition attachment; filename="sparkpost-datasheet-tam-technical-account-management.pdf"
您还可以用作过滤器以提供 sparkpostSMIME 输出的可读摘要:
./sparkpostSMIME.py tests/declaration.eml --sign --encrypt | ./mimeshow.py
您将看到:
收件人 Bob <bob.lumreeker@gmail.com> 发件人 Steve <steve@thetucks.com> 主题 这是我们的声明 Content-Language en-GB MIME-Version 1.0 Content-Type application/pkcs7-mime; smime-type=enveloped-data; name=smime.p7m Content-Transfer-Encoding base64 Content-Disposition attachment; filename=smime.p7m
最后……
回顾一下 – 我们安装了一些简单的命令行工具来签署和加密电子邮件(GitHub 仓库在 这里,附带安装说明)。
我们获得了用于签署的发件人密钥/证书,并通过 SparkPost 发送了一条签名的消息。我们获得了用于加密的收件人证书,然后通过 SparkPost 发送了一条已签名和加密的消息。
最后,我们尝试了方便的独立工具“mimeshow”来查看电子邮件文件内部。
就这些了!再见!