30

文字列、署名、公開鍵があり、文字列の署名を確認したいと思います。キーは次のようになります。

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDfG4IuFO2h/LdDNmonwGNw5srW
nUEWzoBrPRF1NM8LqpOMD45FAPtZ1NmPtHGo0BAS1UsyJEGXx0NPJ8Gw1z+huLrl
XnAVX5B4ec6cJfKKmpL/l94WhP2v8F3OGWrnaEX1mLMoxe124Pcfamt0SPCGkeal
VvXw13PLINE/YptjkQIDAQAB
-----END PUBLIC KEY-----

pycryptoのドキュメントをしばらく読んでいますが、この種のキーを使用してRSAobjを作成する方法がわかりません。あなたがPHPを知っているなら、私は次のことをしようとしています:

openssl_verify($data, $signature, $public_key, OPENSSL_ALGO_SHA1);

また、用語がわからない場合はお知らせください。

4

8 に答える 8

30

M2Cryptoを使用します。RSA および OpenSSL でサポートされているその他のアルゴリズムを確認する方法は次のとおりです。

pem = """-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDfG4IuFO2h/LdDNmonwGNw5srW
nUEWzoBrPRF1NM8LqpOMD45FAPtZ1NmPtHGo0BAS1UsyJEGXx0NPJ8Gw1z+huLrl
XnAVX5B4ec6cJfKKmpL/l94WhP2v8F3OGWrnaEX1mLMoxe124Pcfamt0SPCGkeal
VvXw13PLINE/YptjkQIDAQAB
-----END PUBLIC KEY-----""" # your example key

from M2Crypto import BIO, RSA, EVP
bio = BIO.MemoryBuffer(pem)
rsa = RSA.load_pub_key_bio(bio)
pubkey = EVP.PKey()
pubkey.assign_rsa(rsa)

# if you need a different digest than the default 'sha1':
pubkey.reset_context(md='sha1')
pubkey.verify_init()
pubkey.verify_update('test  message')
assert pubkey.verify_final(signature) == 1
于 2009-02-13T15:59:41.223 に答える
24

マーカー間のデータは、PKCS#1 RSAPublicKey を含む PKCS#8 PublicKeyInfo の ASN.1 DER エンコードの base64 エンコードです。

これは多くの標準であり、暗号ライブラリを使用してデコードするのが最適です( joeforker が提案する M2Cryptoなど)。以下は、フォーマットに関する楽しい情報として扱ってください。

必要に応じて、次のようにデコードできます。

文字列を Base64 でデコードします。

30819f300d06092a864886f70d010101050003818d0030818902818100df1b822e14eda1fcb74336
6a27c06370e6cad69d4116ce806b3d117534cf0baa938c0f8e4500fb59d4d98fb471a8d01012d54b
32244197c7434f27c1b0d73fa1b8bae55e70155f907879ce9c25f28a9a92ff97de1684fdaff05dce
196ae76845f598b328c5ed76e0f71f6a6b7448f08691e6a556f5f0d773cb20d13f629b6391020301
0001

これは、次の DER エンコードです。

   0 30  159: SEQUENCE {
   3 30   13:   SEQUENCE {
   5 06    9:     OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1)
  16 05    0:     NULL
            :     }
  18 03  141:   BIT STRING 0 unused bits, encapsulates {
  22 30  137:       SEQUENCE {
  25 02  129:         INTEGER
            :           00 DF 1B 82 2E 14 ED A1 FC B7 43 36 6A 27 C0 63
            :           70 E6 CA D6 9D 41 16 CE 80 6B 3D 11 75 34 CF 0B
            :           AA 93 8C 0F 8E 45 00 FB 59 D4 D9 8F B4 71 A8 D0
            :           10 12 D5 4B 32 24 41 97 C7 43 4F 27 C1 B0 D7 3F
            :           A1 B8 BA E5 5E 70 15 5F 90 78 79 CE 9C 25 F2 8A
            :           9A 92 FF 97 DE 16 84 FD AF F0 5D CE 19 6A E7 68
            :           45 F5 98 B3 28 C5 ED 76 E0 F7 1F 6A 6B 74 48 F0
            :           86 91 E6 A5 56 F5 F0 D7 73 CB 20 D1 3F 62 9B 63
            :           91
 157 02    3:         INTEGER 65537
            :         }
            :       }
            :   }

"30819f300d06092a864886f70d010101050003818d00308189028181"1024 ビットの RSA キーの場合、定数ヘッダー、その後に 00 バイト、その後に 128 バイトの RSA モジュラスが続くものとして扱うことができます。その後、95% の確率で が得られます0203010001。これは、0x10001 = 65537 の RSA 公開指数を意味します。

これらの 2 つの値をタプルとして使用neて、RSAobj を構築できます。

于 2009-02-13T08:54:06.860 に答える
2

公開鍵には、モジュラス (非常に長い数、1024 ビット、2058 ビット、4096 ビットのいずれか) と公開鍵指数 (はるかに小さい数、通常は 2 のべき乗よりも 1 大きい) の両方が含まれます。公開鍵を使って何かをする前に、その公開鍵を 2 つのコンポーネントに分割する方法を見つける必要があります。

pycrypto についてはよくわかりませんが、署名を検証するには、文字列のハッシュを取得します。次に、署名を復号化する必要があります。累乗剰余について読んでください。署名を解読する式はmessage^public exponent % modulusです。最後のステップは、作成したハッシュと取得した復号化された署名が同じかどうかを確認することです。

于 2009-02-13T03:44:34.313 に答える
1

DER デコードの詳細。

DER エンコーディングは、常に TLV トリプレット形式 (タグ、長さ、値) に従います。

  • タグは、値のタイプ (つまり、データ構造) を指定します
  • 長さは、この値フィールドが占めるバイト数を指定します
  • 値は、別のトリプレットである可能性がある実際の値です

タグは基本的に、値フィールドのバイト データを解釈する方法を示します。ANS.1 には型システムがあります。たとえば、0x02 は整数を意味し、0x30 はシーケンス (1 つ以上の他の型インスタンスの順序付きコレクション) を意味します。

長さの表示には特別なロジックがあります。

  • 長さが 127 未満の場合、L フィールドは 1 バイトのみを使用し、長さの数値として直接コード化されます。
  • 長さが > 127 の場合、L フィールドの最初のバイトの最初のビットは 1 でなければならず、残りの 7 ビットは、値フィールドの長さを指定するために使用される後続のバイト数を表します。値、値自体の実際のバイト。

たとえば、256バイトの長さをエンコードしたい場合、次のようになります

02  82  01  00  1F  2F  3F  4F  …   DE  AD  BE  EF
  • タグ、0x02 は数字であることを意味します
  • 長さ、0x82、ビット表示は 1000 0010 です。これは、次の 2 バイトが値の実際の長さを指定することを意味します。0x0100 は、値フィールドの長さが 256 バイトであることを意味します。
  • 値、1F から EF まで、実際の 256 バイト。

今あなたの例を見て

30819f300d06092a864886f70d010101050003818d0030818902818100df1b822e14eda1fcb74336
6a27c06370e6cad69d4116ce806b3d117534cf0baa938c0f8e4500fb59d4d98fb471a8d01012d54b
32244197c7434f27c1b0d73fa1b8bae55e70155f907879ce9c25f28a9a92ff97de1684fdaff05dce
196ae76845f598b328c5ed76e0f71f6a6b7448f08691e6a556f5f0d773cb20d13f629b6391020301
0001

Rasmus Faber が返信で述べたとおりに解釈されます。

于 2014-07-30T08:34:34.613 に答える
1

ezPyCryptoを使用すると、これが少し簡単になると思います。キークラスの高レベル メソッドには、次の 2 つのメソッドが含まれており、問題が解決されることを願っています。

  • verifyString - 署名に対して文字列を検証します
  • importKey - 公開鍵 (場合によっては秘密鍵も) をインポートします

Rasmusはコメントの中で、verifyStringMD5 を使用するようにハードコードされていると指摘しています。私はjoeforker の答えに従います: M2Cryptoを検討してください。

于 2009-02-13T09:01:22.383 に答える
0

M2Crypto を使用すると、上記の回答は機能しません。これはテスト済みの例です。

import base64
import hashlib
import M2Crypto as m2

# detach the signature from the message if it's required in it (useful for url encoded data)
message_without_sign = message.split("&SIGN=")[0]
# decode base64 the signature
binary_signature = base64.b64decode(signature)
# create a pubkey object with the public key stored in a separate file
pubkey = m2.RSA.load_pub_key(os.path.join(os.path.dirname(__file__), 'pubkey.pem'))
# verify the key
assert pubkey.check_key(), 'Key Verification Failed'
# digest the message
sha1_hash = hashlib.sha1(message_without_sign).digest()
# and verify the signature
assert pubkey.verify(data=sha1_hash, signature=binary_signature), 'Certificate Verification Failed'

そしてそれはそれについてです

于 2015-03-27T13:03:19.610 に答える
0

これはあなたが探している答えではないかもしれませんが、キーをビットに変換するだけなら、Base64 でエンコードされているように見えます。標準の Python ライブラリのモジュールを見てくださいcodecs(と思います)。

于 2009-02-13T02:13:10.100 に答える
-1

joeforker から提供されたコードを試してみましたが、うまくいきません。これが私のサンプルコードで、うまく動作します。

from Crypto.Signature import PKCS1_v1_5
from Crypto.PublicKey import RSA 
from Crypto.Hash import SHA

pem = """-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDfG4IuFO2h/LdDNmonwGNw5srW
nUEWzoBrPRF1NM8LqpOMD45FAPtZ1NmPtHGo0BAS1UsyJEGXx0NPJ8Gw1z+huLrl
XnAVX5B4ec6cJfKKmpL/l94WhP2v8F3OGWrnaEX1mLMoxe124Pcfamt0SPCGkeal
VvXw13PLINE/YptjkQIDAQAB
-----END PUBLIC KEY-----""" # your example key

key = RSA.importKey(pem)
h = SHA.new(self.populateSignStr(params))
verifier = PKCS1_v1_5.new(key)
if verifier.verify(h, signature):
  print "verified"
else:
  print "not verified"
于 2014-08-08T03:59:08.167 に答える