web-dev-qa-db-ja.com

公開鍵は署名をどのように検証しますか?

私は公開鍵/秘密鍵がどのように機能するかについてより良い取り組みをしようとしています。送信者がプライベートキーを使用してドキュメントにデジタル署名を追加してドキュメントのハッシュを取得することは理解していますが、私が理解していないのは、公開キーを使用してその署名を検証する方法です。

私の理解では、公開鍵は暗号化され、秘密鍵は復号化されます...誰でも私を理解するのを助けることができますか?

127
jcampos8782

「公開鍵暗号化、秘密鍵復号化」の理解は正しいです...データ/メッセージの暗号化について。デジタル署名の場合は、逆です。デジタル署名を使用すると、あなたが署名した文書があなたから来たことを証明しようとしています。そのためには、自分だけが持っているもの、つまり秘密鍵を使用する必要があります。

最も簡単な説明のデジタル署名は、データ(ファイル、メッセージなど)のハッシュ(SHA1、MD5など)であり、その後署名者の秘密キーで暗号化されます。それは署名者だけが持っている(または持つべき)ものであるため、そこから信頼が生まれます。誰もが署名者の公開鍵へのアクセス権を持っています(または持っている必要があります)。

したがって、デジタル署名を検証するには、受信者

  1. 同じデータ(ファイル、メッセージなど)のハッシュを計算します。
  2. 送信者のPUBLICキーを使用してデジタル署名を解読し、
  3. 2つのハッシュ値を比較します。

一致する場合、署名は有効と見なされます。一致しない場合は、署名に別のキーが使用されたか、データが(意図的または意図せずに)変更されたことを意味します。

お役に立てば幸いです!

170
Shadowman

キーは逆に機能します。

公開鍵の暗号化、秘密鍵の復号化(暗号化):

openssl rsautl -encrypt -inkey public.pem -pubin -in message.txt -out message.ssl
openssl rsautl -decrypt -inkey private.pem       -in message.ssl -out message.txt

秘密鍵の暗号化、公開鍵の復号化(署名):

openssl rsautl -sign -inkey private.pem       -in message.txt -out message.ssl
openssl rsautl       -inkey public.pem -pubin -in message.ssl -out message.txt

以下は、opensslを使用してこのフロー全体をテストするスクリプトの例です。

#!/bin/sh
# Create message to be encrypted
echo "Creating message file"
echo "---------------------"
echo "My secret message" > message.txt
echo "done\n"

# Create asymmetric keypair
echo "Creating asymmetric key pair"
echo "----------------------------"
openssl genrsa -out private.pem 1024
openssl rsa -in private.pem -out public.pem -pubout
echo "done\n"

# Encrypt with public & decrypt with private
echo "Public key encrypts and private key decrypts"
echo "--------------------------------------------"
openssl rsautl -encrypt -inkey public.pem -pubin -in message.txt         -out message_enc_pub.ssl
openssl rsautl -decrypt -inkey private.pem       -in message_enc_pub.ssl -out message_pub.txt
xxd message_enc_pub.ssl # Print the binary contents of the encrypted message
cat message_pub.txt # Print the decrypted message
echo "done\n"

# Encrypt with private & decrypt with public
echo "Private key encrypts and public key decrypts"
echo "--------------------------------------------"
openssl rsautl -sign    -inkey private.pem -in message.txt          -out message_enc_priv.ssl
openssl rsautl -inkey public.pem -pubin    -in message_enc_priv.ssl -out message_priv.txt
xxd message_enc_priv.ssl
cat message_priv.txt
echo "done\n"

このスクリプトは次を出力します。

Creating message file
---------------------
done

Creating asymmetric key pair
----------------------------
Generating RSA private key, 1024 bit long modulus
...........++++++
....++++++
e is 65537 (0x10001)
writing RSA key
done

Public key encrypts and private key decrypts
--------------------------------------------
00000000: 31c0 f70d 7ed2 088d 9675 801c fb9b 4f95  1...~....u....O.
00000010: c936 8cd0 0cc4 9159 33c4 9625 d752 5b77  .6.....Y3..%.R[w
00000020: 5bfc 988d 19fe d790 b633 191f 50cf 1bf7  [........3..P...
00000030: 34c0 7788 efa2 4967 848f 99e2 a442 91b9  4.w...Ig.....B..
00000040: 5fc7 6c79 40ea d0bc 6cd4 3c9a 488e 9913  [email protected].<.H...
00000050: 387f f7d6 b8e6 5eba 0771 371c c4f0 8c7f  8.....^..q7.....
00000060: 8c87 39a9 0c4c 22ab 13ed c117 c718 92e6  ..9..L".........
00000070: 3d5b 8534 7187 cc2d 2f94 0743 1fcb d890  =[.4q..-/..C....
My secret message
done

Private key encrypts and public key decrypts
--------------------------------------------
00000000: 6955 cdd0 66e4 3696 76e1 a328 ac67 4ca3  iU..f.6.v..(.gL.
00000010: d6bb 5896 b6fe 68f1 55f1 437a 831c fee9  ..X...h.U.Cz....
00000020: 133a a7e9 005b 3fc5 88f7 5210 cdbb 2cba  .:...[?...R...,.
00000030: 29f1 d52d 3131 a88b 78e5 333e 90cf 3531  )..-11..x.3>..51
00000040: 08c3 3df8 b76e 41f2 a84a c7fb 0c5b c3b2  ..=..nA..J...[..
00000050: 9d3b ed4a b6ad 89bc 9ebc 9154 da48 6f2d  .;.J.......T.Ho-
00000060: 5d8e b686 635f b6a4 8774 a621 5558 7172  ]...c_...t.!UXqr
00000070: fbd3 0c35 df0f 6a16 aa84 f5da 5d5e 5336  ...5..j.....]^S6
My secret message
done
53
Jaakko

公開鍵は暗号化され、秘密鍵のみが暗号化を解除できます。逆も同様です。両方とも異なるハッシュに暗号化されますが、各キーは相手の暗号化を解読できます。

メッセージが予想される送信者から送信されたことを確認する方法はいくつかあります。例えば:

送信者は以下を送信します。

  1. メッセージ

  2. 秘密鍵で暗号化されたメッセージのハッシュ

受信機:

  1. 署名(2)を公開鍵で復号化して、メッセージ(おそらく(1)と同じメッセージ)を取得しますが、まだわかりません。これで、確認する必要がある2つのメッセージが同一になりました。したがって、これを行うには、公開キーで暗号化し、2つのハッシュを比較します。だから….
  2. 元のメッセージ(1)を公開鍵で暗号化してハッシュを取得します
  3. 復号化されたメッセージを暗号化して(3)2番目のハッシュを取得し、(4)と比較してそれらが同一であることを確認します。

それらが同一でない場合は、メッセージが改ざんされたか、または考えられたものではなく、他のキーで署名されたことを意味します...

別の例は、送信者が共通のハッシュを使用することです。これは、受信者も使用することがわかっている可能性があります。例えば:

送信者は以下を送信します。

  1. メッセージ
  2. メッセージの既知のハッシュを取得し、秘密鍵でハッシュを暗号化します

受信機:

  1. 復号化(2)およびハッシュ値を取得
  2. 送信者が使用したのと同じハッシュでメッセージ(1)をハッシュします
  3. 2つのハッシュを比較して、一致することを確認します

これにより、メッセージが改ざんされておらず、予期された送信者からのものであることが保証されます。

7
wueb

もっと直感的に明らかにするものを探している人に補足説明を提供すると思いました。

この混乱の大部分は、「公開鍵」と「秘密鍵」の命名から生じます。これらのことは、実際にはどのように機能するかは、「鍵」がどのように理解されるかと直接対立するためです。

暗号化を例にとります。次のように動作すると考えることができます。

  • 秘密のメッセージを読むことができるようにしたい当事者はそれぞれ、鍵を隠します(すなわち、秘密鍵)
  • 秘密のメッセージを送信できるようにしたいすべての当事者は、ロック解除されたロック(つまり、パブリックロック)を取得することができます。
  • その後、秘密のメッセージを送信することは、ロック解除されたロックでロックするのと同じくらい簡単ですが、その後のロック解除は、非表示のキーの1つでのみ行えます。

これにより、関係者間で秘密のメッセージを送信できますが、ここでは直感的な観点から、「パブリックロック」は「パブリックキー」よりも適切な名前です。

ただし、デジタル署名を送信する場合、役割は多少逆​​になります。

  • ロック解除されたロック(つまり、プライベートロック)にアクセスできるのは、メッセージに署名したい当事者のみです。
  • 署名を検証したい当事者はすべて、キー(つまり、公開キー)を取得することができます。
  • 次に、署名者は2つの同一のメッセージを作成します。誰でも読むことができるメッセージと、それに付随するメッセージですが、プライベートロックの1つでロックします。
  • 次に、受信者がメッセージを取得すると、受信者はそれを読み取り、公開キーを使用してロックされたメッセージのロックを解除し、2つのメッセージを比較できます。メッセージが同じ場合、彼らはそれを知っています:

    1. ロック解除されたメッセージは旅行中に改ざんされず、

    2. メッセージは、公開鍵に一致するロックを持っている人からのものでなければなりません。

  • そして最後に、このシステム全体は、署名者の署名を検証したい人が、署名者のロックに一致するキーを取得するための信頼できる場所を持っている場合にのみ機能します。それ以外の場合は、誰でも「ちょっと、秘密のロックの鍵です」と言って、あなたのふりをしてメッセージを送信しますが、プライベートロックでロックします。上記のすべての手順を実行し、メッセージは実際にあなたが思った人から、しかし、あなたはあなたが公開鍵の本当の所有者に関して誤解されたので、だまされています。

署名者の公開鍵を取得するための信頼できるソースがある限り、公開鍵の正当な所有者が誰であるかがわかり、署名を検証することができます。

3
shoe