08.11.2005 10:12:49Разделить ЭЦП с включенным сертификатом на собственно ЭЦП и сертификат Ответов: 5
Виктор
Как разделить ЭЦП, полученную путем включения в подпись сертификата отправителя, на собственно ЭЦП и сертификат?
Корректно ли их просто разделить побайтово?

Подробнее:
Решаемая задача: ЭЦП на XML

1. При подписи включаю сертификат в detached подпись:

CRYPT_SIGN_MESSAGE_PARA param;
param.cMsgCert = 1; // включаем сертификат отправителя
param.rgpMsgCert = &pUserCert;

2. Вставляю полученную подпись в виде Base64 в некий тег XML документа
3. Отправляю XML документ

4. На принимающей стороне извлекаю ЭЦП и выполняю проверку данных с использованием переданного сертификата:

CRYPT_VERIFY_MESSAGE_PARA param;
param.hCryptProv = 0;
param.pfnGetSignerCertificate = NULL;
param.pvGetArg = NULL;

5. Все замечательно.


Однако проблема в том, что я должен при создании ЭЦП разделить подпись и сертификат и засунуть их в разные теги XML Документа:

<SignatureValue>
UADDMHZkyebvRdLs+6Dv7RvgMLRlUaD
</SignatureValue>
- <X509Data>
<X509Certificate> ctA8YGxrtngg/zKVvqEOefnwmViFztc
</X509Certificate>
</X509Data>

Корректно ли их просто разделить побайтово. Например, я включаю сертификат в подпись (detached) и получаю массив размером 1784 байта.
Выкусываю первые 512 байт (алгоритм гостовский) - это будет ЭЦП, а оставшиеся байты будут сертификатом.

Естественно, если на принимающей стороне я солью их вместе, то я смогу проверить подпись. Т.е. технически это будет работать.

Но вот архитектурно/концептуально?
Ведь сертификат, полученный таким образом, явно не будет сертификатом X509. Т.е. тот массив байт, который я запихну в тег <X509Certificate>, не может быть преобразован в "нормальный" сертификат.

Не подскажите в какую сторону думать?

Заранее большое спасибо!
 
Ответы:
08.11.2005 11:08:03Kirill Sobolev
Нет, некорректно.
А почему просто нельзя не включать в подпись сертификат а передавать его отдельно в base64?
08.11.2005 11:20:46Виктор
Хотелось отделаться малой кровью :-)

Прошу прощения за наверное простые вопросы, но:

1. Как получить сертификат, который я с чистой совестью могу вставить в поле X509Certificate?

2. Как этот сертификат позже подцепить при проверке подписи на стороне клиента?

Заранее большое спасибо!

08.11.2005 11:27:14Kirill Sobolev
Это малая кровь :)
1)CERT_CONTEXT::pbCertEncoded - сертификат, CERT_CONTEXT::cbCertEncoded - его длина. Это как раз и можно вставлять. Для того чтобы получить CERT_CONTEXT обратно нужна CertCreateCertificateContext.
2)Для проверки подписи придется написать callback (PFN_CRYPT_GET_SIGNER_CERTIFICATE) pfnGetSignerCertificate в CRYPT_VERIFY_MESSAGE_PARA, который как раз и вернет этот сертификат.
09.11.2005 16:46:09Виктор
Большое спасибо!

Все заработало.

Ради интереса полученный таким образом сертификат сохранил в файл. Если не сложно, подскажите чем бы его посмотреть в человеческом виде.

С уважением, Виктор
09.11.2005 16:50:53Kirill Sobolev
Да тем же чем и обычные сертификаты в файлах.
В проводнике расширению .cer должна быть сопоставлена команада
rundll32.exe cryptext.dll,CryptExtOpenCER %1