如何在 Python 中验证 RSA SHA1 签名?

2022-01-10 00:00:00 python cryptography rsa sha1 signature

问题描述

我有一个字符串、一个签名和一个公钥,我想验证字符串上的签名.密钥如下所示:

I've got a string, a signature, and a public key, and I want to verify the signature on the string. The key looks like this:

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

我已经阅读 pycrypto 文档有一段时间了,但我不知道如何使用这种密钥制作 RSAobj.如果您了解 PHP,我正在尝试执行以下操作:

I've been reading the pycrypto docs for a while, but I can't figure out how to make an RSAobj with this kind of key. If you know PHP, I'm trying to do the following:

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

另外,如果我对任何术语感到困惑,请告诉我.

Also, if I'm confused about any terminology, please let me know.


解决方案

标记之间的数据是包含 PKCS#1 RSAPublicKey 的 PKCS#8 PublicKeyInfo 的 ASN.1 DER 编码的 base64 编码.

The data between the markers is the base64 encoding of the ASN.1 DER-encoding of a PKCS#8 PublicKeyInfo containing an PKCS#1 RSAPublicKey.

这是很多标准,最好使用加密库对其进行解码(例如 M2Crypto 作为 joeforker 建议).将以下内容视为有关格式的一些有趣信息:

That is a lot of standards, and you will be best served with using a crypto-library to decode it (such as M2Crypto as suggested by joeforker). Treat the following as some fun info about the format:

如果你愿意,你可以这样解码:

If you want to, you can decode it like this:

Base64 解码字符串:

Base64-decode the string:

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

对于 1024 位 RSA 密钥,您可以将 "30819f300d06092a864886f70d010101050003818d00308189028181" 视为常量标头,后跟 00 字节,然后是 RSA 模数的 128 字节.在那之后 95% 的时间你会得到 0203010001,这表示 RSA 公共指数 0x10001 = 65537.

For a 1024 bit RSA key, you can treat "30819f300d06092a864886f70d010101050003818d00308189028181" as a constant header, followed by a 00-byte, followed by the 128 bytes of the RSA modulus. After that 95% of the time you will get 0203010001, which signifies a RSA public exponent of 0x10001 = 65537.

您可以将这两个值用作元组中的 ne 来构造 RSAobj.

You can use those two values as n and e in a tuple to construct a RSAobj.

相关文章