Product

解决方案

资源

Company

Product

解决方案

资源

Company

S/MIME 第 2 部分:通过 SparkPost 签名、密封和交付

2018年12月31日

电子邮件

1 min read

S/MIME 第 2 部分:通过 SparkPost 签名、密封和交付

在第一部分中,我们快速介绍了 S/MIME,查看了在一系列邮件客户端中对我们消息流的签名和加密。S/MIME 消息可以被签名(提供发件人身份的证明)、加密(保持消息内容的秘密)或两者兼而有之。

Diagram illustrating email security layers showing the relationship between S/MIME signing, S/MIME encryption, and TLS connections in the email delivery process from message source through email server to recipient.

在本期中,我们将:

  • 安装一些用于签名和加密电子邮件的简单命令行工具

  • 获取您的发件人密钥/证书以进行签名

  • 通过SparkPost发送签名消息,并查看接收到的消息

  • (可选)获取您的收件人证书以进行加密

  • 通过SparkPost发送签名和加密的消息,并查看接收到的消息

  • 尝试一个方便的独立工具“mimeshow”查看电子邮件文件内部结构。

好的——让我们开始吧!

1. 安装工具

示范工具可在GitHub上获取,附有安装说明。您可能会注意到“build passing”标志——Travispytest自动检查构建状态。请注意,这些工具不是SparkPost正式支持的,但我已经尝试让它们坚固且易于使用。

如果您对Python和pip有一些了解,安装过程应该会相当熟悉。Pipfile会自动为您处理外部依赖项。一旦完成,您可以通过运行检查一切是否安装好

./sparkpostSMIME.py -h

您应该看到友好的帮助文本。接下来,我们需要…

2. 获取您的发件人密钥/证书以进行签名

如果您已经拥有用于发送身份的密钥文件,可以跳到下一步。否则,这里有两个选项可供选择:

a) 自签名测试密钥/证书(不外部有效)

如果您只是测试,可以使用Linux上的命令行工具openssl,为电子邮件地址制作“自签名”证书和密钥,遵循类似此过程的步骤。过程结束后,您将获得一个smime.p12文件。重命名此文件以匹配您的发送身份,包括@符号,例如,alice@example.com.p12。

b) 外部有效的密钥/证书

如果您希望获得允许您签名的外部有效密钥/证书,这里有一个提供商列表这里。我发现Comodo效果很好(非商业用途免费),而且比上述自签名过程更简单。按照注册流程,接收验证邮件,并确保在Firefox中打开链接。前往Firefox首选项/隐私和安全。滚动到证书/查看证书:

Firefox browser settings page showing certificate management options under the Privacy & Security section, with controls for how the browser handles personal certificate requests.


选择您的证书,并使用“备份”选项以PKCS12格式保存为文件(在文件名中添加扩展名.p12),该格式包含私钥和公共证书链。

Certificate Manager window showing a list of software security device certificates from COMODO CA Limited, with details including certificate names and serial numbers


提供一个密码以保护.p12文件:

Certificate backup password entry dialog with password fields and strength meter


生成单独的公共(.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,有openssll实现可用,比如内置于Git命令行工具中的MINGW64,但我发现它容易锁住。您可能会发现这样做在Linux上更容易、更快捷,然后再将文件复制过来。Windows的同样Git工具带有一个很好的ssh客户端,您可以使用它登录到Linux机器,例如Amazon EC2实例。


2.1 签署邮件

在测试目录中已经有适用于alice@example.com的虚拟密钥/证书和邮件源文件,所以即便在拥有自己的密钥之前,您也可以获得一些输出。只需输入以下内容:

cd tests ../sparkpostSMIME.py example_email1.eml --sign

然后您将得到:

To: Bob <bob@example.com> 
From: Alice <alice@example.com> 
Subject: A message 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发送电子邮件,除非您拥有该域名,因此下一步是使用您自己的密钥,从您自己的域发送签名消息。

如果您已经拥有用于发送身份的密钥文件,可以跳到下一步。否则,这里有两个选项可供选择:

a) 自签名测试密钥/证书(不外部有效)

如果您只是测试,可以使用Linux上的命令行工具openssl,为电子邮件地址制作“自签名”证书和密钥,遵循类似此过程的步骤。过程结束后,您将获得一个smime.p12文件。重命名此文件以匹配您的发送身份,包括@符号,例如,alice@example.com.p12。

b) 外部有效的密钥/证书

如果您希望获得允许您签名的外部有效密钥/证书,这里有一个提供商列表这里。我发现Comodo效果很好(非商业用途免费),而且比上述自签名过程更简单。按照注册流程,接收验证邮件,并确保在Firefox中打开链接。前往Firefox首选项/隐私和安全。滚动到证书/查看证书:

Firefox browser settings page showing certificate management options under the Privacy & Security section, with controls for how the browser handles personal certificate requests.


选择您的证书,并使用“备份”选项以PKCS12格式保存为文件(在文件名中添加扩展名.p12),该格式包含私钥和公共证书链。

Certificate Manager window showing a list of software security device certificates from COMODO CA Limited, with details including certificate names and serial numbers


提供一个密码以保护.p12文件:

Certificate backup password entry dialog with password fields and strength meter


生成单独的公共(.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,有openssll实现可用,比如内置于Git命令行工具中的MINGW64,但我发现它容易锁住。您可能会发现这样做在Linux上更容易、更快捷,然后再将文件复制过来。Windows的同样Git工具带有一个很好的ssh客户端,您可以使用它登录到Linux机器,例如Amazon EC2实例。


2.1 签署邮件

在测试目录中已经有适用于alice@example.com的虚拟密钥/证书和邮件源文件,所以即便在拥有自己的密钥之前,您也可以获得一些输出。只需输入以下内容:

cd tests ../sparkpostSMIME.py example_email1.eml --sign

然后您将得到:

To: Bob <bob@example.com> 
From: Alice <alice@example.com> 
Subject: A message 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发送电子邮件,除非您拥有该域名,因此下一步是使用您自己的密钥,从您自己的域发送签名消息。

如果您已经拥有用于发送身份的密钥文件,可以跳到下一步。否则,这里有两个选项可供选择:

a) 自签名测试密钥/证书(不外部有效)

如果您只是测试,可以使用Linux上的命令行工具openssl,为电子邮件地址制作“自签名”证书和密钥,遵循类似此过程的步骤。过程结束后,您将获得一个smime.p12文件。重命名此文件以匹配您的发送身份,包括@符号,例如,alice@example.com.p12。

b) 外部有效的密钥/证书

如果您希望获得允许您签名的外部有效密钥/证书,这里有一个提供商列表这里。我发现Comodo效果很好(非商业用途免费),而且比上述自签名过程更简单。按照注册流程,接收验证邮件,并确保在Firefox中打开链接。前往Firefox首选项/隐私和安全。滚动到证书/查看证书:

Firefox browser settings page showing certificate management options under the Privacy & Security section, with controls for how the browser handles personal certificate requests.


选择您的证书,并使用“备份”选项以PKCS12格式保存为文件(在文件名中添加扩展名.p12),该格式包含私钥和公共证书链。

Certificate Manager window showing a list of software security device certificates from COMODO CA Limited, with details including certificate names and serial numbers


提供一个密码以保护.p12文件:

Certificate backup password entry dialog with password fields and strength meter


生成单独的公共(.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,有openssll实现可用,比如内置于Git命令行工具中的MINGW64,但我发现它容易锁住。您可能会发现这样做在Linux上更容易、更快捷,然后再将文件复制过来。Windows的同样Git工具带有一个很好的ssh客户端,您可以使用它登录到Linux机器,例如Amazon EC2实例。


2.1 签署邮件

在测试目录中已经有适用于alice@example.com的虚拟密钥/证书和邮件源文件,所以即便在拥有自己的密钥之前,您也可以获得一些输出。只需输入以下内容:

cd tests ../sparkpostSMIME.py example_email1.eml --sign

然后您将得到:

To: Bob <bob@example.com> 
From: Alice <alice@example.com> 
Subject: A message 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 New User Guide 的指导进行设置。我们在当前目录中有发送者证书和密钥文件:

steve@thetucks.com.crt steve@thetucks.com.pem

文件 tests/declaration.eml 包含在项目中。它只是一个文本文件,因此您可以自定义 From: 地址以适应您自己的发送域,并自定义 To: 地址以适应您的测试接收者。文件的开头如下所示:

To: Bob <bob.lumreeker@gmail.com> From: Steve <steve@thetucks.com> Subject: Here is our declaration 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=<<Put your API key here>

发送电子邮件:

./sparkpostSMIME.py tests/declaration.eml --sign --send_api

您会看到:

已打开到 https://api.sparkpost.com/api/v1 的连接 发送 tests/declaration.eml From: Steve <steve@thetucks.com> To: Bob  <bob.lumreeker@gmail.com> OK - 在 1.15 秒内

大约一秒钟后,电子邮件到达 Bob 的收件箱。Thunderbird 用信封上的红点显示它,表示有效的发送者签名。

Thunderbird email inbox showing an email with a subject 'Here is our declaration'

成功!喝完那杯咖啡,你值得拥有。如果您遇到困难,请检查电子邮件文件中的 From: 地址是否与您的 .crt 和 .pem 文件名称匹配。

4. 加密消息

要加密消息,您需要收件人的公钥以证书形式。这是一个文本文件,看起来像这样:

Bag Attributes   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 and Secure Email CA -----BEGIN CERTIFICATE-----这里看起来像是随机字符-----END CERTIFICATE-----

在tests目录中有一个为bob@example.com的虚拟收件人证书,因此您可以在拥有真实证书之前进行练习:

cd tests ../sparkpostSMIME.py example_email1.eml --sign --encrypt

您将看到:

To: Bob <bob@example.com>
From: Alice <alice@example.com> 
Subject: A message 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,与我文件中的From:地址相匹配。

以下是发送的命令:

./sparkpostSMIME.py tests/declaration.eml --sign --encrypt --send_api

我看到:

Opened connection to https://api.sparkpost.com/api/v1 Sending tests/declaration.eml From: Steve <steve@thetucks.com> To: Bob <bob.lumreeker@gmail.com> OK - in 1.168 seconds

邮件在Thunderbird中显示,带有“红点”签名图标和“挂锁”加密图标。

Thunderbird email view with signature and encryption icons

您可以像在第1部分中显示的那样轻松发送带有链接和图片的复杂HTML电子邮件。某些客户端(如Thunderbird)请求许可以显示加密S/MIME消息中的外部链接和图片,但仅签名消息在包括Thunderbird和Gmail在内的客户端中显示良好:

Avocado marketing email with guacamole in a blue bowl and product order sectionsGmail interface showing an HTML email with guacamole image and Avocado marketing content

注意下拉菜单显示“已验证的电子邮件地址”。

进一步的想法和需要注意的事项

这个工具采用了超简单的方法来拉取必要的密钥——它只是在当前目录中查找命名文件。更复杂的安排,例如将所有密钥保存在数据库中,可以很容易地添加,但我希望代码尽可能简单。

您可以包含其他收件人使用 Cc: 和 Bcc:,他们将会收到邮件;这对归档目的可能很有用。签名的邮件会被接收,其他收件人可以连同签名一起展示。工具会从已发送的邮件中去掉 Bcc: 标头(就像桌面邮件客户端一样)。

为了确保邮件通过 SparkPost 时不被更改(这可能会破坏签名),工具设置了 “transactional” 邮寄的 API 选项,并禁用了打开和点击跟踪。

如果您使用加密,请记住,该工具会为此提取单一的 To: 地址。只有当其他收件人拥有 To: 收件人的私钥时,才能解码邮件正文。如果您只是使用次要收件人作为发送记录,例如,那可能也是可以的。

签好、封好、送达...I’m yours

这是我们关于如何通过SparkPost签署、封装和传递S/MIME消息的快速概述。快速提醒:演示项目可在GitHub上获得, 我已尽力使其易于安装和使用。

额外功能:使用“mimeshow”显示MIME部分

RFC822 MIME多部分文件的内部结构对人类来说相当复杂。项目包括一个独立工具,称为mimeshow,以简化这一过程。

这可以处理您拥有的任何电子邮件文件(不仅仅是S/MIME文件)并显示内部结构。这是一个例子:

./mimeshow.py testcases/img_and_attachment.eml

您将看到:

To Bob <bob.lumreeker@gmail.com>
From Steve <steve@thetucks.com> 
Subject Testing attachments etc 
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


您将看到:

To Bob <bob.lumreeker@gmail.com>  
From Steve <steve@thetucks.com>
Subject Here is our declaration 
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 repo 包括完整的安装说明)。

我们获得了用于签署的发件人密钥/证书,并通过 SparkPost 发送了签名消息。我们获得了用于加密的收件人证书,然后通过 SparkPost 发送了一封签名和加密的消息。

最后,我们尝试了方便的独立工具“mimeshow”来查看电子邮件文件内部。

就这样了!在我们的下一期内容中,我们将向您展示如何将这些 S/MIME 功能扩展到 本地安全电子邮件平台,如 PowerMTA 和 Momentum。再见!

其他新闻

阅读更多来自此类别的内容

A person is standing at a desk while typing on a laptop.

这个完整的AI原生平台可以随着您的业务进行扩展。

Product

解决方案

资源

社交

Newsletter

通过每周更新到您的收件箱,随时了解 Bird 的最新动态。

Signup

© 2025 Bird

A person is standing at a desk while typing on a laptop.

这个完整的AI原生平台可以随着您的业务进行扩展。

Product

解决方案

资源

社交

Newsletter

通过每周更新到您的收件箱,随时了解 Bird 的最新动态。

Signup

© 2025 Bird