вопрос по ЭЦП.

Автор sudv, 18 Февраль 2014, 20:26:07

« предыдущая тема - следующая тема »

0 Пользователей и 1 Гость просматривают эту тему.

Вниз

sudv

Добрый день.

Можно ли имея подписанное сообщение вытащить из него открытый ключ, которым это сообщение было подписано?

С уваженеим, Дмитрий Сураев.


Sergey

Добрый день.

Все зависит от того в какой формат упакована подпись.

sudv

Подпись оказалась подписаным сообщением PKCS#7

Как можно вытащить из него подписаное сообщение используя библиотеку strlib?

И как можно проверить сообщение PKCS#7 на целостность, пользуясь библиотекой strlib?

xthtp tumarCom и .net разобрался, а вот с strlib есть с этим проблеммы.

С уважением, Дмитрий Сураев.

PS сообщение в base64:

MIIF3wYJKoZIhvcNAQcCoIIF0DCCBcwCAQExEDAOBgorBgEEAbURAQIBBQAwgf8GCSqGSIb3DQEHAaCB8QSB7igEMAQ5BDwENQRABDQENQQ9BD4EMgQwBA0ACgAWBDAEPQQwBEIEDQAKABoEMAQ7BDgENQQyBD0EMAQNAAoAMwAzADUANgA1ADkADQAKADAANQAwADcANwA5AA0ACgA3ADkAMAA3ADAANQA0ADAAMQAxADQAOQANAAoAMwA5ADAANQA2ADQADQAKADkAOAA3ADYANQA0ADMAMgAxAA0ACgAzADAAMAAwADAAMAAwADAADQAKAA0ACgBLAFoAVAANAAoANAAyADYAMwA0ADUAKgAqACoAKgAqACoAMgAyADcAMwANAAoAMgA2ADAAMACgggMYMIIDFDCCAr2gAwIBAgIgbn1GIlcP73+5jLzS6aLmWUADN6mVuQc+eld4hsZ7UcYwDgYKKwYBBAG1EQECAgUAMDMxFTATBgNVBAMTDEtJU0MgQmV0YSBDQTENMAsGA1UEChMES0lTQzELMAkGA1UEBhMCS1owHhcNMTMwNjIxMTE0NDMzWhcNMTQwNjIxMTE0OTMzWjBWMQswCQYDVQQGEwJLWjEjMCEGA1UECgwa0JTQkSDQkNCeINCh0JHQtdGA0JHQsNC90LoxIjAgBgNVBAMMGdCc0LDRhdC90LjQvSDQodCV0KDQk9CV0JkwYzAOBgorBgEEAbURAQUIBQADUQAGAgAAOqoAAABFQzEAAgAAoSPCbEni3JIjeakazmt4FPWTUuvRIJNkrytYYRBFSBsz8fXKMUcplCQreq4moJC4oQ7gnO+cb2YHwT7sPWqHb6OCAXAwggFsMAsGA1UdDwQEAwIDyDBrBgNVHR8EZDBiMC+gLaArhilodHRwOi8vYmV0YWNhLmtpc2Mua3ovY2dpL1Jldkxpc3RHT1NULmNybDAvoC2gK4YpaHR0cDovL2JldGFjYS5raXNjLmt6L2NnaS9SZXZMaXN0R09TVC5jcmwwPAYIKwYBBQUHAQEEMDAuMCwGCCsGAQUFBzABhiBodHRwOi8vYmV0YWNhLmtpc2Mua3ovY2dpL3N0YXR1czApBgNVHQ4EIgQgbn1GIlcP73+5jLzS6aLmWUADN6mVuQc+eld4hsZ7UcYwgYYGA1UdIwR/MH2AIIejoUiTXZIVpaS26fcNmRPGBtHDY0LdDIwBYY2F5YXroTekNTAzMRUwEwYDVQQDEwxLSVNDIEJldGEgQ0ExDTALBgNVBAoTBEtJU0MxCzAJBgNVBAYTAktagiCHo6FIk12SFaWktun3DZkTxgbRw2NC3QyMAWGNheWF6zAOBgorBgEEAbURAQICBQADQQDnm92NYNRw037sWOQx+YFbGySZRlWeuT0BGdo3drvRsVNwp7mpYaTS4pkedOJ/h7EtE8XgoCUDS8fkE742w6aZMYIBlTCCAZECAQEwVzAzMRUwEwYDVQQDEwxLSVNDIEJldGEgQ0ExDTALBgNVBAoTBEtJU0MxCzAJBgNVBAYTAktaAiBufUYiVw/vf7mMvNLpouZZQAM3qZW5Bz56V3iGxntRxjAOBgorBgEEAbURAQIBBQCggdAwGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMTMxMjE3MDQwNjU4WjAvBgkqhkiG9w0BCQQxIgQg9fKuzS8eBKykHaPhtqSmc8WuVuheJV8GAYOhhOVQp+swZQYJKwYBBAG1EQIIMVgwVjELMAkGA1UEBhMCS1oxIzAhBgNVBAoMGtCU0JEg0JDQniDQodCR0LXRgNCR0LDQvdC6MSIwIAYDVQQDDBnQnNCw0YXQvdC40L0g0KHQldCg0JPQldCZMA4GCisGAQQBtREBBQgFAARA+Miw6MBrk45MEkdHD1f4aDxOe6elL7mD1eeUXVEa3ekG6d8lr5uIex9V9KT24alD3FnoqQhab0NkzwHZJR4MvA==


Sergey

Добрый день.

Для этого необходимо выполнить следующие шаги:
Получить хендл на криптопровайдер
retCode = CSPOpenContext(&hProv, NULL, 25, 0, CRYPT_VERIFYCONTEXT, NULL, 0,NULL,NULL, NULL);
Получить хендл на хранилище сертификатов
retCode = CrtOpenStore(0, hProv, 0, false, NULL, &hStore);
Получить коллекцию на сертификаты вложенные в PKCS#7
retCode=GetMessageCertificate(hStore,cmsBlob,cmsSize,&hCollection);
Получить хендл для работы с PKCS#7
retCode = SignMsgOpen(hProv, 0, &hSign);
Получить количество подписавших
retCode = MessageKeysCount(cmsBlob, cmsSize, &countSender);
Проверить подпись и получить данные о подписи (память выделяет вызывающая программа)
retCode=VerifySignMessage(hSign, hCollection, cmsBlob, cmsSize, 0 ,SignerName, timeToSigned, dataDescriptor, dataToSigned, &dataSize, dataOID, &VerifyRes);
Закрыть все открытые хендлы
       
if(hCollection)
FreeCertificateCollection(&hCollection);
if(hSign)
SignMsgClose(&hSign);
if(hStore)
CrtCloseStore(&hStore);
if(hProv)
CSPCloseContext(&hProv);



sudv

Сергей, большое спасибо за оперативный ответ.

а как реализовать r =  ObjectTumarCom.ParsePKCS7(pkcs7)?
т.е. получить подписаный контент?

С уважением, Дмитрий Сураев.

Sergey

Функция VerifySignMessage возвращает подписанный контент.

sudv

Спасибо Сергей, помогли.

Разбираю пример "Расширенная проверка электронного документа".
Есть трудности с p7i.object.pbData

можно реализовать этот функционал без структкуры, т.е. подставить блок памяти правильно его заполнив?

len=sizeof(p7i);
p7i.object.pbData=WBuf;
p7i.object.cbData=sz;
if (!CPGetProvParam(hProv,PP_PKCS7_CONTENT_OID,(BYTE*)&p7i,&len,0)) {
printf("CPGetProvParam Error: %0X\n",GetLastErrorCSP(hProv));
return 1;


Sergey

Добрый день.

Представить структуру как блок памяти можно.
А для чего нужно использовать эту функцию, по большому счету можно обойтись и без нее.

sudv

Добрый день Сергей.

Мне уже теперь нужно на ТУМАР-CSP сделать тоже самое для PKCS#7

1. вытащить подписаный контент.
2. проверить подпись.

sudv

При этом также контент и сертификат лежит в томже самом сообщении.

С уважением, Дмитрий Сураев.

Sergey

Чтобы извлечь данные из PKCS#7 необходимо
1. Загрузить криптопровайдер cpAcquireContext
2. Создать объект hash cpCreateHash
3. Установить PKCS#7 cpSetHashParam с флагом HP_PKCS7_BODY
4. Извлечь данные cpGetHashParam с флагом HP_PKCS7_DATA, если нужно узнать размер то вызвать с флагом HP_PKCS7_DATA_SIZE
5. Узнать количество сертификатов cpGetHashParam с флагом HP_PKCS7_CRT_COUNT
6. Извлечь сертификаты cpGetHashParam с флагом HP_PKCS7_ENUM_CERT с параметром CRYPT_FIRST для первого сертификата и CRYPT_NEXT
7. Установить сертификат CPImportKey
8. Проверить подпись CPVerifySignature

sudv

Сергей, большое спасибо.
Выполняю Установить PKCS#7 cpSetHashParam с флагом HP_PKCS7_BODY
, при этом получаю ошибку
80090011   NTE_NOT_FOUND   Object was not found
Подскажите пожалуйста что это обозначает и как с этим бороться.

PS на всякий случай:

   /* 1. Загрузить криптопровайдер cpAcquireContext */
   DEFINE VARIABLE vNULL AS MEMPTR NO-UNDO.
   SET-SIZE(vNULL) = 1.
   
   RUN CPAcquireContext(OUTPUT phProv , vNULL , {&CRYPT_VERIFYCONTEXT} ,
                        vNULL ,  OUTPUT ret-val).
//вернула 1

   /* 2. Создать объект hash cpCreateHash */
   hProv = GET-INT64 (phProv,1).
   RUN CPCreateHash ( hProv , {&CALG_TGR3411}
                    , 0 , 0 , OUTPUT phHash , OUTPUT ret-val).
//вернула 1

   /* 3. Установить PKCS cpSetHashParam с флагом HP_PKCS7_BODY */
   /* расшифровать из base64 */
   DEFINE VARIABLE WBuf AS MEMPTR    NO-UNDO.
   WBuf = BASE64-DECODE( DSKey ).

   RUN CPSetHashParam ( hProv , phHash , {&HP_PKCS7_BODY} , WBuf ,0, OUTPUT ret-val).
//вернула 0

//получим код ошибки
   IF ret-val NE 1 THEN
   DO:
      DEFINE VARIABLE hexError   AS CHARACTER NO-UNDO.
   
      /* адрес памти для буффера данных  */
      DEFINE VARIABLE pData              AS MEMPTR     NO-UNDO.
      /* адрес памти для значения длины буфера  данных  pbData */
      DEFINE VARIABLE pDataLen           AS MEMPTR     NO-UNDO.
   
      SET-SIZE(pData)               = 4. /* ссылка буффер */
      SET-SIZE(pDataLen)            = 4. /* должно лежать число Integer */
      PUT-UNSIGNED-LONG(pDataLen,1) = 4.


      RUN CPGetProvParam(hProv, {&PP_LAST_ERROR}, OUTPUT pData, INPUT-OUTPUT pDataLen, 0, OUTPUT ret-val).
      hexError = hex( GET-UNSIGNED-LONG (PDATA,1) ).

      MESSAGE "CPGetProvParam" "Код ошибки: " + hexError
         VIEW-AS ALERT-BOX INFO BUTTONS OK.
   END.

Sergey

Добрый день.
Выложите PKCS#7 на котором выдается данная ошибка.

sudv

Добрый день Сергей.

сообщение в base64. я его декодирую в буфер памяти.
При этом используя Тумар com оно раскодируется проверяется, вообщем все отлично.

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

sudv

эту ошибку преодолел, теперь другая.
Mismatch in the parameter datatypes in DLL procedure CPSetHashParam
Это уже на моей стороне, разбираюсь

Вверх