08.06.2004 12:38:13Проверка ЭЦП сертификата Ответов: 1
Олег
Добрый!
Пишу повторный вопрос про проблему проверки ЭЦП корневого сертификата.
Что я делаю не так? Проблема острая и если не решится, то мы будем вынуждены отказаться от применения этого криптопровайдера, что очень плохо.
Например при проверке сертификатов изготовленных в ЦС "Валидата" этих проблем нет - правда там нет mscsp.
Скорее всего проблемы в подписанных данных CertInfo - м.б. там есть какие то нюансы.
Куок кода:

const
// блоб с открытым ключом Криптопро
OPEN_KEY_CP: array[0..35] of Byte = (
// BLOBHEADER
$06, // тип
$20, // версия
$01,$00, // резерв
$1E,$2E,$00,$00, // идентификатор алгоритма
// CRYPT_PUBKEYPARAM
$4D,$41,$47,$31, // Magic = ’MAG1’
$00,$04,$00,$00, // BitLen
// идентификаторы подписи и хеширования в DER
$30,$12,$06,$07,$2A,$85,$03,$02,$02,$20,
$02,$06,$07,$2A,$85,$03,$02,$02,$1E,$01
// далее открытый ключ в сетевом представлении 128 или 64 байт
//............
);

var
hHash: HCRYPTHASH;
hKey: HCRYPTKEY;
// блоб с открытым ключом Криптопро
okBLOB: array[0..SizeOf(OPEN_KEY_CP)+128-1] of Byte;
PubKey: array[0..127+3] of Byte; // открытый ключ
Sign: array[0..63] of Byte; // ЭЦП
SignData: array[0..4000] of Byte; // Подписанные данные в сертификате CertInfo в ASN кодировке

.....
Средствами OpenSSL из корневого сертификата "CP CSP Test CA" получаем
PubKey - открытый ключ из сертификата 131 байт - первые 3 байта "мусор"
Sign - ЭЦП 64 байта
SignData - подписанные данные 741 байт

Check(CryptAcquireContext(
@hProv,
nil,
’Crypto-Pro Cryptographic Service Provider’,
2,
0
));

// Создание и инициализация объекта хэширования
Check(CryptCreateHash(hProv, CALG_GR3411, 0, 0, @hHash));
// Хэширование потоковых данных
Check(CryptHashData(hHash, @SignData, dwSizeSignData, 0));
// создание BLOB открытого ключа для импорта
CopyMemory(@okBLOB, @OPEN_KEY_CP, 36);
// копируем открытый ключ в структуру
CopyMemory(@okBLOB[36], @PubKey[3], 128);
// Импорт открытого ключа
Check(CryptImportKey(hProv, @okBLOB, 164, 0, 0, @hKey));
// Проверка подписи хэша
Check(CryptVerifySignature(hHash, @Sign, 64, hKey, nil, 0));
 
Ответы:
11.06.2004 14:10:02Василий
1. Первые 3 байта PubKey - вовсе не мусор, а заголовок ASN.1, означающий - тип OCTET STRING, длина содержимого 128.
2. Проверьте порядок байтов (пример- корневой сертификат нашего тестового ЦС):
- для SignData (длина 741): 30,82,02,e1,a0,03,...,03,03,00,03
- для Sign (длина 64): e9,5b,de,41,c0,...,78,ee,62,82