OpenSSL

密码学和 SSL/TLS 工具包

openssl-smime

名称

openssl-smime - S/MIME 命令

概要

openssl smime [-help] [-encrypt] [-decrypt] [-sign] [-resign] [-verify] [-pk7out] [-binary] [-crlfeol] [-cipher] [-in file] [-certfile file] [-signer file] [-nointern] [-noverify] [-nochain] [-nosigs] [-nocerts] [-noattr] [-nodetach] [-nosmimecap] [-recip file] [-inform DER|PEM|SMIME] [-outform DER|PEM|SMIME] [-keyform DER|PEM|P12|ENGINE] [-passin arg] [-inkey filename|uri] [-out file] [-content file] [-to addr] [-from ad] [-subject s] [-text] [-indef] [-noindef] [-stream] [-md digest] [-CAfile file] [-no-CAfile] [-CApath dir] [-no-CApath] [-CAstore uri] [-no-CAstore] [-engine id] [-rand files] [-writerand file] [-allow_proxy_certs] [-attime timestamp] [-no_check_time] [-check_ss_sig] [-crl_check] [-crl_check_all] [-explicit_policy] [-extended_crl] [-ignore_critical] [-inhibit_any] [-inhibit_map] [-partial_chain] [-policy arg] [-policy_check] [-policy_print] [-purpose purpose] [-suiteB_128] [-suiteB_128_only] [-suiteB_192] [-trusted_first] [-no_alt_chains] [-use_deltas] [-auth_level num] [-verify_depth num] [-verify_email email] [-verify_hostname hostname] [-verify_ip ip] [-verify_name name] [-x509_strict] [-issuer_checks] [-provider name] [-provider-path path] [-propquery propq] [-config configfile] recipcert ...

描述

此命令处理 S/MIME 邮件。它可以加密、解密、签名和验证 S/MIME 消息。

选项

有六个操作选项来设置要执行的操作类型:-encrypt-decrypt-sign-resign-verify-pk7out。这些选项是互斥的。其他选项的含义取决于操作类型。

-help

打印使用信息。

-encrypt

使用给定的收件人证书加密邮件。输入文件是要加密的消息。输出文件是 MIME 格式的加密邮件。

请注意,不会对收件人证书进行吊销检查,因此,如果该密钥遭到泄露,其他人可能能够解密文本。

-decrypt

使用提供的证书和私钥解密邮件。需要一个 MIME 格式的加密邮件消息作为输入文件。解密后的邮件将写入输出文件。

-sign

使用提供的证书和私钥签名邮件。输入文件是要签名的消息。签名的 MIME 格式消息将写入输出文件。

-resign

重新签名消息:获取现有消息和一个或多个新签名者。

-verify

验证签名的邮件。需要一个签名的邮件消息作为输入,并输出签名数据。支持明文签名和不透明签名。

-pk7out

获取输入消息并输出一个 PEM 编码的 PKCS#7 结构。

-in filename

要加密或签名的输入消息,或要解密或验证的 MIME 消息。

-out filename

已解密或验证的消息文本,或已签名或验证的输出 MIME 格式消息。

-inform DER|PEM|SMIME

PKCS#7 (S/MIME) 结构的输入格式(如果读取了结构);默认为 SMIME。有关详细信息,请参阅 openssl-format-options(1)

-outform DER|PEM|SMIME

PKCS#7 (S/MIME) 结构的输出格式(如果写入结构);默认为 SMIME。有关详细信息,请参阅 openssl-format-options(1)

-keyform DER|PEM|P12|ENGINE

密钥格式;默认情况下未指定。有关详细信息,请参阅 openssl-format-options(1)

-stream, -indef, -noindef

-stream-indef 选项等效,并为编码操作启用流式 I/O。这允许对数据进行单遍处理,而无需将整个内容保存在内存中,从而可能支持非常大的文件。如果输出格式为 SMIME,则 S/MIME 签名与分离数据一起自动设置,它目前默认情况下在所有其他操作中处于关闭状态。

-noindef

禁用流式 I/O,因为它将生成无限长度的构造编码。此选项目前无效。将来,流式处理将在所有相关操作中默认启用,此选项将禁用它。

-content filename

这指定一个包含分离内容的文件,这仅对 -verify 命令有用。这仅适用于 PKCS#7 结构使用分离签名形式,其中不包含内容的情况。如果输入格式为 S/MIME 且它使用 multipart/signed MIME 内容类型,则此选项将覆盖任何内容。

-text

如果加密或签名,此选项将在提供的消息中添加纯文本 (text/plain) MIME 标头。如果解密或验证,它会剥离文本标头:如果解密或验证的消息不是 MIME 类型 text/plain,则会发生错误。

-md digest

签名或重新签名时要使用的摘要算法。如果未指定,则将使用签名密钥的默认摘要算法(通常为 SHA1)。

-cipher

要使用的加密算法。例如 DES (56 位) - -des,三重 DES (168 位) - -des3,EVP_get_cipherbyname() 函数) 也可以使用,前面带有连字符,例如 -aes-128-cbc。有关您的 OpenSSL 版本支持的密码列表,请参阅 openssl-enc(1)

如果未指定,则使用三重 DES。仅在 -encrypt 时使用。

-nointern

验证消息时,通常会在消息中包含的证书中搜索签名证书。使用此选项,仅使用 -certfile 选项中指定的证书。但是,提供的证书仍可作为不受信任的 CA 使用。

-noverify

不要验证签名的消息的签名者证书。

-nochain

不要对签名者证书进行链验证;即,不要使用签名消息中的证书作为不受信任的 CA。

-nosigs

不要尝试验证消息上的签名。

-nocerts

签名消息时,签名者的证书通常会包含在其中,使用此选项时,签名者的证书将被排除。这将减小签名消息的大小,但验证者必须在本地获得签名者证书的副本(例如,使用 -certfile 选项传递)。

-noattr

通常,当消息被签名时,会包含一组属性,其中包括签名时间和支持的对称算法。使用此选项时,它们不会包含。

-nodetach

签名消息时,使用不透明签名。此形式更能抵抗邮件中继的转换,但无法被不支持 S/MIME 的邮件代理读取。没有此选项,将使用 MIME 类型 multipart/signed 的明文签名。

-nosmimecap

签名消息时,不要包含 SMIMECapabilities 属性。

-binary

通常,输入消息将转换为“规范”格式,该格式实际上使用 CR 和 LF 作为行尾:S/MIME 规范要求如此。当此选项存在时,不会进行任何转换。这在处理可能不是 MIME 格式的二进制数据时很有用。

-crlfeol

通常,输出文件使用单个 LF 作为行尾。当此选项存在时,将改为使用 CRLF

-certfile file

允许指定其他证书。签名时,这些证书将包含在消息中。验证时,将搜索这些证书以查找签名者证书。输入可以是 PEM、DER 或 PKCS#12 格式。

-signer file

签名或重新签名消息时的签名证书,如果需要多个签名者,则可以多次使用此选项。如果要验证消息,则如果验证成功,签名者证书将写入此文件。

-nocerts

签名时不要包含签名者证书。

-noattr

签名时不要包含任何签名属性。

-recip file

解密消息时的收件人证书。此证书必须与消息中的收件人之一匹配,否则会发生错误。

-inkey filename|uri

签名或解密时要使用的私钥。这必须与相应的证书匹配。如果未指定此选项,则私钥必须包含在使用 -recip-signer 文件指定的证书文件中。签名时,此选项可以多次使用以指定连续的密钥。

-passin arg

私钥密码来源。有关 arg 格式的更多信息,请参阅 openssl-passphrase-options(1)

-to, -from, -subject

相关的邮件标头。这些标头包含在消息的签名部分之外,因此可以手动包含。如果签名,许多 S/MIME 邮件客户端会检查签名者证书的电子邮件地址是否与 From: 地址中指定的地址匹配。

-allow_proxy_certs, -attime, -no_check_time, -check_ss_sig, -crl_check, -crl_check_all, -explicit_policy, -extended_crl, -ignore_critical, -inhibit_any, -inhibit_map, -no_alt_chains, -partial_chain, -policy, -policy_check, -policy_print, -purpose, -suiteB_128, -suiteB_128_only, -suiteB_192, -trusted_first, -use_deltas, -auth_level, -verify_depth, -verify_email, -verify_hostname, -verify_ip, -verify_name, -x509_strict -issuer_checks

设置证书链验证的各种选项。有关详细信息,请参阅 "Verification Options" in openssl-verification-options(1)

任何验证错误都会导致命令退出。

-CAfile file, -no-CAfile, -CApath dir, -no-CApath, -CAstore uri, -no-CAstore

有关详细信息,请参阅 "Trusted Certificate Options" in openssl-verification-options(1)

-engine id

请参阅 "Engine Options" in openssl(1)。此选项已弃用。

-rand files, -writerand file

有关详细信息,请参阅 "Random State Options" in openssl(1)

-provider name
-provider-path path
-propquery propq

请参阅 "Provider Options" in openssl(1)provider(7)property(7)

-config configfile

请参阅 "Configuration Option" in openssl(1)

recipcert ...

一个或多个消息收件人的证书,用于加密消息。

注意

MIME 消息必须在标头和输出之间不包含任何空行。某些邮件程序会自动添加空行。将邮件直接管道到 sendmail 是实现正确格式的一种方法。

要签名或加密的提供的消息必须包含必要的 MIME 标头,否则许多 S/MIME 客户端将无法正确显示它(如果可以的话)。您可以使用 -text 选项自动添加纯文本标头。

“签名和加密”消息是指对已签名消息进行加密的消息。这可以通过加密已签名的消息来实现:请参阅示例部分。

该程序版本只允许每个消息使用一个签名者,但它会在接收到的消息上验证多个签名者。一些 S/MIME 客户端如果消息包含多个签名者,就会出现问题。可以通过对已签名的消息进行签名来“并行”签名消息。

-encrypt-decrypt 选项反映了 S/MIME 客户端中的常见用法。严格来说,它们处理 PKCS#7 密封数据:PKCS#7 加密数据用于其他目的。

-resign 选项在添加新的签名者时使用现有的消息摘要。这意味着属性必须至少存在于一个使用相同消息摘要的现有签名者中,否则此操作将失败。

-stream-indef 选项启用流式 I/O 支持。因此,编码使用无限长度构造编码的 BER,不再是 DER。流式传输支持 -encrypt 操作和 -sign 操作(如果内容未分离)。

流式传输始终用于使用分离数据的 -sign 操作,但由于内容不再是 PKCS#7 结构的一部分,因此编码仍然是 DER。

退出代码

0

操作完全成功。

1

解析命令选项时发生错误。

2

无法读取其中一个输入文件。

3

创建 PKCS#7 文件或读取 MIME 消息时发生错误。

4

解密或验证消息时发生错误。

5

消息已正确验证,但写入签名者证书时发生错误。

示例

创建明文签名消息

openssl smime -sign -in message.txt -text -out mail.msg \
       -signer mycert.pem

创建不透明签名消息

openssl smime -sign -in message.txt -text -out mail.msg -nodetach \
       -signer mycert.pem

创建签名消息,包含一些额外的证书,并从另一个文件读取私钥

openssl smime -sign -in in.txt -text -out mail.msg \
       -signer mycert.pem -inkey mykey.pem -certfile mycerts.pem

创建具有两个签名者的签名消息

openssl smime -sign -in message.txt -text -out mail.msg \
       -signer mycert.pem -signer othercert.pem

在 Unix 下将签名消息直接发送到 sendmail,包括标题

openssl smime -sign -in in.txt -text -signer mycert.pem \
       -from [email protected] -to someone@somewhere \
       -subject "Signed message" | sendmail someone@somewhere

验证消息,如果成功则提取签名者的证书

openssl smime -verify -in mail.msg -signer user.pem -out signedtext.txt

使用三重 DES 发送加密邮件

openssl smime -encrypt -in in.txt -from [email protected] \
       -to someone@somewhere -subject "Encrypted message" \
       -des3 user.pem -out mail.msg

签名和加密邮件

openssl smime -sign -in ml.txt -signer my.pem -text \
       | openssl smime -encrypt -out mail.msg \
       -from [email protected] -to someone@somewhere \
       -subject "Signed and Encrypted message" -des3 user.pem

注意:加密命令不包含 -text 选项,因为要加密的消息已经包含 MIME 标题。

解密邮件

openssl smime -decrypt -in mail.msg -recip mycert.pem -inkey key.pem

Netscape 表单签名的输出是一个 PKCS#7 结构,具有分离签名格式。您可以使用此程序通过换行 base64 编码的结构并将其包围在

-----BEGIN PKCS7-----
-----END PKCS7-----

中并使用命令

openssl smime -verify -inform PEM -in signature.pem -content content.txt

或者,您可以将签名进行 base64 解码并使用

openssl smime -verify -inform DER -in signature.der -content content.txt

使用 128 位 Camellia 创建加密消息

openssl smime -encrypt -in plain.txt -camellia128 -out mail.msg cert.pem

将签名者添加到现有消息

openssl smime -resign -in mail.msg -signer newsign.pem -out mail2.msg

错误

MIME 解析器不是很智能:它似乎可以处理我抛给它的大多数消息,但可能会在其他消息上出现问题。

当前代码只将签名者的证书写入文件:如果签名者有单独的加密证书,则必须手动提取。应该有一些启发式方法来确定正确的加密证书。

理想情况下,应该维护一个每个电子邮件地址的证书数据库。

当前代码没有注意到 SMIMECapabilities 签名属性中提供的允许的对称加密算法。这意味着用户必须手动包含正确的加密算法。它应该将允许的密码列表存储在数据库中,并且只使用那些密码。

没有对签名者的证书进行吊销检查。

当前代码只能处理 S/MIME v2 消息,更复杂的 S/MIME v3 结构可能会导致解析错误。

另请参见

ossl_store-file(7)

历史

多个 -signer 选项和 -resign 命令的使用是在 OpenSSL 1.0.0 中首次添加的

-no_alt_chains 选项是在 OpenSSL 1.1.0 中添加的。

-engine 选项在 OpenSSL 3.0 中已弃用。

版权所有 2000-2023 OpenSSL 项目作者。保留所有权利。

根据 Apache 许可证 2.0 版(“许可证”)授权。除符合许可证的规定外,您不得使用此文件。您可以在源代码分发中的 LICENSE 文件或以下地址获取副本:https://www.openssl.org/source/license.html.