Opensslコマンドを使用して、電子メールのコンテンツを暗号化/復号化するためのキーを取得および復号化できるかどうかを知りたいです。私はこのようなもので暗号化されたメール全体を復号化できることを知っています
openssl smime -decrypt -in enc_mail.eml -inkey recip_priv.pem > dec_mail.eml
ただし、その間の手順を教えてください。手順を正しく理解していれば、メールの実際の内容は受信者の公開鍵ではなく、送信者側でランダムに生成された鍵で暗号化されています。この鍵は、受信者の公開鍵で暗号化され、暗号化されたメッセージに添付されます。私は正しいですか? opensslを使用して、添付された暗号化キーを表示し、個別に復号化することはできますか?
ありがとう。
はい、できます。この例では、openssl smime
をデフォルトのRC2 CBCと40ビットのキーで使用しています。新しい cms
サブコマンドの動作は少し異なります で、デフォルトで3-DESを使用します。 重要なデータを暗号化するためにこれらのアルゴリズムのどちらも使用するべきではありません;-)
2つのマイナーな警告があります。1つ目は、他のいくつかのツールも使用します(ただし、OpenSSLはすべての重い作業に使用されます)、2つ目は電子メールがどのように暗号化されたかについていくつかの仮定を行うため。
En/decryptionは、ほとんどのRSAを使用する方法のラインに沿っています:(低速で高価な)RSAを使用して対称鍵をen/decryptし、高速対称鍵を使用して実際のデータをen/decryptします。 (詳細については this question または this を参照してください)。
メールを受け取り、P7M部分を抽出してデコードします。 base64でエンコードされた単一の.p7m
パーツがある場合、metamail
を使用してこれを簡単に行うことができます。
$ metamail -wy enc_mail.eml
P7Mファイルを保存します。これは ASN.1 DERエンコードされた [〜#〜] cms [〜#〜] (PKCS#7)ファイルなので、中を覗くことができます。
$ dumpasn1 -tilda smime.p7m
0 1946: SEQUENCE {
4 9: . OBJECT IDENTIFIER envelopedData (1 2 840 113549 1 7 3)
: . . (PKCS #7)
15 1931: . [0] {
[ .. certificate details and whatnot omitted ...]
188 13: . . . . . SEQUENCE {
190 9: . . . . . . OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1)
: . . . . . . . (PKCS #1)
201 0: . . . . . . NULL
: . . . . . . }
203 256: . . . . . OCTET STRING
: . . . . . . A0 DA EA FB EA 1A 0F 81 ........
: . . . . . . F4 30 9F 78 5C 9B A7 27 .0.x\..'
[ ... blob snipped ...]
463 1483: . . . SEQUENCE {
467 9: . . . . OBJECT IDENTIFIER data (1 2 840 113549 1 7 1)
: . . . . . (PKCS #7)
478 26: . . . . SEQUENCE {
480 8: . . . . . OBJECT IDENTIFIER rc2CBC (1 2 840 113549 3 2)
: . . . . . . (RSADSI encryptionAlgorithm)
490 14: . . . . . SEQUENCE {
492 2: . . . . . . INTEGER 160
496 8: . . . . . . OCTET STRING 3E EA 0E 12 37 A8 56 70
: . . . . . . }
: . . . . . }
506 1440: . . . . [0]
: . . . . . A5 FF A1 70 2C AD 82 6A ...p,..j
: . . . . . C7 F0 84 E8 9E 93 8F 53 .......S
[... blob snipped ...]
私が使用しているのは dumpasn1
です。これは、openssl asn1parse
が関心のあるさまざまなblobを表示またはダンプすることを拒否するためです。メールの構造は、上記のものとは異なります。列1と2は、それぞれの(おそらくネストされた)サブ構造のオフセットとサイズです。
興味深い部分はオフセットにあります:
オフセット188では、RSAが使用され、続いて256バイトのデータが使用されていることがわかります。そのため、そのデータBLOB(オフセット203)を抽出し、バイナリに変換します。
$ dumpasn1 -a -203 smime.p7m | tail -qn +2 | xxd -r -p > rsa.bin
(開始オフセット-203
と、出力の最初の行をスキップするためのtail
の使用に注意してください。これは少し複雑ですが、残念ながらdumpasn1
とopenssl asn1parse
はtype-lengthプレフィックスは、オブジェクトをスライスしてダイスするときにそのまま残ります。)
RSAを使用してこのデータを復号化します。
$ openssl rsautl -inkey recip_priv.pem -in rsa.bin -decrypt -out rc2key.bin
$ xxd -u -p rc2key.bin
92F6EB53B1
この場合、必要な対称鍵である5バイト(40ビット)の出力が得られます。入力は PKCS#1 v1.5 パディングされた(§8.1を参照) さまざまな理由 でしたので、サイズの差異が生じました。
メインのペイロード(電子メール)は、オフセット506のblobにあります。それをファイルに抽出します。
$ dumpasn1 -a -506 smime.p7m | tail -qn +2 | xxd -r -p > email.bin
これが少しトリッキーなビットです。RC2については、 RFC 2268 のセクション6を参照してください。
rc2CBC OBJECT IDENTIFIER
::= {iso(1) member-body(2) US(840) rsadsi(113549)
encryptionAlgorithm(3) 2}
RC2-CBCParameter ::= CHOICE {
iv IV,
params SEQUENCE {
version RC2Version,
iv IV
}
}
RC2Version ::= INTEGER -- 1-1024
IV ::= OCTET STRING -- 8 octets
これは、オフセット490のデータ構造を説明しています。
480 8: . . . . . OBJECT IDENTIFIER rc2CBC (1 2 840 113549 3 2)
: . . . . . . (RSADSI encryptionAlgorithm)
490 14: . . . . . SEQUENCE {
492 2: . . . . . . INTEGER 160
496 8: . . . . . . OCTET STRING 3E EA 0E 12 37 A8 56 70
: . . . . . . }
(RC2Version 160(0xa0)がEKBテーブルのキーサイズ40ビット(0x28)と一致することを確認できます。)
つまり、S/MIME暗号化アルゴリズム(RC2 40ビットCBC、オフセット480)、RC2キー(オフセット203でblobから復号化)、RC2 IV(暗号化なし、オフセット496)、および暗号化ペイロード(オフセット506):
$ openssl enc -d -rc2-40-cbc -in email.bin -out email.txt -K 92F6EB53B1 -iv 3EEA0E1237A85670
そしてemail.txt
はあなたが探しているものでなければなりません。
チップ:
xxd
の古いバージョンを使用しないようにしてください。入力の16進データが壊れる可能性がありますopenssl enc -kfile ...
が機能しないので、-K
を使用しますopenssl smime
mayが暗号化前にメッセージを変更しました( [〜#〜] crlf [〜#〜] 要件)berdump
は、その出力がさらに処理されやすいため、便利なツールです。 DERはBERのサブセットであるため、PKCS#7 DERファイルを直接指すことができます。S/MIME は PKCS7 を使用します。おそらく、自分でコードを記述する必要があります。
C++でこれを行う方法の例を次に示します。 https://stackoverflow.com/questions/6369096/how-to-read-the-certificates-file-from-the-pkcs7-p7b-certificate-file -usind-open
そして、これはJavaの例です: https://stackoverflow.com/questions/11026588/pkcs7-encryption