背景:我继承了一个基于 Linux 的嵌入式系统,其中包含 SMTP 代理和一些我必须忍受的古怪限制。它位于 SMTP 客户端和服务器之间。当 SMTP 客户端连接时,代理会打开与服务器的连接,并在进行一些即时处理后将客户端的数据传递到服务器。
挑战:我需要使用标准 PKI 技术和 S/MIME 格式对发送到服务器的电子邮件进行签名和/或加密(请参阅 RFC2311)。我可以从适当的证书访问所有必需的公钥。
古怪的限制(请接受它们,因为它们远远超出了我的控制范围):
- 我无法存储电子邮件;它必须即时处理。
- 我可以使用公钥在本地进行加密,但我无法直接访问私钥,这意味着数字签名必须由“签名设备”通过 9600bps 连接完成。
- 典型的电子邮件大小为数十或数百MB。 (电子邮件服务器和收件人可以处理这些大小;唯一的问题是签名时出现不可接受的延迟。)
- 任何新代码都应该采用 C 语言,但是可以接受,例如,将数据通过管道传输到只要不存储数据(例如没有临时文件),即可用于加密/签名的独立实用程序。
- 交货期为 14-21 天。
问题:
- 我希望找到一个开源实用程序或库,可以生成适当的 MIME 标头并加密/签署大量数据,但我在 Sourceforge、Google 代码上没有找到它, 等等您使用过可以推荐的产品吗?
- 我非常希望找到一个 RFC,其中表示可以接受对 100MB 数据进行哈希处理,然后对哈希值进行签名,因为这样可以缓解 9600bps 的瓶颈。但同样,没有运气。是否有与典型电子邮件客户端兼容的行业标准“快捷方式”(RFC?)?
谢谢你的想法。
Background: I've inherited an embedded linux-based system that contains an SMTP proxy and some wacky constraints that I just have to live with. It sits between an SMTP client and server. When an SMTP client connects, the proxy opens a connection to the server and passes the client's data to the server after some on-the-fly processing.
The challenge: I need to sign and/or encrypt the email on its way to the server using standard PKI techniques and S/MIME formats (see RFC2311, for example). I have access to all the required public keys from the appropriate certificates.
The wacky constraints (please just accept them, as they're far beyond my control):
- I can't store the email; it must be processed on-the-fly.
- I can do the encryption locally using the public keys, but I cannot access the private keys directly, which means the digital signature must be done by a "signing device" through a 9600bps connection.
- Typical email messages are tens or hundreds of MB in size. (The email server and recipients can handle those sizes; the only issue is the unacceptable delay when signing.)
- Any new code should be in C, but it's acceptable, for example, to pipe the data to a stand-alone utility for encryption/signature as long as the data is never stored (e.g. no temporary files).
- Delivery is in 14-21 days.
Questions:
- I was hoping to find an open-source utility or library that would generate the appropriate MIME headers and encrypt/sign a blob of data, but I didn't find that on Sourceforge, Google code, etc. Have you used one that you could recommend?
- I was desperately hoping to find an RFC that says it's acceptable to hash the 100MB of data and then sign the hash, as that would mitigate the 9600bps bottleneck. But again, no luck. Is there an industry-standard "shortcut" (RFC?) that would be compatible with typical email clients?
Thanks for your thoughts.
发布评论
评论(1)
问题 1:
OpenSSL 既是一个实用程序,又是一个库,可以创建和验证 S/MIME 消息(包括 MIME 标头)。有关实用程序版本的使用,请参阅 smime(1) 手册页 - 这都是构建的使用库版本,所以它也可以做到。
问题 2:
这不仅是可以接受的,而且也是 S/MIME 签名始终的完成方式。您可能会使用 multipart/signed 格式创建签名消息(请参阅 RFC2311< 的第 3.4.3 节/a>)。此多部分 MIME 类型包含作为具有 application/pkcs7-signature MIME 类型的对象的分离签名。第 3.4.3.1 节告诉我们,这包含一个 PKCS #7 签名数据对象。 RFC2315 中描述了 PKCS #7,第 9 节中描述了signedData 对象。部分告诉我们,我们创建要签名的消息的消息摘要(S/MIME 表示实现必须至少理解 MD5 和 SHA1 消息摘要,因此您可以使用 SHA1 作为具有最佳安全性的可互操作选项),并对其进行加密使用签名者的私钥。
只要签名设备愿意从您那里获取 SHA1 哈希值并使用签名者的私钥对其进行加密,那么您就可以自己完成其余的签名生成工作。
然后,您将获取多部分/签名的 MIME 对象并根据 S/MIME 规范对其进行加密,然后再次对整个蜡球进行签名(签名-加密-签名模式),以便最终您拥有:
附录:
OpenSSL 支持可插拔的加密“引擎”,可以代表库执行加密操作。实现此目的的最佳方法可能是为外部签名设备创建 OpenSSL 引擎,并在启用该引擎的情况下调用常规 S/MIME OpenSSL 函数。如果您的外部签名设备是“现成的”,则可能已经有 OpenSSL 的引擎包装器。
Question 1:
OpenSSL is both a utility and a library that can both create and verify S/MIME messages, including the MIME headers. See the smime(1) man page for usage of the utility version - this is all built using the library version, so it can do it too.
Question 2:
Not only is that acceptable, it's the way S/MIME signatures are always done. You will presumably be creating a signed message using the multipart/signed format (see section 3.4.3 of RFC2311). This multipart MIME type contains the detached signature as an object with a MIME type of application/pkcs7-signature. Section 3.4.3.1 tells us that this contains a PKCS #7 signedData object. PKCS #7 is described in RFC2315, and the signedData object is described in section 9. This section tells us that we create a message digest of the message to be signed (S/MIME says that implementations have to understand at least MD5 and SHA1 message digests, so you would use SHA1 as the interoperable option with best security), and encrypt it with the signer's private key.
As long as the signing device is happy to take a SHA1 hash from you and encrypt it with the signer's private key, then you can do all the rest of the signature generation yourself.
You'd then take the multipart/signed MIME object and encrypt it as per the S/MIME specs, and then sign the whole ball of wax again (Sign-Encrypt-Sign mode), so that ultimately you have:
Addendum:
OpenSSL supports pluggable cryptographic "engines" that can perform cryptographic operations on behalf of the library. The best way to implement this would probably be to create an OpenSSL engine for your external signing device, and just call the regular S/MIME OpenSSL functions with that engine enabled. If your external signing device is "off-the-shelf", there might already be OpenSSL an engine wrapper for it.