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 檔名

要加密或簽署的輸入訊息,或要解密或驗證的 MIME 訊息。

-out 檔名

已解密或驗證的訊息文字,或已簽署或驗證的輸出 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 檔名

這會指定一個包含分離內容的檔案,這只會在 -verify 指令中使用。這只會在 PKCS#7 結構使用分離簽章格式,其中不包含內容時使用。如果輸入格式為 S/MIME 且它使用 multipart/signed MIME 內容類型,這個選項將會覆寫任何內容。

-text

如果要加密或簽署,這個選項會將純文字 (text/plain) MIME 標頭新增到提供的訊息。如果要解密或驗證,它會移除文字標頭:如果解密或驗證的訊息不是 MIME 類型 text/plain,則會發生錯誤。

-md 摘要

簽署或重新簽署時要使用的摘要演算法。如果沒有提供,則會使用簽署金鑰的預設摘要演算法(通常是 SHA1)。

-密碼

要使用的加密演算法。例如 DES(56 位元)- -des,三重 DES(168 位元)- -des3,也可以使用 EVP_get_cipherbyname() 函式,並在前面加上連字號,例如 -aes-128-cbc。請參閱 openssl-enc(1) 以取得 OpenSSL 版本支援的密碼清單。

如果未指定,則使用三重 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 檔案

允許指定其他憑證。簽署時,這些憑證會包含在訊息中。驗證時,這些憑證會用於搜尋簽署者的憑證。輸入可以是 PEM、DER 或 PKCS#12 格式。

-signer 檔案

簽署或重新簽署訊息時的簽署憑證,如果需要多個簽署者,此選項可以使用多次。如果要驗證訊息,則在驗證成功時,簽署者的憑證會寫入此檔案。

-nocerts

簽署時不包含簽署者的憑證。

-noattr

簽署時不包含任何已簽署的屬性。

-recip 檔案

解密訊息時的收件者憑證。此憑證必須符合訊息收件者之一,否則會發生錯誤。

-inkey 檔名|uri

簽署或解密時要使用的私密金鑰。這必須符合對應的憑證。如果未指定此選項,則私密金鑰必須包含在使用-recip-signer檔案指定的憑證檔案中。簽署時,此選項可以使用多次來指定連續的金鑰。

-passin 引數

私密金鑰密碼來源。有關引數格式的更多資訊,請參閱openssl-passphrase-options(1)

-to, -from, -subject

相關郵件標頭。這些標頭包含在訊息簽署部分之外,因此可以手動包含。如果簽署,許多 S/MIME 郵件用戶端會檢查簽署者的憑證電子郵件地址是否與「寄件者:」地址中指定的地址相符。

-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

設定憑證鏈驗證的各種選項。有關詳細資訊,請參閱 openssl-verification-options(1) 中的「驗證選項」

任何驗證錯誤都會導致命令退出。

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

有關詳細資訊,請參閱 openssl-verification-options(1) 中的「受信任憑證選項」

-engine id

請參閱 openssl(1) 中的「引擎選項」。此選項已棄用。

-rand files-writerand file

有關詳細資訊,請參閱 openssl(1) 中的「隨機狀態選項」

-provider name
-provider-path path
-propquery propq

請參閱 openssl(1) 中的「提供者選項」provider(7)property(7)

-config configfile

請參閱 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 steve@openssl.org -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 steve@openssl.org \
       -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 steve@openssl.org -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)

歷程

在 OpenSSL 1.0.0 中,首先新增了使用多個 -signer 選項和 -resign 命令的功能。

在 OpenSSL 1.1.0 中,新增了 -no_alt_chains 選項。

在 OpenSSL 3.0 中,-engine 選項已棄用。

版權所有 2000-2023 OpenSSL 專案作者。保留所有權利。

根據 Apache 授權條款 2.0(「授權條款」)授權。您不得在不遵守授權條款的情況下使用此檔案。您可以在原始程式碼散佈中的 LICENSE 檔案中取得副本,或在 https://www.openssl.org/source/license.html 取得副本。