14.05.2004 15:24:22Ошибка в CSP крипто про: неоднозначное поведение CryptExportKey Ответов: 3
Ivan Ravin
Уважаемые разработчики! Прошу проверить ошибку, заключающуюся в разном результате экспорта ключей.
Вот описание: пусть есть контейнер, содержащий ключ обмена ProCSP. Экспортируем эток ключ в буфер:
CryptExportKey(hKey, 0, PUBLICKEYBLOB, 0, FromPoint, @BufLen)
результирующий буфер начинается так:
06 20 00 00 1E 2E...

Допустим, из этого ключа сделали сертификат, то есть сэкспортировали его через CryptExportPublicKeyInfo, собрали остальную информацию и все это подписали. Теперь, если извлечь ключ из сертификата (CryptImportPublicKeyInfo) и экспортировать в буфер как в первом случае, то получаем точно такой же буфер, с отличием в 3 байте:
06 20 01 00 1E 2E...
Итак, открытые ключи различаются на 1 байт, а если взять от того и другого хеш, то несовпадение 100% :).

Как мне убедиться, что сертификат и контейнер соответствуют друг другу? В случае с провайдером крипто про получается, что описанный способ не подойдет, либо мне надо игнорировать это 3-й байт.

Итак, в первом случае PUBLICKEYBLOB экспортировался из секретного ключа, во втором - из открытого. Несовпадение налицо. Это правильно?
 
Ответы:
14.05.2004 16:04:14Чудов Григорий
Функция CryptExportKey возвращает блоб, первые 6 байт которого имеют формат структуры BLOBHEADER, описанной в MSDN.
typedef struct _PUBLICKEYSTRUC {
BYTE bType;
BYTE bVersion;
WORD reserved;
ALG_ID aiKeyAlg;
} BLOBHEADER, PUBLICKEYSTRUC;

Третий и четвертый байты составляют поле reserved, зарезервированное для нужд разработчика.

Рекомендуется пользоваться внешним форматом открытого ключа, возвращаемом функцией CryptExportPublicKeyInfo. Его можно ставнивать с содержимым pCertContext->pCertInfo->SubjectPublicKeyInfo из сертификата.
14.05.2004 16:52:48ivan ravin
> Рекомендуется пользоваться внешним форматом открытого ключа, возвращаемом функцией CryptExportPublicKeyInfo.
Его можно ставнивать с содержимым pCertContext->pCertInfo->SubjectPublicKeyInfo из сертификата

К сожалению, не не всегда имеется сертификат, а есть только открытый ключ, сэкспортированный средствами API 1, то есть через CryptExportKey. Получить из него "внешний" формат невозможно. Могу ли я сравнивать открытые ключи без учета первых 6 байт?
14.05.2004 17:07:38Чудов Григорий
Странная ситуация. С чем же его сравнивать, если не с сертификатом?
Ну, да дело ваше. Корректнее в таком случае было бы игнорировать зарезервированные 3й и 4й байты, и сравнивать всё остальное. Это по моим данным будет работать на всех известных версиях провайдера, но формально про формат блоба ничего не гарантируется.