openssl SMIME 和多部分消息

openssl SMIME and multipart messages

我需要从 bash 发送一封带有二进制附件的加密电子邮件。我已经阅读了 RFC、openssl 文档以及 SF 中的其他几篇文章,但均无济于事。

到目前为止我理解的过程是这样的:

  1. 创建 MIME 邮件
  2. 使用 openssl smime 对其进行加密,为信封生成额外的 headers。这应该用我自己的私钥签名,但用收件人的 public 密钥加密。
  3. 将此输出通过管道发送到 sendmail
  4. 接收方应该能够在 outlook 中解密整个内容。

但是我看到的是一些乱码。如果有人能指出我搞砸的地方,我将不胜感激。

以下是具体细节:

1. MIME 消息

From: <FROM>
To: <TO>
Subject: <SUBJECT>
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="<BOUNDARY>"

--<BOUNDARY>
Content-Type: text/plain; charset=utf-8

<TEXT>

--<BOUNDARY>
Content-Type: application/octet-stream
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
 filename= "<FILENAME>"

<BASE64_DATA>

--<BOUNDARY>

2。签名和加密:

SIGNED=$(openssl smime -sign -in mime.txt -signer MyPublic.cer -inkey MyPrivate.key)
ENCRYPTED=$(openssl smime -encrypt -subject "Work damn you" RecipientPublic.cer <<< $SIGNED)

3。发送

echo "$ENCRYPTED" | sendmail recipient@hush-hush.com

所以...血泪之后就完成了

经验教训:

  1. 此外 Content-Type: multipart/alternative; 应该是 Content-Type: multipart/mixed; 否则电子邮件客户端会混淆并显示垃圾。
  2. @dave_thompson_085 对遗漏的评论 - 最后是正确的。那是整个戏剧的一部分。 是任何会弄乱编码的时髦 word-wrapping(不要问我为什么)。
  3. 在 Bash 中,与在 real-life 中一样,引号很重要。所以 ENCRYPTED=$(openssl smime -encrypt -subject "Work damn you" RecipientPublic.cer <<< $SIGNED) 实际上应该是 ENCRYPTED=$(openssl smime -encrypt -subject "Work damn you" RecipientPublic.cer <<< "$SIGNED")
  4. Openssl 将负责封装适当的 headers,因此除了 -subject 标志外,无需在此处执行任何操作。