Статус: Участник
Группы: Участники
Зарегистрирован: 15.04.2009(UTC) Сообщений: 10
|
Коллеги, возникла необходимость с помощью crypto api реализовать подпись и проверку xml дукумента в соответствии со спецификацией http://tools.ietf.org/html/rfc3275 и с использованием российских гостов. Порывшись в интернете нашел спецификацию http://tools.ietf.org/ht...v-cryptopro-cpxmldsig-05разработанную сотрудниками crypto pro. Вот Xml документ, который приводится в спецификации (я снял base64): |1.xml| 1)Итак, следуя стандартам я применил C14N к документу, предварительно убрав поддерево содержащее тэга signature. Получился документ: |2.xml| 2) Далее к документу на шаге один я применил хэш CALG_GR3411 с помощью кода(упрощенная версия кода): Код:
::CryptAcquireContext(&cryptoProv, NULL, CP_GR3410_2001_PROV, PROV_GOST_2001_DH, CRYPT_VERIFYCONTEXT);
HCRYPTHASH hHash;
::CryptCreateHash(cryptoProv,
CALG_GR3411,
NULL,
0,
&hHash);
::CryptHashData(hHash,
(BYTE*)buff,
buffSize,
0);
DWORD hash_size = 0;
DWORD paramSize;
::CryptGetHashParam(hHash,
HP_HASHSIZE,
(BYTE*)(&hash_size),
¶mSize,
0);
::CryptGetHashParam(hHash,
HP_HASHVAL,
(BYTE*)(hashValBuffer),
&hash_size,
0);
::CryptDestroyHash(hHash);
3) полученный хэш я обернул в base64 и получил исходное /JwtQsvy5k/R0VeLzdm2IijPBtSJ5pJRjT9FUQHEyTg=. Что меня сильно порадовало ибо это то что нужно. 4) Далее я применил C14n к |3.xml| и получил: |4.xml| 5) Затем я снял base64 с сертификата |5.xml| и импортировал его(см код проверки подписи ниже) 6) Затем я снял base64 со значения сигнатуры |6.xml| Я использую это значение для проверки подписи данных полученных на шаге 4 с помощью сертификата, полученного на шаге 5 Код, который проверяет сигнатуру документа фейлится на проверке подписи. Все остальные шаги выполняются без ошибок (упрощенная версия кода): Код:
// сертификат с шага 5
static const unsigned char certBuffer[] = {0x30,0x82,0x1,0xd0,0x30,0x82,0x1,0x7f,0x2,0x10,0x2b,0xf5,0xc6,0x1e,0xc2,0x11,0xbd,0x17,0xc7,0xdc,0xd4,0x62,0x66,0xb4,0x2e,0x21,0x30,0x8,0x6,0x6,0x2a,0x85,0x3,0x2,0x2,0x3,0x30,0x6d,0x31,0x1f,0x30,0x1d,0x6,0x3,0x55,0x4,0x3,0xc,0x16,0x47,0x6f,0x73,0x74,0x52,0x33,0x34,0x31,0x30,0x2d,0x32,0x30,0x30,0x31,0x20,0x65,0x78,0x61,0x6d,0x70,0x6c,0x65,0x31,0x12,0x30,0x10,0x6,0x3,0x55,0x4,0xa,0xc,0x9,0x43,0x72,0x79,0x70,0x74,0x6f,0x50,0x72,0x6f,0x31,0xb,0x30,0x9,0x6,0x3,0x55,0x4,0x6,0x13,0x2,0x52,0x55,0x31,0x29,0x30,0x27,0x6,0x9,0x2a,0x86,0x48,0x86,0xf7,0xd,0x1,0x9,0x1,0x16,0x1a,0x47,0x6f,0x73,0x74,0x52,0x33,0x34,0x31,0x30,0x2d,0x32,0x30,0x30,0x31,0x40,0x65,0x78,0x61,0x6d,0x70,0x6c,0x65,0x2e,0x63,0x6f,0x6d,0x30,0x1e,0x17,0xd,0x30,0x35,0x30,0x38,0x31,0x36,0x31,0x34,0x31,0x38,0x32,0x30,0x5a,0x17,0xd,0x31,0x35,0x30,0x38,0x31,0x36,0x31,0x34,0x31,0x38,0x32,0x30,0x5a,0x30,0x6d,0x31,0x1f,0x30,0x1d,0x6,0x3,0x55,0x4,0x3,0xc,0x16,0x47,0x6f,0x73,0x74,0x52,0x33,0x34,0x31,0x30,0x2d,0x32,0x30,0x30,0x31,0x20,0x65,0x78,0x61,0x6d,0x70,0x6c,0x65,0x31,0x12,0x30,0x10,0x6,0x3,0x55,0x4,0xa,0xc,0x9,0x43,0x72,0x79,0x70,0x74,0x6f,0x50,0x72,0x6f,0x31,0xb,0x30,0x9,0x6,0x3,0x55,0x4,0x6,0x13,0x2,0x52,0x55,0x31,0x29,0x30,0x27,0x6,0x9,0x2a,0x86,0x48,0x86,0xf7,0xd,0x1,0x9,0x1,0x16,0x1a,0x47,0x6f,0x73,0x74,0x52,0x33,0x34,0x31,0x30,0x2d,0x32,0x30,0x30,0x31,0x40,0x65,0x78,0x61,0x6d,0x70,0x6c,0x65,0x2e,0x63,0x6f,0x6d,0x30,0x63,0x30,0x1c,0x6,0x6,0x2a,0x85,0x3,0x2,0x2,0x13,0x30,0x12,0x6,0x7,0x2a,0x85,0x3,0x2,0x2,0x24,0,0x6,0x7,0x2a,0x85,0x3,0x2,0x2,0x1e,0x1,0x3,0x43,0,0x4,0x40,0x84,0x95,0x68,0x75,0x60,0x2,0x1a,0x40,0x75,0x8,0xcd,0x13,0x8c,0x31,0x89,0x2c,0xfd,0xe5,0x5,0x3,0x7a,0x43,0x5c,0xf4,0x6d,0x2b,0xf,0xe7,0x4f,0x32,0x7e,0x57,0x8f,0xeb,0xcc,0x16,0xb9,0x95,0x88,0x3,0xd0,0x9a,0x7c,0x85,0xae,0xf,0xe4,0x8d,0xea,0xa6,0xbb,0x7e,0x56,0xc7,0xcb,0xb0,0xdf,0xf,0x66,0xbc,0xca,0xea,0x1a,0x60,0x30,0x8,0x6,0x6,0x2a,0x85,0x3,0x2,0x2,0x3,0x3,0x41,0,0x3c,0x2f,0xc9,0x9,0x44,0xb7,0x27,0xa9,0xec,0xa7,0xd5,0xe9,0xfb,0x53,0x6d,0xd2,0xc3,0xaa,0x64,0x7c,0x44,0x2e,0xde,0xed,0x31,0x16,0x45,0x4f,0xbc,0x54,0x3f,0xdd,0xc1,0xde,0x17,0x6e,0x8d,0x1b,0xec,0x71,0xb5,0x93,0xf3,0xdd,0x36,0x93,0x55,0x77,0x68,0x89,0x89,0x17,0x62,0x20,0xf4,0xda,0xb1,0x31,0xd5,0xb5,0x1c,0x33,0xde,0xe2};
// документ полученный на шаге 4
static const unsigned char canonicalizedXml[] = {0x3c,0x53,0x69,0x67,0x6e,0x65,0x64,0x49,0x6e,0x66,0x6f,0x3e,0x3c,0x43,0x61,0x6e,0x6f,0x6e,0x69,0x63,0x61,0x6c,0x69,0x7a,0x61,0x74,0x69,0x6f,0x6e,0x4d,0x65,0x74,0x68,0x6f,0x64,0x20,0x41,0x6c,0x67,0x6f,0x72,0x69,0x74,0x68,0x6d,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x54,0x52,0x2f,0x32,0x30,0x30,0x31,0x2f,0x52,0x45,0x43,0x2d,0x78,0x6d,0x6c,0x2d,0x63,0x31,0x34,0x6e,0x2d,0x32,0x30,0x30,0x31,0x30,0x33,0x31,0x35,0x22,0x20,0x2f,0x3e,0x3c,0x53,0x69,0x67,0x6e,0x61,0x74,0x75,0x72,0x65,0x4d,0x65,0x74,0x68,0x6f,0x64,0x20,0x41,0x6c,0x67,0x6f,0x72,0x69,0x74,0x68,0x6d,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x32,0x30,0x30,0x31,0x2f,0x30,0x34,0x2f,0x78,0x6d,0x6c,0x64,0x73,0x69,0x67,0x2d,0x6d,0x6f,0x72,0x65,0x23,0x67,0x6f,0x73,0x74,0x72,0x33,0x34,0x31,0x30,0x32,0x30,0x30,0x31,0x2d,0x67,0x6f,0x73,0x74,0x72,0x33,0x34,0x31,0x31,0x22,0x20,0x2f,0x3e,0x3c,0x52,0x65,0x66,0x65,0x72,0x65,0x6e,0x63,0x65,0x20,0x55,0x52,0x49,0x3d,0x22,0x22,0x3e,0x3c,0x54,0x72,0x61,0x6e,0x73,0x66,0x6f,0x72,0x6d,0x73,0x3e,0x3c,0x54,0x72,0x61,0x6e,0x73,0x66,0x6f,0x72,0x6d,0x20,0x41,0x6c,0x67,0x6f,0x72,0x69,0x74,0x68,0x6d,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x32,0x30,0x30,0x30,0x2f,0x30,0x39,0x2f,0x78,0x6d,0x6c,0x64,0x73,0x69,0x67,0x23,0x65,0x6e,0x76,0x65,0x6c,0x6f,0x70,0x65,0x64,0x2d,0x73,0x69,0x67,0x6e,0x61,0x74,0x75,0x72,0x65,0x22,0x20,0x2f,0x3e,0x3c,0x2f,0x54,0x72,0x61,0x6e,0x73,0x66,0x6f,0x72,0x6d,0x73,0x3e,0x3c,0x44,0x69,0x67,0x65,0x73,0x74,0x4d,0x65,0x74,0x68,0x6f,0x64,0x20,0x41,0x6c,0x67,0x6f,0x72,0x69,0x74,0x68,0x6d,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x32,0x30,0x30,0x31,0x2f,0x30,0x34,0x2f,0x78,0x6d,0x6c,0x64,0x73,0x69,0x67,0x2d,0x6d,0x6f,0x72,0x65,0x23,0x67,0x6f,0x73,0x74,0x72,0x33,0x34,0x31,0x31,0x22,0x20,0x2f,0x3e,0x3c,0x44,0x69,0x67,0x65,0x73,0x74,0x56,0x61,0x6c,0x75,0x65,0x3e,0x2f,0x4a,0x77,0x74,0x51,0x73,0x76,0x79,0x35,0x6b,0x2f,0x52,0x30,0x56,0x65,0x4c,0x7a,0x64,0x6d,0x32,0x49,0x69,0x6a,0x50,0x42,0x74,0x53,0x4a,0x35,0x70,0x4a,0x52,0x6a,0x54,0x39,0x46,0x55,0x51,0x48,0x45,0x79,0x54,0x67,0x3d,0x3c,0x2f,0x44,0x69,0x67,0x65,0x73,0x74,0x56,0x61,0x6c,0x75,0x65,0x3e,0x3c,0x2f,0x52,0x65,0x66,0x65,0x72,0x65,0x6e,0x63,0x65,0x3e,0x3c,0x2f,0x53,0x69,0x67,0x6e,0x65,0x64,0x49,0x6e,0x66,0x6f,0x3e};
// сигнатура полученная на шаге 6
static unsigned char decodedSignedInfoSignature[] = {0x15,0xc6,0xf7,0xab,0x88,0x81,0xbd,0xd7,0xe0,0x62,0x8e,0xe7,0xf7,0x91,0x9a,0x40,0x2b,0x9d,0xf7,0x56,0xf,0xef,0xf,0x28,0x57,0x4d,0xd1,0xeb,0x39,0x11,0xd,0xd9,0x5c,0xf8,0x39,0xc2,0x73,0x4a,0xfd,0x32,0xc0,0x39,0x6b,0xf6,0xe1,0x60,0x2c,0x96,0x3d,0xdf,0xdc,0x11,0x4f,0x3e,0xa9,0x81,0x6b,0xc8,0x96,0xdc,0x8a,0xbc,0xb0,0x1c};
PCCERT_CONTEXT certContext = ::CertCreateCertificateContext(CERT_ENCODING_TYPE,
(BYTE*)certBuffer,
certSize);
if(certContext)
{
HCRYPTPROV cryptProv = NULL;
if(::CryptAcquireContext(&cryptProv, NULL, CP_GR3410_2001_PROV, PROV_GOST_2001_DH, CRYPT_VERIFYCONTEXT))
{
HCRYPTKEY hKey;
if(::CryptImportPublicKeyInfo(cryptProv,
CERT_ENCODING_TYPE,
&certContext->pCertInfo->SubjectPublicKeyInfo,
&hKey))
{
HCRYPTHASH hHash;
if(::CryptCreateHash(cryptProv,
CALG_GR3411,
NULL,
0,
&hHash))
{
if(::CryptHashData(hHash,
(BYTE*)canonicalizedXml,
sizeof(canonicalizedXml),
0))
{
if(::CryptVerifySignature(hHash,
(BYTE*)decodedSignedInfoSignature,
sizeof(decodedSignedInfoSignature),
hKey,
NULL,
0))
{
ret_val = true;
}
Отсюда я делаю три предположения: 1) Я неверно понял рекомендацию и к 64-м байтам сигнатуры, которая берется из значения тэга SignatureValue после снятия base64 применяется еще какое-то преобразование о котором явно не написано в рекомендации 2) Код которай проверяет сигнатуру неверен. Ну с другой стороны этот код нормально работет когда я даю ему сигнатуру сгенерированную при помощи функций crypto api и своего тестового вектора и сертификата. Так что тут возможен вариант, что я какие-то параметры не задал при проверке подписи. 3) Документ который приведен в рекомендации http://tools.ietf.org/ht...v-cryptopro-cpxmldsig-05в качестве примера содержит неверную сигнатуру. p.s В основном интересуют комментарии людей писавших рекомендации или хорошо в ней разбирающихся. По техническим причинам должен реализовать стандарт(точнее некоторое его подмножество) с помощью CryptoApi. Буду очень благодарен за помощь. Вложение(я):  1.xml (2kb) загружен 32 раз(а). 2.xml (1kb) загружен 24 раз(а). 3.xml (1kb) загружен 25 раз(а). 4.xml (1kb) загружен 21 раз(а). 5.xml (1kb) загружен 18 раз(а). 6.xml (1kb) загружен 20 раз(а).У Вас нет прав для просмотра или загрузки вложений. Попробуйте зарегистрироваться.
|