02.08.2006 18:01:46Проверка подписи CP* функциями Ответов: 4
Дмитрий
Здравствуйте.
Ранее я сдавал вопросы связанные с данной темой, однако полученные советы не помогли, поэтому я решил создать отдельную тему.

Итак, подпись создается функциями высокого уровня а именно CryptSignMessage(...), далее пытаюсь проверить эту подпись функцией CPVerifySignature(...) и получаю ошибку "Ошибка 2148073478: Неправильная подпись.", хотя эта же подпись функцией CryptVerifyMessageSignature(...) верифицируется нормально.

Я делаю следующее:
1) Выделяю алгоритм хеширования
hashAlg = CertOIDToAlgId((LPCSTR)data);
[out]hashAlg = 32798
2) Ввыделяю подписываемое сообщение, копированием определенного количества байтов следующий после OID "1.2.840.113549.1.7.1"
3) Выделяю сертификат отправителя
3.1) из него выделяю блоб открытого ключа
3.2) привожу ключ к виду, пригодному для импортирования.
4) Получаю значение подписи, таким же образом как и подписываемые данные
5) Получаю дескриптор CSP
PTableProvStruc *pVTable;
...
pVTable->Version = 3;
pVTable->FuncVerifyImage = &FunVerifyImage;
pVTable->FuncReturnhWnd = &FunReturnHWnd;
pVTable->pszProvName = "Crypto-Pro GOST R 34.10-2001 Cryptographic Service Provider";
pVTable->dwProvType = 75;
pVTable->cbContextInfo = 0;
pVTable->pbContextInfo = NULL;
CPAcquireContext(&hCpProv, NULL, CRYPT_VERIFYCONTEXT, pVTable);
Функция CPAcquireContext возвращает true
6) импортирую открытый ключ
CPImportKey(hCpProv,pbImportBlob,dwImportBlobSize,0,0,&key);
Функция CPImportKey возвращает true
7) Создаю объект функции хеширования
CPCreateHash(hCpProv,hashAlg,0,0,&hHash)
Функция CPCreateHash возвращает true
8) Вычисляю хеш данных
CPHashData(hCpProv,hHash,captionOfFile,sizeOfFile,0);
Функция CPHashData возвращает true
9) И все это передаваю в CPVerifySignature
CPVerifySignature(hCpProv,hHash,hash,hashSize,hImportedKey,NULL,0)
Функция возвращает false, ошибка: "2148073478: Неправильная подпись"

В чем может быть ошибка, или я чего-то не делаяю, или же наоборот что-то лишнее делаю.

При просмотре файлика через программу DumpAsn1 вижу следеющее:
SEQUENCE {
OBJECT IDENTIFIER '1 2 840 113549 1 7 2'
[0] {
SEQUENCE {
INTEGER 1
SET {
SEQUENCE {
OBJECT IDENTIFIER '1 2 643 2 2 9'
NULL
}
}
SEQUENCE {
OBJECT IDENTIFIER '1 2 840 113549 1 7 1'
[0] {
OCTET STRING 'dsgdfghfdjkhfjkjhgfsdgfh'
}
}
[0] {
SEQUENCE {
SEQUENCE {
[0] {
INTEGER 2
}
INTEGER
53 CB 7F E5 00 01 00 00 11 F3
SEQUENCE {
OBJECT IDENTIFIER '1 2 643 2 2 3'
NULL
}
SEQUENCE {
SET {
SEQUENCE {
OBJECT IDENTIFIER '1 2 840 113549 1 9 1'
IA5String 'info@cryptopro.ru'
}
}
SET {
SEQUENCE {
OBJECT IDENTIFIER '2 5 4 6'
PrintableString 'RU'
}
}
SET {
SEQUENCE {
OBJECT IDENTIFIER '2 5 4 10'
PrintableString 'CRYPTO-PRO'
}
}
SET {
SEQUENCE {
OBJECT IDENTIFIER '2 5 4 3'
PrintableString 'Test Center CRYPTO-PRO'
}
}
}
SEQUENCE {
UTCTime '060727063324Z'
UTCTime '070727064324Z'
}
SEQUENCE {
SET {
SEQUENCE {
OBJECT IDENTIFIER '2 5 4 6'
PrintableString 'RU'
}
}
SET {
SEQUENCE {
OBJECT IDENTIFIER '2 5 4 3'
PrintableString 'inch'
}
}
}
SEQUENCE {
SEQUENCE {
OBJECT IDENTIFIER '1 2 643 2 2 19'
SEQUENCE {
OBJECT IDENTIFIER '1 2 643 2 2 36 0'
OBJECT IDENTIFIER '1 2 643 2 2 30 1'
}
}
BIT STRING 0 unused bits, encapsulates {
OCTET STRING
B9 6B E2 27 2A 52 04 C4 D6 77 D5 B4 D6 8F 2C D8
5C 47 F6 CA 29 31 1C 48 86 09 CC 82 01 A7 AC A3
27 FE 14 84 A8 39 86 90 C5 9F 09 4E CB 98 0E 8B
9F C3 A7 02 0A 94 AB C6 55 9D 60 5D 20 3E 64 F8
}
}
[3] {
SEQUENCE {
SEQUENCE {
OBJECT IDENTIFIER '2 5 29 15'
BOOLEAN TRUE
OCTET STRING, encapsulates {
BIT STRING 4 unused bits
'1111'B
}
}
SEQUENCE {
OBJECT IDENTIFIER '1 2 840 113549 1 9 15'
OCTET STRING, encapsulates {
SEQUENCE {
SEQUENCE {
OBJECT IDENTIFIER '1 2 643 2 2 21'
}
}
}
}
SEQUENCE {
OBJECT IDENTIFIER '2 5 29 14'
OCTET STRING, encapsulates {
OCTET STRING
41 7D 04 4C 02 9F B3 67 F5 23 BA 45 D3 53 38 B4
20 30 19 0C
}
}
SEQUENCE {
OBJECT IDENTIFIER '2 5 29 37'
OCTET STRING, encapsulates {
SEQUENCE {
OBJECT IDENTIFIER '1 3 6 1 5 5 7 3 2'
}
}
}
SEQUENCE {
OBJECT IDENTIFIER '2 5 29 35'
OCTET STRING, encapsulates {
SEQUENCE {
[0]
48 55 30 18 CB 3C 22 A9 17 D7 62 62 64 05 A7 A4
CC 86 8A 11
}
}
}
SEQUENCE {
OBJECT IDENTIFIER '2 5 29 31'
OCTET STRING, encapsulates {
SEQUENCE {
SEQUENCE {
[0] {
[0] {
[6]
'http://www.cryptopro.ru/certenroll/Test%20Center'
'%20CRYPTO-PRO.crl'
}
}
}
}
}
}
SEQUENCE {
OBJECT IDENTIFIER '1 3 6 1 5 5 7 1 1'
OCTET STRING, encapsulates {
SEQUENCE {
SEQUENCE {
OBJECT IDENTIFIER '1 3 6 1 5 5 7 48 2'
[6]
'http://www.cryptopro.ru/CertEnroll/Crypto.crypto'
'pro.ru_Test%20Center%20CRYPTO-PRO(1).crt'
}
SEQUENCE {
OBJECT IDENTIFIER '1 3 6 1 5 5 7 48 1'
[6] 'http://www.cryptopro.ru/ocsp/ocsp.srf'
}
SEQUENCE {
OBJECT IDENTIFIER '1 3 6 1 5 5 7 48 1'
[6] 'http://www.cryptopro.ru/ocspnc/ocsp.srf'
}
}
}
}
}
}
}
SEQUENCE {
OBJECT IDENTIFIER '1 2 643 2 2 3'
NULL
}
BIT STRING 0 unused bits
CC A9 6E DF 1D 3C 09 A1 E6 E2 A0 C2 54 44 42 19
AA EF 9C 66 FC 0B 83 AF 24 8A 68 92 CD DB F3 0C
49 41 89 F0 77 BA 40 02 B9 B3 86 D9 A9 AE EC 4E
F5 B9 05 76 70 6E EC B7 D0 53 EF E4 34 E6 F7 85
}
}
SET {
SEQUENCE {
INTEGER 1
SEQUENCE {
SEQUENCE {
SET {
SEQUENCE {
OBJECT IDENTIFIER '1 2 840 113549 1 9 1'
IA5String 'info@cryptopro.ru'
}
}
SET {
SEQUENCE {
OBJECT IDENTIFIER '2 5 4 6'
PrintableString 'RU'
}
}
SET {
SEQUENCE {
OBJECT IDENTIFIER '2 5 4 10'
PrintableString 'CRYPTO-PRO'
}
}
SET {
SEQUENCE {
OBJECT IDENTIFIER '2 5 4 3'
PrintableString 'Test Center CRYPTO-PRO'
}
}
}
INTEGER
53 CB 7F E5 00 01 00 00 11 F3
}
SEQUENCE {
OBJECT IDENTIFIER '1 2 643 2 2 9'
NULL
}
SEQUENCE {
OBJECT IDENTIFIER '1 2 643 2 2 19'
NULL
}
OCTET STRING
96 07 3E 7C CC B5 9C 83 60 BE 4E E0 85 B6 78 3E
18 95 7B 7C 10 13 64 76 1C CB 0C CA F4 DE E2 09
B0 2E E3 78 B8 04 DF 3C CD 60 B0 B8 6D B0 1B C6
5E 28 FB 40 2E 09 53 4A 4B 6D 44 02 1B 9A 2E 7A
}
}
}
}
}

Сравнил подпись получаемую моей программой с подписью полученнной функцией CryptMsg*. Они получились идентичными.
 
Ответы:
03.08.2006 11:18:49Kirill Sobolev
Мб проблема в п.4) Получаю значение подписи, таким же образом как и подписываемые данные?
Косвенно на это указывает то, что 2 идентичные подписи по ГОСТу получаться не могут - в создании подписи участвует случайное число.
03.08.2006 12:12:57Дмитрий
Возможно Вы меня не так поняли.
В пункте 4 я выделяю подпись из сообщения в формате PKCS7. Например из файла, который приведен выше, я получаю указатель на буфер (который в последствии передается в функцию CPVerifySignature(...pbSignature,cbSignature...)):
96 07 3E 7C CC B5 9C 83 60 BE 4E E0 85 B6 78 3E
18 95 7B 7C 10 13 64 76 1C CB 0C CA F4 DE E2 09
B0 2E E3 78 B8 04 DF 3C CD 60 B0 B8 6D B0 1B C6
5E 28 FB 40 2E 09 53 4A 4B 6D 44 02 1B 9A 2E 7A

в бинарном виде естественно, иначе я не понял что Вы хотели сказать.
08.08.2006 7:38:40Дмитрий
Здравствуйте.
А может быть причиной отрицательной верификации, то что при получении подписи из сообщения, помимо кодирования на закрытом ключе она еще и кодируется при переводе ее в OCTET STRING при "сборки" сообщения в PKCS#7, а CPVerifySignature (да как и CryptVerifySignature) хочет разкодированный?
08.08.2006 12:41:58Kirill Sobolev
Если у Вас вытащенная подпись совпадает с тем, что выдает dumpasn1, то все нормально, значит Вы вытаскиваете не ASN.
Кодируется она простым переворотом (как BIT STRING), т.е. 7A 2E ... 07 96 в Вашем случае.