logo
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline olekhov  
#1 Оставлено : 6 марта 2018 г. 14:18:26(UTC)
olekhov

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

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

Сказал(а) «Спасибо»: 4 раз
Задача: сформировать (временный) ключ подписи и экспортировать его (в зашифрованном виде).
На принимающей стороне расшифровать.

Две стороны: "генератор ключей" (Generator), "приёмник ключей" (Recipient)

На стороне "генератора ключей":
Код:

// Создание временного контейнера с экспортируемым ключом
CryptAcquireContext(&hGenProv, "\\\.\\REGISTRY\\TEMPKEY"..);
CryptGenKey(hProv, AT_SIGNATURE, CRYPT_EXPORTABLE, &hGenKey ) ;
CryptExportKey(hGenKey, ... PUBLICKEYBLOB, pbGenKeyPUB... );

// Создание эфемерного ключа для ключевого обмена
CryptGenKey(hGenProv, CALG_DH_GR3410_12_256_EPHEM, CRYPT_PREGEN|CRYPT_EXPORTABLE, &hEphem);
CryptSetKeyParam(hEphem, KP_X, NULL, 0);
CryptExportKey(hEphem, ... PUBLICKEYBLOB, pbEphemPub... );
CryptSetKeyParam(hKEK, KP_ALGID, CALG_PRO12_EXPORT)

// Импорт публичного ключа приёмника и вывод ключа обмена KEK
CryptImportKey(hGenProv, pbRecipientPublicKeyBlob, hEphemKey, &hKEK);

// На ключе обмена KEK зашифровать ключ из временного контейнера
CryptExportKey(hGenKey, hKEK, PRIVATEKEYBLOB, pbEncryptedBlob, ..);


На стороне приёмника:
Код:

// Открытие личного ключа приёмника для расшифровки ключей
CryptAcquireContext(&hRecipientProv, "mykey",...);
CryptGetUserKey(hRecipientProv, AT_KEYEXCHANGE, &hRecipientKey);
// Импорт публичной части эфемерного ключа от генератора
CryptImportKey(hRecipientProv, pbEphemPub, hRecipientKey, &hKEK);
CryptSetKeyParam(hKEK, KP_ALGID, CALG_PRO12_EXPORT);

// CryptImportKey( hRecipientProv, pbEncryptedBlob, hKEK, &hGenKey);
// этот путь работает в том смысле что на стороне приёмника 

// Задача - расшифровать pbEncryptedBlob



Из pbEncryptedBlob достал ASN.1 структуру

Код:

Offset| Len  |LenByte|
======+======+=======+======================================================================
     0|    99|      1| SEQUENCE : 
     2|    91|      1|    SEQUENCE : 
     4|     8|      1|       OCTET STRING : 
      |      |       |          4BB2D25DB1B86406  // UKM
    14|    40|      1|       SEQUENCE : 
    16|    32|      1|          OCTET STRING : 
      |      |       |             A942F8052AA3A528DBE631B80A3FEA4034EFE92EEDA92088044DA6B9F6E2C160 // зашифрованное значение ключа
    50|     4|      1|          OCTET STRING : '7D54464E' // контрольная сумма ключа
    56|    37|      1|       CONTEXT SPECIFIC (0) : 
    58|     2|      1|          BIT STRING UnusedBits:7 : 
      |      |       |             80
    62|    31|      1|          CONTEXT SPECIFIC (0) : 
    64|     8|      1|             OBJECT IDENTIFIER :  [1.2.643.7.1.1.1.1]
    74|    19|      1|             SEQUENCE : 
    76|     7|      1|                OBJECT IDENTIFIER : GostR3410_2001_CryptoPro_A_ParamSet [1.2.643.2.2.35.1]
    85|     8|      1|                OBJECT IDENTIFIER :  [1.2.643.7.1.1.2.2]
    95|     4|      1|    OCTET STRING : '58DCE44C'



Пробовал как-то так
Код:

CryptSetKeyParam(hKEK, KP_ALGID, CALG_G28147);
// Сформировать CRYPT_DIVERSBLOB (https://cpdn.cryptopro.ru/content/csp39/html/group___pro_c_s_p_key_1g22d0afd866885ab6779eabc9dab4a6b8.html)
...
        divblob.DiversBlobHeader.aiDiversAlgId = CryptoAPI.CALG_PRO12_DIVERS;
        divblob.DiversBlobHeader.cbDiversData = 8;
        memcpy(divblob.pbData, EncryptedBlob->UKM;
// Вывести ключ импорта
CryptImportKey(... &divblob, hKEK, &hDivKEK); 
CryptSetKeyParam(hDivKEK, KP_MODE, CRYPT_MODE_ECB)
CryptDecrypt(hDivKEK, NULL, FALSE, EncryptedBlob->EncryptedKey+ 0, &enclen);
CryptDecrypt(hDivKEK, NULL, FALSE, EncryptedBlob->EncryptedKey+ 8, &enclen);
CryptDecrypt(hDivKEK, NULL, FALSE, EncryptedBlob->EncryptedKey+16, &enclen);
CryptDecrypt(hDivKEK, NULL, FALSE, EncryptedBlob->EncryptedKey+24, &enclen);


В результате расшифровывается мусор, контрольная сумма под ключом не сходится, публичный ключ к расшифрованному значению не подходит.

Я правильно понимаю, что CALG_PRO_DIVERS соответствует "rfc4357, CryptoPro KEK Diversification Algorithm" ?
CALG_PRO12_DIVERS - аналогично для ключей 34.10-2012 ?

Если нет, то можно ли диверсифицировать ключ алгоритмом CryptoPro KEK Diversification Algorithm из rfc4357 средствами CryptoAPI ?
Offline Русев Андрей  
#2 Оставлено : 16 апреля 2018 г. 7:32:31(UTC)
Русев Андрей

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

Группы: Администраторы, Участники
Зарегистрирован: 16.04.2008(UTC)
Сообщений: 436

Поблагодарили: 69 раз в 58 постах
В нашем sdk (windows) и devel-пакете (*nix) есть пример экспорта-импорта закрытого ключа: EncryptKey.c, DecryptKey.c.
Раньше там была реализация на Diffie-Hellman, сейчас упростили до PBKDF2.
Техническую поддержку оказываем тут.
Наша база знаний.
RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.