Печать

Программное взаимодействие с УЦ CERTEX

 

 Как сформировать запрос на выпуск сертификата в формате PKCS#10?

  CPExportKey(hProv,hKey,0,PUBLICKEYBLOB_REQ_P10,0,pbData,&dwData);

  где:
    hKey - созданный ключ, для которого необходимо сформировать запрос.

  Примечания:
  Для формирования запроса в текстовом виде (PEM) вместо
PUBLICKEYBLOB_REQ_P10
    надо указать PUBLICKEYBLOB_REQ_P10_PEM.

  -------------------------------------------------------------------------------
  Как сформировать запрос на выпуск сертификата в формате PKCS#10, подписать  и вложить в PKCS#7?

  CPExportKey(hProv,hKey,hKeySign,PUBLICKEYBLOB_REQ_P7,0,pbData,&dwData);

  где:
    hKey - созданный ключ, для которого необходимо сформировать запрос.
    hKeySign - ключ подписи с действующим сертификатом.

  Примечания:
  Для формирования запроса в текстовом виде (PEM) вместо
PUBLICKEYBLOB_REQ_P7
    надо указать PUBLICKEYBLOB_REQ_P7_PEM.

  -------------------------------------------------------------------------------
  Как сформировать электронный документ в формате PKCS#7?

  CPSignHash(hProv,hHash,AT_SIGNATURE,NULL,CRYPT_SIGN_PKCS7,pbData,&dwData);

  hHash - вычисленный хэш на данные.

  Примечания:
  - Для формирования PKCS#7 в текстовом виде (Base64), нужно указать
флаг PKCS7_BASE64_ENCODING.
  - Для добавления в ЭД сертификатов, перед вызовом CPSignHash нужно
выполнить:
    CPSetHashParam(hProv,hHash,HP_PKCS7_CERTIFICATE,Cert,0);
    где:
      Cert - блоб с нужным сертификатом.
  - Для добавления в ЭД подписываемых данных, перед вызовом CPSignHash  
нужно выполнить:
    CPSetHashParam(hProv,hHash,HP_PKCS7_DATA_SIZE,(BYTE*)&len,0);
    CPSetHashParam(hProv,hHash,HP_PKCS7_DATA,Data,0);
    где:
      len - размер данных.
      Data - подписываемые данные.
  - Для добавления в ЭД подписываемых атрибутов, перед вызовом
CPSignHash нужно выполнить:
    CPSetHashParam(hProv,hHash,HP_PKCS9_CUR_OID,(BYTE*)OID_PKCS9_XXX,0);
    CPSetHashParam(hProv,hHash,HP_PKCS9A_SIZE,(BYTE*)&len,0);
    CPSetHashParam(hProv,hHash,HP_PKCS9A_DATA,(BYTE*)attr,0);
    где:
      OID_PKCS9_XXX - OID нужного атрибута.
      len - размер данных атрибута.
      attr - данные атрибута.
  - Для добавления в ЭД не подписываемых  атрибутов, перед вызовом
CPSignHash нужно выполнить:
    CPSetHashParam(hProv,hHash,HP_PKCS9_CUR_OID,(BYTE*)OID_PKCS9_XXX,0);
    CPSetHashParam(hProv,hHash,HP_PKCS9U_SIZE,(BYTE*)&len,0);
    CPSetHashParam(hProv,hHash,HP_PKCS9U_DATA,(BYTE*)attr,0);
    где:
      OID_PKCS9_XXX - OID нужного атрибута.
      len - размер данных атрибута.
      attr - данные атрибута.

  -------------------------------------------------------------------------------
  Как проверить электронный документ в формате PKCS#7?

  CPVerifySignature(hProv,hHash,pbData,dwData,hKey,0,0);

  где:
    pbData - блоб электронного документа в формате PKCS#7.
    dwData - размер блоба.
    hKey - открытый ключ подписавшего документ.

  Примечания:
  Если открытый ключ доступен в виде сертификата, то его можно получить
вызовом:
    CPImportKey(hProv,Cert,len,0,0,&hKey);
  Получить размер вложенных в ЭД данных:
    CPGetHashParam(hProv,hHash,HP_PKCS7_DATA_SIZE,(BYTE*)&dsize,&len,0);
  Получить вложенные в ЭД данные:
    CPGetHashParam(hProv,hHash,HP_PKCS7_DATA,data,&dsize,0);
  Узнать количество подписей в ЭД:
    CPGetHashParam(hProv,hHash,HP_PKCS7_SIGN_COUNT,(BYTE*)&scount,&len,0);
  Установить нужную подпись для работы:
    CPSetHashParam(hProv,hHash,HP_PKCS7_CUR_SIGN,(BYTE*)&num,0);
  Узнать серийный номер сертификата подписавшего:
    CPGetHashParam(hProv,hHash,HP_PKCS7_SI_SN,SN,&len,0);
  Узнать DN-имя подписавшего:
    CPGetHashParam(hProv,hHash,HP_PKCS7_SI_DN,DN,&len,0);
  Узнать алгоритм хэш:
    CPGetHashParam(hProv,hHash,HP_PKCS7_SI_HASH_AID,(BYTE*)&ai,&len,0);
  Узнать алгоритм подписи:
    CPGetHashParam(hProv,hHash,HP_PKCS7_SI_SIGN_AID,(BYTE*)&ai,&len,0);
  Узнать количество вложенных в ЭД сертификатов:
    CPGetHashParam(hProv,hHash,HP_PKCS7_CRT_COUNT,(BYTE*)&dw,&len,0);
  Получить все вложенные сертификаты:
    len=sizeof(Cert);
    if
(CPGetHashParam(hProv,hHash,HP_PKCS7_ENUM_CERT,Cert,&len,CRYPT_FIRST)) {
      do {
        // работа
        len=sizeof(Cert);
      } while(CPGetHashParam(hProv,hHash,HP_PKCS7_ENUM_CERT,Cert,&len,0));
    }
  Узнать значение подписываемого атрибута:
    CPSetHashParam(hProv,hHash,HP_PKCS9_CUR_OID,(BYTE*)OID_PKCS9_XXX,0);
    CPGetHashParam(hProv,hHash,HP_PKCS9A_SIZE,(BYTE*)&len,&dw,0);
    CPGetHashParam(hProv,hHash,HP_PKCS9A_DATA,(BYTE*)attr,&len,0);
  Узнать значение не подписываемого атрибута:
    CPSetHashParam(hProv,hHash,HP_PKCS9_CUR_OID,(BYTE*)OID_PKCS9_XXX,0);
    CPGetHashParam(hProv,hHash,HP_PKCS9U_SIZE,(BYTE*)&len,&dw,0);
    CPGetHashParam(hProv,hHash,HP_PKCS9U_DATA,(BYTE*)attr,&len,0);
  Узнать тип вложенных данных:
    ObjectInfoStr_t p7i;
    len=sizeof(p7i);
    p7i.object.pbData=Buf;
    p7i.object.cbData=size;
    CPGetProvParam(hProv,PP_PKCS7_CONTENT_OID,(BYTE*)&p7i,&len,0);

  -------------------------------------------------------------------------------
  Как зашифровать данные и сформировать цифровой пакет в формате PKCS#7?

  1. Устанавливаем сертификаты получателей:
    CPImportKey(hProv,Cert,len,0,0,&hExpKeyN);
  2. Создаем сессионный ключ:
    CPGenKey(hProv,CALG_GOST,CRYPT_EXPORTABLE,&hKey);
  3. Шифруем данные:
    CPEncrypt(hProv,hKey,0,TRUE,0,Data,&len,size);
  4. Формируем PKCS7 для N-го получателя
    
CPExportKey(hProv,hKey,hExpKeyN,SIMPLEBLOB_P7,CRYPT_DEFAULT_MODE,NULL,&len);
  5. Формируем результат
    CPExportKey(hProv,hKey,0,SIMPLEBLOB_P7,0,result,&len);

  Примечания:
  Если зашифрованные данные должны быть включены в PKCS#7, то перед его
формированием:
    CPSetKeyParam(hProv,hKey,KP_PKCS7_DATA_SIZE,(BYTE*)&len,0);
    CPSetKeyParam(hProv,hKey,KP_PKCS7_DATA,(BYTE*)Data,0);

  -------------------------------------------------------------------------------
  Как расшифровать данные в формате цифровой пакет (PKCS#7)?

  1. Устанавливаем цифровой пакет (PKCS#7):
    CPImportKey(hProv,Data,len,0,0,&hKey)) {
  2. Узнаем размер вложенных данных:
    CPGetKeyParam(hProv,hKey,KP_PKCS7_DATA_SIZE,(BYTE*)&len,&dw,0);
  3. Получаем данные:
    CPGetKeyParam(hProv,hKey,KP_PKCS7_DATA,Buf,&len,0);
  4. Расшифровываем данные:
    CPDecrypt(hProv,hKey,0,TRUE,0,Buf,&len);

  -------------------------------------------------------------------------------
  Как сформировать OCSP-запрос на получение статуса сертификата?

  1. Получим ключ на подпись:
    CPGetUserKey(hProv,AT_SIGNATURE,&hExpKey);
  2. Загружаем проверяемый сертификат:
    CPImportKey(hProv,Cert,len,0,0,&hKey);
  3. Формируем OCSP-запрос
    CPExportKey(hProv,hKey,hExpKey,PUBLICKEYBLOB_OCSP,0,Buf,&len);

  -------------------------------------------------------------------------------
  Как работать с ответом OCSP сервера?

  1. Установим ответ OCSP сервера:
    CPImportKey(hProv,Buf,len,0,0,&hKey);
  2. Узнаем время проверки статуса сервером OCSP:
   CPGetKeyParam(hProv,hKey,KP_OCSP_REP_TIME,Time,&len,0);
  3. Узнаем серийный номер проверенного сертификата:
    CPGetKeyParam(hProv,hKey,KP_OCSP_REP_CRT_SN,SN,&len,0);
  4. Узнаем статус проверяемого сертификата:
    CPGetKeyParam(hProv,hKey,KP_OCSP_REP_CRT_STATUS,(BYTE*)&dw,&len,0);
    // 0 - good; 1 - revoked; 2 - unknown
  5. Если сертификат был отозван, узнаем когда:
    CPGetKeyParam(hProv,hKey,KP_OCSP_REP_REV_TIME,Time,&len,0);
  6. Если сертификат был отозван, узнаем причину отзыва:
    CPGetKeyParam(hProv,hKey,KP_OCSP_REP_REV_REASON,(BYTE*)&dw,&len,0);
  7. Узнаем рекомендуемое время обновления "с":
    CPGetKeyParam(hProv,hKey,KP_OCSP_REP_THIS_UPD,Time,&len,0);
  8. Узнаем рекомендуемое время обновления "по":
    CPGetKeyParam(hProv,hKey,KP_OCSP_REP_NEXT_UPD,Time,&len,0);
  9. Получим сертификат подписавшего OCSP-ответ:
    CPGetKeyParam(hProv,hKey,KP_CERTIFICATE,Cert,&len,0);
    // Проверяем сертификат (см. примеры проверки, с учетом полномочий OCSP)
  10. Импортируем сертификат OCSP сервера:
    CPImportKey(hProv,Cert,len,0,0,&hKey);
  11. Проверяем подлинность ответа сервера:
    CPVerifySignature(hProv,0,Buf,len,hKey,NULL,CRYPT_OBJECT_OCSP);

  -------------------------------------------------------------------------------
  Как сформировать TSP-запрос на получение метки времени для указанного документа?

  1. Создеем хэш-объект
    CPCreateHash(hProv,CALG_TGR3411,0,0,&hHash);
  2. Хэшируем данные
    CPHashData(hProv,hHash,(BYTE*)Data,len,0);
  3. Устанавливаем политику использования TSP
    CPSetHashParam(hProv,hHash,HP_TIME_STAMP_OID,(BYTE*)tsp_policy,0);
  4. Если требуется чтобы TSP-сервер вложил свой сертификат:
    dw=1;
    CPSetHashParam(hProv,hHash,HP_TIME_STAMP_CRT,(BYTE*)&dw,0);
  5. Формируем запрос
    CPGetHashParam(hProv,hHash,HP_TIME_STAMP_REQ,Buf,&len,0);

  -------------------------------------------------------------------------------
  Как работать с ответом TSA сервера метки времени?

  1. Создеем хэш-объект:
    CPCreateHash(hProv,CALG_TGR3411,0,0,&hHash);
  2. Загружаем в него метку времени:
    CPSetHashParam(hProv,hHash,HP_TSTAMP_BODY,Buf,0);
  3. Узнаем статус обработки:
    CPGetHashParam(hProv,hHash,HP_TSTAMP_STSTUS,(BYTE*)&dw,&len,0);
  4. Узнаем хэш:
    CPGetHashParam(hProv,hHash,HP_TSTAMP_HASH,hash,&len,0);
  5. Узнаем политику:
    CPGetHashParam(hProv,hHash,HP_TSTAMP_POLICIE,policy,&len,0);
  6. Узнаем время:
    CPGetHashParam(hProv,hHash,HP_TSTAMP_TIME,Time,&len,0);
  7. Узнаем серийный номер метки времени:
    CPGetHashParam(hProv,hHash,HP_TSTAMP_SN,tsp_sn,&len,0);
  8. Узнаем NONCE:
    CPGetHashParam(hProv,hHash,HP_TSTAMP_NONCE,nonce,&len,0);
  9. Узнаем DN:
    CPGetHashParam(hProv,hHash,HP_TSTAMP_DN,DN,&len,0);

  Примечания:
  Так как ответ TSA сервера метки времени имеет формат PKCS#7, проверка
    подлинности осуществляется по аналогии с примерами проверки подписи
PKCS#7.
  Для добавления метки времени в электронный документ она помещается как
не подписываемый
    атрибут и имеет OID - OID_PKCS9_TIMESTAMPATTR.

  -------------------------------------------------------------------------------
  Как проверить подлинность сертификата?

  CPVerifySignature(hProv,0,Cert,len,0,NULL,CRYPT_OBJECT_CRT);

  -------------------------------------------------------------------------------
  Как проверить валидность сертификата?

  1. Загружаем проверяемый сертификат:
    CPImportKey(hProv,Cert,len,0,0,&hKey);
  2. Получим информацию о валидности:
    CPGetKeyParam(hProv,hKey,KP_CRT_VFROM,(BYTE*)vfr,&len,0);
    CPGetKeyParam(hProv,hKey,KP_CRT_VTO,  (BYTE*)vto,&len,0);
  3. Посмотрим текущее время:
    CPGetProvParam(hProv,PP_SYS_TIME,(BYTE*)cur,&len,0);
  4. Проверяем валидность:
    if (memcmp(vfr,cur,14)>0) Error;
    if (memcmp(vto,cur,14)<0) error="" p="">

  -------------------------------------------------------------------------------
  Как проверить права использования ключа сертификата?

  1. Получим информацию о правах использования ключа:
    CPGetKeyParam(hProv,hKey,KP_CRT_USAGE,(BYTE*)&dw,&len,0);
  2. Проверим, например, можно ли использовать ключ для создания ЭЦП ?
    if (dw & CRT_KEYUSAGE_DIGSIGN) - OK;
    else                           - Error;

  -------------------------------------------------------------------------------
  Как проверить полномочия ключа сертификата?

  1. Получим информацию о полномочиях ключа:
    CPGetKeyParam(hProv,hKey,KP_CRT_PURPOSES,(BYTE*)&dw,&len,0);
  2. Проверим, например, можно ли использовать ключ для подписи
OCSP-ответов ?
  if (dw&CRT_PURPOSE_OCSP) - OK;
  else                     - Error;

  -------------------------------------------------------------------------------
  Как проверить политики использования сертификата?

  Получим информацию о всех политиках сертификата:
  len=sizeof(policy);
  if
(CPGetKeyParam(hProv,hKey,KP_CRT_ENUM_POLICIES,(BYTE*)policy,&len,CRYPT_FIRST))
    do {
      // принимаем решение по полученной политике
      len=sizeof(policy);
    }
while(CPGetKeyParam(hProv,hKey,KP_CRT_ENUM_POLICIES,(BYTE*)policy,&len,0));

  -------------------------------------------------------------------------------
  Как проверить статус сертификата с использованием СОС?

  1. Импортируем СОС
    CPImportKey(hProv,CRL,len,0,0,&hCRL);
  2. Проверяем статус сертификата
    CPVerifySignature(hProv,0,Cert,len,hCRL,NULL,CRYPT_OBJECT_REV);

  -------------------------------------------------------------------------------
  Как проверить подлинность COC?

  CPVerifySignature(hProv,0,CRL,len,0,NULL,CRYPT_OBJECT_CRL);