2014-08-27 6 views
1

Я создаю некоторые самозаверяющие сертификаты через C#, используя вызовы CryptoAPI с использованием p/invoke для использования в приложении. Я назначаю правильную информацию структуре CERT_INFO, получая открытый ключ с помощью CryptExportPublicKey. Когда я зашифровать сертификат с CryptSignAndEncryptCertificate, полученное значение выглядит правильным, но при тестировании с OpenSSL -verify, я получаю следующие ошибки:Сертификат не подписан должным образом

6704:error:0407006A:rsa routines:RSA_padding_check_PKCS1_type_1:block type is not 01:.\crypto\rsa\rsa_pk1.c:100: 
6704:error:04067072:rsa routines:RSA_EAY_PUBLIC_DECRYPT:padding check failed:.\crypto\rsa\rsa_eay.c:721: 
6704:error:0D0C5006:asn1 encoding routines:ASN1_item_verify:EVP lib:.\crypto\asn1\a_verify.c:221: 

При проверке сертификата в декодере CSR на http://certlogik.com/decoder/, модуль поле информации открытого ключа имеет ведущий 00 байт, которого нет при анализе открытого ключа с KeyPal. Может ли кто-нибудь сказать мне, что мне нужно сделать, чтобы исправить эту ошибку?

+0

Что такое 'CryptSignAndEncryptCertificate'? У вас есть код? При использовании OpenSSL API вы обычно просто программно создаете сам подписанный сертификат; вы не проходите промежуточный шаг КСО. Утилита 'req' OpenSSL может создавать самоподписанные. Вы используете команду 'openssl req -x509 ...'. '-x509' сообщает, что он создает самоподписанный, а не запрос. Исходный код можно найти в '/apps/req.c'. – jww

+0

CryptSignAndEncodeCertificate является одним из вызовов функций в Windows CryptoAPI. Я не использую openSSL. –

+0

Вы уверены, что 'CryptSignAndEncryptCertificate' является функцией Windows? http://www.google.com/#q=CryptSignAndEncryptCertificate+msdn возвращает 0 результатов. Если вы не используете OpenSSL, то почему у вас есть сообщения об ошибках OpenSSL? – jww

ответ

0

Для тех, кто заинтересован:

Структура CERT_INFO, который передается в CryptSignAndEncodeCertificate содержит поле SubjectPublicKeyInfo, который является CERT_PUBLIC_KEY_INFO структура. Сначала я пытался взять указатель, полученный от CryptExportPublicKeyInfo, и назначить его SubjectPublicKeyInfo через Marshal.PtrToStructure. Как оказалось, Marshal.PtrToSTructure просто заставляет SubjectPublicKeyInfo указывать на ту же ячейку памяти, что и возвращаемый указатель. Когда указатель освобождается, память недействительна, а SubjectPublicKeyInfo остается в неопределенном состоянии. Способ обойти это создать новую структуру, а затем назначить эту новую структуру SubjectPublicKeyInfo. Это приводит к тому, что значения из новой структуры будут скопированы в SubjectPublicKeyInfo, поэтому ее местоположение памяти никогда не будет аннулировано. Или, по крайней мере, это самое близкое, что я могу понять. Если у кого-то есть лучшее объяснение, я бы с удовольствием это услышал.