Ключевое слово в защите информации
КЛЮЧЕВОЕ СЛОВО
в защите информации
Получить ГОСТ TLS-сертификат для домена (SSL-сертификат)
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline Серёня  
#1 Оставлено : 10 марта 2014 г. 11:42:27(UTC)
Серёня

Статус: Участник

Группы: Участники
Зарегистрирован: 03.03.2014(UTC)
Сообщений: 22
Мужчина
Российская Федерация
Откуда: Москва

Сказал «Спасибо»: 2 раз
Здравствуйте.

Необходимо из сертификата получить СНИЛС. На сколько я понял, то он хранится в szOID_SNILS "1.2.643.100.3" и , вроде бы, его можно прочитать с помощью функции CryptExportPublicKeyInfoEx.
Однако я не совсем понимаю, как ее использовать. Описание функции выглядит вот так
Код:
BOOL WINAPI CryptExportPublicKeyInfoEx(
  _In_     HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hCryptProvOrNCryptKey,
  _In_     DWORD dwKeySpec,
  _In_     DWORD dwCertEncodingType,
  _In_     LPSTR pszPublicKeyObjId,
  _In_     DWORD dwFlags,
  _In_     void *pvAuxInfo,
  _Out_    PCERT_PUBLIC_KEY_INFO pInfo,
  _Inout_  DWORD *pcbInfo
);

Так вот, должна ли быть проинициализирована структура CERT_PUBLIC_KEY_INFO? если должна, то каким образом? Что-то не могу сообразить. Если не инициализировать, то segfault случается.
И как потом из этой структуры получить СНИЛС? Он будет в pPublicKeyInfo->PublicKey.pbData?

На всякий случай приложу описание структур
Код:
typedef struct _CERT_PUBLIC_KEY_INFO {
  CRYPT_ALGORITHM_IDENTIFIER Algorithm;
  CRYPT_BIT_BLOB             PublicKey;
} CERT_PUBLIC_KEY_INFO, *PCERT_PUBLIC_KEY_INFO;

typedef struct _CRYPT_BIT_BLOB {
  DWORD cbData;
  BYTE  *pbData;
  DWORD cUnusedBits;
} CRYPT_BIT_BLOB, *PCRYPT_BIT_BLOB;

typedef struct _CRYPT_ALGORITHM_IDENTIFIER {
  LPSTR            pszObjId;
  CRYPT_OBJID_BLOB Parameters;
} CRYPT_ALGORITHM_IDENTIFIER, *PCRYPT_ALGORITHM_IDENTIFIER;

Отредактировано пользователем 11 марта 2014 г. 14:02:22(UTC)  | Причина: Не указана

Online Андрей Писарев  
#2 Оставлено : 10 марта 2014 г. 14:21:32(UTC)
Андрей *

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 13,513
Мужчина
Российская Федерация

Сказал «Спасибо»: 554 раз
Поблагодарили: 2252 раз в 1757 постах
Функция CryptExportPublicKeyInfoEx экспортирует информацию об открытом ключе.
Техническую поддержку оказываем тут
Наша база знаний
Online Андрей Писарев  
#3 Оставлено : 10 марта 2014 г. 14:32:51(UTC)
Андрей *

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 13,513
Мужчина
Российская Федерация

Сказал «Спасибо»: 554 раз
Поблагодарили: 2252 раз в 1757 постах
Извлечь можно с помощью CertGetNameString
Техническую поддержку оказываем тут
Наша база знаний
thanks 1 пользователь поблагодарил Андрей * за этот пост.
Серёня оставлено 11.03.2014(UTC)
Offline Серёня  
#4 Оставлено : 11 марта 2014 г. 11:58:44(UTC)
Серёня

Статус: Участник

Группы: Участники
Зарегистрирован: 03.03.2014(UTC)
Сообщений: 22
Мужчина
Российская Федерация
Откуда: Москва

Сказал «Спасибо»: 2 раз
Воспользовался функцией CertGetNameString, но получаю "E_NOTIMPL 0x80004001L". Вот тут http://www.cryptopro.ru/...ts&m=30146#post30146 написано что эта функция реализована только для CERT_NAME_SIMPLE_DISPLAY_TYPE но, как я понял, мне нужно СERT_NAME_ATTR_TYPE ? реализовано ли это на данный момент? как получить СНИЛС под unix?
Offline Мясников Роман  
#5 Оставлено : 12 марта 2014 г. 10:11:12(UTC)
Мясников Роман

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 27.01.2012(UTC)
Сообщений: 338

Сказал(а) «Спасибо»: 1 раз
Поблагодарили: 41 раз в 41 постах
Если хочешь посмотреть информацию о сертификате, попробуй использовать openssl.
Например:
./openssl x509 -in файл_сертификата -text -inform der
Offline Серёня  
#6 Оставлено : 12 марта 2014 г. 13:14:04(UTC)
Серёня

Статус: Участник

Группы: Участники
Зарегистрирован: 03.03.2014(UTC)
Сообщений: 22
Мужчина
Российская Федерация
Откуда: Москва

Сказал «Спасибо»: 2 раз
Что? зачем мне openSSL? Я пытаюсь работать с CSP 3.6 через capilite под linux.
Offline Katarina  
#7 Оставлено : 13 марта 2014 г. 17:40:34(UTC)
Katarina

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 13.03.2014(UTC)
Сообщений: 1
Российская Федерация
Откуда: Москва

Вот код программы, которая ищет СНИЛС в файле сертификата c именем "cert.cer" и выводит его значение на экран.

1. кладем сертификат в папку с кодом.
2. собираем исполняемый файл:
Код:
eval `/opt/cprocsp/src/doxygen/setenv.sh --32`; g++ -DUNIX -DHAVE_LIMITS_H -DHAVE_STDINT_H -I/opt/cprocsp/include -I/opt/cprocsp/include/cpcsp -I/opt/cprocsp/include/asn1c/rtsrc -I/opt/cprocsp/include/asn1data -DSIZEOF_VOID_P=4 -L/opt/cprocsp/lib/ia32 -lasn1data -lssp -lcapi10 -lcapi20 -lpthread /tmp/snils.c 

3../a.out - получаем строку со значением СНИЛСа

код программы:

Код:

#include <stdio.h>
#ifdef _WIN32
#   include <windows.h>
#   include <wincrypt.h>
#else
#   include <stdlib.h>
#   include <string.h>
#   include <CSP_WinDef.h>
#   include <CSP_WinCrypt.h>
#endif
#include <WinCryptEx.h>

#include <locale.h>


static void HandleError(char *s);
static PCCERT_CONTEXT ReadCertFromFile (const TCHAR *fname);


PCCERT_CONTEXT ReadCertFromFile (const TCHAR *infile)
{
    BYTE                *cert = NULL;
    DWORD               len = 0;
    PCCERT_CONTEXT      ret = NULL;
    FILE                *f = NULL;
    size_t              mem_len = 0;
    int                 flag = 0;
    unsigned char       *mem_tbr = NULL;

    //-------------------------------------------------------------------
    //  get file data pointer
    //-------------------------------------------------------------------
    //  open file 
    if (infile  == NULL) 
    {
        fprintf (stderr, "No file specified\n");
        goto err;
    }
    f = fopen (infile, "rb");
    if (!f) 
    {
        fprintf (stderr, "Cannot open input file\n");
        goto err;
    }
    //-------------------------------------------------------------------
    // read file 
    mem_len = 0;
    mem_tbr = NULL;
    if (fseek(f, 0, SEEK_END) == 0) 
    {
        long fl_len = ftell(f);
        if (fl_len == -1) 
            goto err;

        mem_len = (size_t)fl_len;
        if ((long)mem_len != fl_len)
            goto err;
        if (mem_len) 
        {
            if ((mem_tbr = (unsigned char*)malloc(mem_len)) == NULL) 
                goto err;
            if (fseek(f, 0, SEEK_SET)) 
                goto err;
            if (fread (mem_tbr, mem_len, 1, f) != 1) 
                if (ferror(f))
                    goto err;
        }
    }

    len = mem_len;
    cert = mem_tbr;

    //-------------------------------------------------------------------

    ret = CertCreateCertificateContext ( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, cert, len);
    if (!ret) 
    {
        fprintf (stderr, "The public key can not be written to file.\n");
        goto err;
    }
    //-------------------------------------------------------------------
    //  release file data pointer
    if (cert) free (cert); 

    flag = 1;
err:
    if (f) fclose (f);
    f = NULL;
    if (!flag) 
    {
        if (mem_tbr) free(mem_tbr);
        mem_tbr = NULL;
        return NULL;
    }
    return ret;
}// End of ReadCertFromFile



int main()
{
    char                    fname[] = "cert.cer";        // Имя файла c сертификатом   
    BYTE                    *DecodedSub = NULL;
    DWORD                   DecodedSub_len = 0;
    BYTE                    *DecodedSnils = NULL;
    DWORD                   DecodedSnils_len = 0;
    PCCERT_CONTEXT          pCertContext = NULL;
    PCERT_INFO              pCertInfo;
    CERT_NAME_INFO          * pSubject;
    CERT_NAME_BLOB          Subject;
    DWORD                   MY_ENCODING_TYPE = X509_ASN_ENCODING | PKCS_7_ASN_ENCODING;
    int                     i,j;
    int                     flag = 0;

    
    pCertContext = ReadCertFromFile (fname);
    pCertInfo= (*pCertContext).pCertInfo ;
    Subject = (*pCertInfo).Subject; 

    //-------------------------------------------------------------------
    // Decode Subject
    if (!CryptDecodeObject(MY_ENCODING_TYPE, X509_NAME, Subject.pbData, Subject.cbData, 0, NULL, &DecodedSub_len))
        HandleError("CryptDecodeObject(X509_NAME, NULL) failed");

    DecodedSub = malloc (DecodedSub_len);
    if (! DecodedSub) 
        HandleError ("Memory allocation error.");

    if (!CryptDecodeObject(MY_ENCODING_TYPE, X509_NAME, Subject.pbData, Subject.cbData, 0, DecodedSub, &DecodedSub_len)) 
    {
        free (DecodedSub);
        HandleError("CryptDecodeObject(X509_NAME, DecodedSub) failed");
    }

    pSubject = (CERT_NAME_INFO*) DecodedSub;

    //-------------------------------------------------------------------
    // Decode SNILS
    for (i = 0; (i < pSubject->cRDN) && (flag == 0) ; i++)
        for (j = 0; (j < pSubject->rgRDN[i].cRDNAttr) && (flag == 0); j++)
        {
            if (strcmp(pSubject->rgRDN[i].rgRDNAttr[j].pszObjId, szOID_SNILS) == 0)
            {
                flag = 1;

                DecodedSnils = (CHAR *)malloc(pSubject->rgRDN[i].rgRDNAttr[j].Value.cbData + 1);
                if (! DecodedSnils) 
                {
                    free (DecodedSub);
                    HandleError ("Memory allocation error(DecodedSnils).");
                }
                if (!memcpy(DecodedSnils, pSubject->rgRDN[i].rgRDNAttr[j].Value.pbData,pSubject->rgRDN[i].rgRDNAttr[j].Value.cbData))
                {
                    free (DecodedSub);
                    HandleError ("Memcpy error(DecodedSnils).");
                }
                DecodedSnils[pSubject->rgRDN[i].rgRDNAttr[j].Value.cbData] = 0;

                printf("Decoded SNILS is:  %s\n", DecodedSnils);
            }
        }
    //-------------------------------------------------------------------
    // Free memory.
    if (DecodedSnils) free (DecodedSnils);
    if (DecodedSub) free (DecodedSub);

    return 0; 
}// End of main


void HandleError(char *s)
{
    DWORD err = GetLastError();
    printf("Error number     : 0x%x\n", err);
    printf("Error description: %s\n", s);
    if(!err) err = 1;
    exit(err);
}// End of HandleError




Отредактировано пользователем 13 марта 2014 г. 17:42:20(UTC)  | Причина: Не указана

Offline Серёня  
#8 Оставлено : 14 марта 2014 г. 17:01:33(UTC)
Серёня

Статус: Участник

Группы: Участники
Зарегистрирован: 03.03.2014(UTC)
Сообщений: 22
Мужчина
Российская Федерация
Откуда: Москва

Сказал «Спасибо»: 2 раз
Получилось, спасибо за помощь.
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Guest (3)
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.