Cryptography 无法验证已签名的数据

Cryptography 无法验证已签名的数据,cryptography,digital-signature,smartcard,digital-certificate,cryptoapi,Cryptography,Digital Signature,Smartcard,Digital Certificate,Cryptoapi,通过使用智能卡工具,我在数据上签名“你好” 我得到的输出是十六进制格式 14 5F 65 CE 7C 2D 8A 0A FA B0 FB 86 CE 28 90 84 37 2D 04 63 B2 35 FA 40 4A B6 35 C8 90 AF 55 7F B1 CA FE FD 5B F9 1B 7C DB 74 63 BF 16 5B B3 6D E8 2D B6 D7 2E 90 AF 0A 5E CF 78 73 E3 37 02 C2 97 0E F9 B3 40 4C 67 C

通过使用智能卡工具,我在数据上签名“你好”

我得到的输出是十六进制格式

14 5F 65 CE 7C 2D 8A 0A FA B0 FB 86 CE 28 90 84
37 2D 04 63 B2 35 FA 40 4A B6 35 C8 90 AF 55 7F
B1 CA FE FD 5B F9 1B 7C DB 74 63 BF 16 5B B3 6D
E8 2D B6 D7 2E 90 AF 0A 5E CF 78 73 E3 37 02 C2
97 0E F9 B3 40 4C 67 CD E4 7C D9 4B D3 C9 86 51
8E 1E 84 81 B4 30 AC 68 96 59 CB 63 E5 C8 28 48
C7 1D E8 E9 FC E8 C9 BE 36 33 0A F0 A9 35 C4 D4
BF 60 66 21 5C 41 8F 48 91 D4 BB AF 75 7A B3
2A 8A 28 B8 30 D1 B4 6B 69 23 82 2D 28 77 30 05
D5 C9 AB 41 17 C1 68 6D D9 80 0F F2 C1 FC 32 6E
22 61 27 97 9C DD C3 50 33 AA DB F4 BA 98 29 FA
4F E2 B4 BC C5 9E 90 34 F3 BC 3D 78 01 47 AF 96
20 06 6F F9 41 30 D7 35 52 D3 DE 85 E3 FE 0B B7
15 4D 1A 73 B8 36 F4 A1 59 A2 7E 05 50 8B 52 AC
B4 EF 2D D9 29 9D D9 BB C8 DF F3 67 C5 D1 D9 C0
0C 65 68 A8 12 9B 24 92 4E EB 98 D8 B0 D9 2E 6A

我已经以字符串格式将各自的签名数据保存在signedData.txt文件中

._eÎ|-Š.ú°û†Î(„7-.c²5ú@J¶5ȯU±Êþý[ù.|Ûtc¿.[³mè-¶×.¯.^Ïxsã7.—.ù³@LgÍä|ÙKÓɆQŽ.„´0¬h– YËcåÈ(HÇ.èéüèɾ63.ð©5ÄÔ¿`f!\AH‘Ô»¯uuz³*Š(¸0Ñ´ki#‚-(w0.ÕÉ«A.ÁhmÙ€.òÁü2n"a'—œÝÃP3ªÛôº˜)úOâ ´¼Åž4ó¼=x.G¯– .oùA0×5RÓÞ…ãþ.·.M.s¸6ô¡Y¢~.P‹R¬´ï-Ù)Ù»ÈßógÅÑÙÀ.eh¨.›$’Në˜Ø°Ù.j
我正在使用Windows CryptoAPI验证此签名数据

我正在打开signedData.txt文件并将数据写入缓冲区“ 签名缓冲区“

然后,我从存储中找到我的证书,并使用

hPubKey=cryptImportPubliceInfo(hProv,编码类型,&pCertContext->pCertInfo->SubjectPublicKeyInfo,&hCertPubKey)

然后我使用CALG_SHA_256创建一个散列对象

hObject=CryptCreateHash(hProv、CALG_SHA_256、0、0和hHashObject)

然后用散列对象添加我的数据

CryptHashData(hhObject,Buffer,BufferLen,0);//char Buffer=“你好”

在最后一步中,我使用

CryptVerifySignature(hObject,signedBuffer,signedBufferBytes,hPubKey,NULL,0);/*signedBuffer包含字符串格式的签名数据*/

/*signedBufferBytes在缓冲区中有字节数*/

但该签名数据未经验证。我得到的错误代码是
0x80090006-签名无效

十六进制格式的公钥为:

30 82 01 0a 02 82 01 01 00 b8 f8 dc 2c a5 03 84
ba 72 c6 0e 03 89 51 6f 39 a8 41 e3 49 b3 f7 14
31 d3 43 b7 fc 1f 61 c2 43 b0 77 9e 19 af f4 8b
02 99 72 c1 17 21 1d 23 da ab 53 54 74 33 e4 ab
9d 82 d2 68 33 9a b5 9c 99 cb f0 12 e0 f8 44 4f
e8 91 3f 60 ed ca fa 3b 40 bd 64 50 92 d3 c2 c1
48 ad 24 3e ca 64 2c 50 a9 01 b5 9f f4 a4 46 e5
84 e9 a4 87 41 86 a1 7a 7f fc a6 f0 e0 b1 de f0
c1 f2 5d c8 84 16 15 4d e4 df 43 3a cd ad ec
eb af 1b 9c a7 5c 40 dc ae 1f 71 6e a4 c6 0f dd
3e 3c c8 0d 25 4c 61 74 df aa ed b5 d5 b9 06 6a
8e b0 b7 c0 e6 c9 bf db b1 07 2e a2 76 aa e7 28
1c 8d 32 4e b3 58 1d 34 89 96 ed 3e da 29 e0 1e
c9 c2 2e 18 19 a6 ba 91 32 b7 85 97 87 92 16 c5
01 b4 4f 57 5c 56 1b f5 f4 6a 29 6b 2e 51 8b f5
4c 6f b8 fd cb 09 d9 fd 66 09 04 49 b6 ba 7e d0
af 70 3a 51 41 5a a5 04 bf 02 03 01

我现在使用的签名缓冲区是:

BYTE            bSignatureBuf[]     = {
        0x6A, 0x2E, 0xD9, 0xB0, 0xD8, 0x98, 0xEB, 0x4E, 0x92, 0x24, 0x9B, 0x12, 0xA8, 0x68, 0x65, 0x0C,
        0xC0, 0xD9, 0xD1, 0xC5, 0x67, 0xF3, 0xDF, 0xC8, 0xBB, 0xD9, 0x9D, 0x29, 0xD9, 0x2D, 0xEF, 0xB4,
        0xAC, 0x52, 0x8B, 0x50, 0x05, 0x7E, 0xA2, 0x59, 0xA1, 0xF4, 0x36, 0xB8, 0x73, 0x1A, 0x4D, 0x15,
        0xB7, 0x0B, 0xFE, 0xE3, 0x85, 0xDE, 0xD3, 0x52, 0x35, 0xD7, 0x30, 0x41, 0xF9, 0x6F, 0x06, 0x20,
        0x96, 0xAF, 0x47, 0x01, 0x78, 0x3D, 0xBC, 0xF3, 0x34, 0x90, 0x9E, 0xC5, 0xBC, 0xB4, 0xE2, 0x4F,
        0xFA, 0x29, 0x98, 0xBA, 0xF4, 0xDB, 0xAA, 0x33, 0x50, 0xC3, 0xDD, 0x9C, 0x97, 0x27, 0x61, 0x22,
        0x6E, 0x32, 0xFC, 0xC1, 0xF2, 0x0F, 0x80, 0xD9, 0x6D, 0x68, 0xC1, 0x17, 0x41, 0xAB, 0xC9, 0xD5,
        0x05, 0x30, 0x77, 0x28, 0x2D, 0x82, 0x23, 0x69, 0x6B, 0xB4, 0xD1, 0x30, 0xB8, 0x28, 0x8A, 0x2A,
        0xB3, 0x7A, 0x75, 0x75, 0xAF, 0xBB, 0xD4, 0x91, 0x48, 0x8F, 0x41, 0x5C, 0x21, 0x66, 0x60, 0xBF,
        0xD4, 0xC4, 0x35, 0xA9, 0xF0, 0x0A, 0x33, 0x36, 0xBE, 0xC9, 0xE8, 0xFC, 0xE9, 0xE8, 0x1D, 0xC7,
        0x48, 0x28, 0xC8, 0xE5, 0x63, 0xCB, 0x59, 0x96, 0x68, 0xAC, 0x30, 0xB4, 0x81, 0x84, 0x1E, 0x8E,
        0x51, 0x86, 0xC9, 0xD3, 0x4B, 0xD9, 0x7C, 0xE4, 0xCD, 0x67, 0x4C, 0x40, 0xB3, 0xF9, 0x0E, 0x97,
        0xC2, 0x02, 0x37, 0xE3, 0x73, 0x78, 0xCF, 0x5E, 0x0A, 0xAF, 0x90, 0x2E, 0xD7, 0xB6, 0x2D, 0xE8,
        0x6D, 0xB3, 0x5B, 0x16, 0xBF, 0x63, 0x74, 0xDB, 0x7C, 0x1B, 0xF9, 0x5B, 0xFD, 0xFE, 0xCA, 0xB1,
        0x7F, 0x55, 0xAF, 0x90, 0xC8, 0x35, 0xB6, 0x4A, 0x40, 0xFA, 0x35, 0xB2, 0x63, 0x04, 0x2D, 0x37,
        0x84, 0x90, 0x28, 0xCE, 0x86, 0xFB, 0xB0, 0xFA, 0x0A, 0x8A, 0x2D, 0x7C, 0xCE, 0x65, 0x5F, 0x14
    };

首先,您不应该像注释中给出的那样将二进制数据视为文本

更重要的是,您的签名是使用PKCS#1 SHA-1生成的,并且您的哈希函数指定了SHA-256——可能是使用PKCS#1[^1]。在签名生成和验证期间,必须使用相同的哈希函数

在使用公钥解密签名后,您可以通过在ASN.1描述中查找OID来查看所使用的哈希函数(以防您想知道如何找到所使用的哈希函数)

还要注意API中的这句话:

本机加密API使用小端字节顺序(ed:用于签名字节)

请注意,非M$world使用大端字节顺序

[^1]:与往常一样,Microsoft不会指定其应用的确切协议[^2]


[^2]:只要stackoverflow稍作努力,就可以正确查看标记脚注

您是否将文件中的数据作为字符串进行读写?不要这样做,因为它不是文本数据。是的。我使用的是signedData.txt文件,从该文件我将数据写入signedBuffer。此signedBuffer用于验证目的。您应该将签名数据视为二进制数据;并非所有二进制数据都表示有效的字符编码。如果你想要文本,你应该首先把它转换成base 64(当然,通过解码base 64数据,再转换成二进制)。是的,哈希算法是sha1。谢谢你指出这一点。我以字节数组格式本身获取签名,但没有将其转换为字符串,并且以相反的顺序获取签名。此外,我已将哈希算法更改为sha1,但签名仍然未验证。我认为这足以回答您的问题,除非您希望我们与您进行调试会话(我们不会)。我已使用OpenSSL验证了相同的签名。但我仍然想知道为什么这个签名没有使用CryptoAPI进行验证。顺便说一句,谢谢你的帮助。
BYTE            bSignatureBuf[]     = {
        0x6A, 0x2E, 0xD9, 0xB0, 0xD8, 0x98, 0xEB, 0x4E, 0x92, 0x24, 0x9B, 0x12, 0xA8, 0x68, 0x65, 0x0C,
        0xC0, 0xD9, 0xD1, 0xC5, 0x67, 0xF3, 0xDF, 0xC8, 0xBB, 0xD9, 0x9D, 0x29, 0xD9, 0x2D, 0xEF, 0xB4,
        0xAC, 0x52, 0x8B, 0x50, 0x05, 0x7E, 0xA2, 0x59, 0xA1, 0xF4, 0x36, 0xB8, 0x73, 0x1A, 0x4D, 0x15,
        0xB7, 0x0B, 0xFE, 0xE3, 0x85, 0xDE, 0xD3, 0x52, 0x35, 0xD7, 0x30, 0x41, 0xF9, 0x6F, 0x06, 0x20,
        0x96, 0xAF, 0x47, 0x01, 0x78, 0x3D, 0xBC, 0xF3, 0x34, 0x90, 0x9E, 0xC5, 0xBC, 0xB4, 0xE2, 0x4F,
        0xFA, 0x29, 0x98, 0xBA, 0xF4, 0xDB, 0xAA, 0x33, 0x50, 0xC3, 0xDD, 0x9C, 0x97, 0x27, 0x61, 0x22,
        0x6E, 0x32, 0xFC, 0xC1, 0xF2, 0x0F, 0x80, 0xD9, 0x6D, 0x68, 0xC1, 0x17, 0x41, 0xAB, 0xC9, 0xD5,
        0x05, 0x30, 0x77, 0x28, 0x2D, 0x82, 0x23, 0x69, 0x6B, 0xB4, 0xD1, 0x30, 0xB8, 0x28, 0x8A, 0x2A,
        0xB3, 0x7A, 0x75, 0x75, 0xAF, 0xBB, 0xD4, 0x91, 0x48, 0x8F, 0x41, 0x5C, 0x21, 0x66, 0x60, 0xBF,
        0xD4, 0xC4, 0x35, 0xA9, 0xF0, 0x0A, 0x33, 0x36, 0xBE, 0xC9, 0xE8, 0xFC, 0xE9, 0xE8, 0x1D, 0xC7,
        0x48, 0x28, 0xC8, 0xE5, 0x63, 0xCB, 0x59, 0x96, 0x68, 0xAC, 0x30, 0xB4, 0x81, 0x84, 0x1E, 0x8E,
        0x51, 0x86, 0xC9, 0xD3, 0x4B, 0xD9, 0x7C, 0xE4, 0xCD, 0x67, 0x4C, 0x40, 0xB3, 0xF9, 0x0E, 0x97,
        0xC2, 0x02, 0x37, 0xE3, 0x73, 0x78, 0xCF, 0x5E, 0x0A, 0xAF, 0x90, 0x2E, 0xD7, 0xB6, 0x2D, 0xE8,
        0x6D, 0xB3, 0x5B, 0x16, 0xBF, 0x63, 0x74, 0xDB, 0x7C, 0x1B, 0xF9, 0x5B, 0xFD, 0xFE, 0xCA, 0xB1,
        0x7F, 0x55, 0xAF, 0x90, 0xC8, 0x35, 0xB6, 0x4A, 0x40, 0xFA, 0x35, 0xB2, 0x63, 0x04, 0x2D, 0x37,
        0x84, 0x90, 0x28, 0xCE, 0x86, 0xFB, 0xB0, 0xFA, 0x0A, 0x8A, 0x2D, 0x7C, 0xCE, 0x65, 0x5F, 0x14
    };