27 votes

Comment vérifiez-vous un RSA SHA1 signature en Python?

J'ai une chaîne de caractères, une signature et d'une clé publique, et je veux vérifier la signature sur la chaîne. La clé ressemble à ceci:

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

J'ai lu les pycrypto docs pendant un certain temps, mais je ne peux pas comprendre comment faire un RSAobj avec ce type de clé. Si vous connaissez PHP, je suis en train de faire ce qui suit:

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

Aussi, si je suis confus au sujet de toute terminologie, s'il vous plaît laissez-moi savoir.

25voto

joeforker Points 14483

Utilisation M2Crypto. Voici comment vérifier le RSA et tout autre algorithme pris en charge par 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

22voto

Rasmus Faber Points 24195

Les données entre les marqueurs de l'encodage base64 de l'ASN.1 DER-encodage d'un fichier PKCS#8 PublicKeyInfo contenant un fichier PKCS#1 RSAPublicKey.

C'est beaucoup de normes, et vous serez mieux servi avec l'aide d'une bibliothèque de chiffrement pour les décoder (comme M2Crypto comme suggéré par joeforker). Traiter quelques le plaisir d'infos sur le format:

Si vous le souhaitez, vous pouvez décoder comme ceci:

Base64-décoder la chaîne:

30819f300d06092a864886f70d010101050003818d0030818902818100df1b822e14eda1fcb74336
6a27c06370e6cad69d4116ce806b3d117534cf0baa938c0f8e4500fb59d4d98fb471a8d01012d54b
32244197c7434f27c1b0d73fa1b8bae55e70155f907879ce9c25f28a9a92ff97de1684fdaff05dce
196ae76845f598b328c5ed76e0f71f6a6b7448f08691e6a556f5f0d773cb20d13f629b6391020301
0001

C'est le DER-encodage de:

   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
            :         }
            :       }
            :   }

Pour une clé RSA 1024-bit, vous pouvez traiter "30819f300d06092a864886f70d010101050003818d00308189028181" comme une constante de l'en-tête, suivi par un 00 octet, suivie par les 128 octets du RSA module. Après que 95% du temps, vous obtiendrez 0203010001, ce qui signifie un RSA publique exposant de 0x10001 = 65537.

Vous pouvez utiliser ces deux valeurs de n et e, dans un tuple à la construction d'un RSAobj.

2voto

user64349 Points 143

Une clé publique contient à la fois un module(très long, peut être 1 024 bits, 2058bit, 4096bit) et d'une clé publique exposant(beaucoup plus petit nombre, généralement équivalent à un plus de deux à une certaine puissance). Vous avez besoin de savoir comment découper la clé publique dans les deux composants avant de pouvoir faire quelque chose avec elle.

Je ne sais pas beaucoup au sujet de pycrypto mais pour vérifier une signature, prendre le hachage de la chaîne. Maintenant, nous devons déchiffrer la signature. Lire sur l'exponentiation modulaire; la formule pour déchiffrer une signature est - message^public exponent % modulus. La dernière étape consiste à vérifier si le hachage et la restitution de la signature que vous avez obtenu sont les mêmes.

1voto

David Z Points 49476

Peut-être que ce n'est pas la réponse que vous cherchez, mais si tout ce que vous besoin de faire est de tourner la clé en bits, on dirait qu'il est encodé en Base64. Regardez l' codecs module (je crois) dans la bibliothèque standard de Python.

1voto

Garth Kidd Points 2792

Je pense que ezPyCrypto pourrait les rendre un peu plus facile. Le haut niveau des méthodes de la clé classe comprend ces deux méthodes qui, je l'espère, permettra de résoudre votre problème:

  • verifyString - vérifier une chaîne de contre signature
  • importKey - importer la clé publique (et éventuellement la clé privée aussi)

Rasmus points dans les commentaires qu' verifyString est codé en dur pour utiliser MD5, auquel cas ezPyCryto ne peut pas aider Andrew, à moins qu'il patauge dans son code. Je reporte à joeforker réponse: considérer M2Crypto.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X