Я пытаюсь проверить цифровую подпись XML с помощью openSSL. Когда я фактически использую EVP_VerifyFinal, я получаю код ошибки 0D07209B (ASN1_get_object: слишком длинный). Он, как я загружаю в KeyInfo от CERT:Как загрузить ключ DSA из KeyInfo с помощью openSSL
<KeyInfo>
<KeyValue>
<DSAKeyValue>
<P>/KaCzo4Syrom78z3EQ5SbbB4sF7ey80etKII864WF64B81uRpH5t9jQTxeEu0ImbzRMqzVDZkVG9xD7nN1kuFw==</P>
<Q>li7dzDacuo67Jg7mtqEm2TRuOMU=</Q>
<G>Z4Rxsnqc9E7pGknFFH2xqaryRPBaQ01khpMdLRQnG541Awtx/XPaF5Bpsy4pNWMOHCBiNU0NogpsQW5QvnlMpA==</G>
<Y>butK4tBy8dwSJFjTRpTvmYZYnsDGO4CzMVgcD8EQ2UJrQZd0ZapQI/Ea2DZzQBTFjjdnNkFuNOtjVI615lhiBQ==</Y>
</DSAKeyValue>
</KeyValue>
</KeyInfo>
Мой (псевдокод) метод для загрузки РПОО:
pDSA = DSA_new();
pDSA.p = BN_bin2bn(base64Decode(text of P element));
pDSA.q = BN_bin2bn(base64Decode(text of Q element));
pDSA.g = BN_bin2bn(base64Decode(text of G element));
pDSA.pub_key = BN_bin2bn(base64Decode(text of Y element));
Использование BN_bn2hex после этого дает мне значения:
p: FCA682CE8E12CABA26EFCCF7110E526DB078B05EDECBCD1EB4A208F3AE1617AE01F35B91A47E6DF63413C5E12ED0899BCD132ACD50D99151BDC43EE737592E17
q: 962EDDCC369CBA8EBB260EE6B6A126D9346E38C5
g: 678471B27A9CF44EE91A49C5147DB1A9AAF244F05A434D6486931D2D14271B9E35030B71FD73DA179069B32E2935630E1C2062354D0DA20A6C416E50BE794CA4
pub_key: 6EEB4AE2D072F1DC122458D34694EF9986589EC0C63B80B331581C0FC110D9426B41977465AA5023F11AD836734014C58E376736416E34EB63548EB5E6586205
, подтверждающие подпись:
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#dsa-sha1"/>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>uooqbWYa5VCqcJCbuymBKqm17vY=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>L4h4TFDj5rDKCHm0D+aH2LeSfAMV2t0V5S91Afu6U0NlfpjxdTXRUA==</SignatureValue>
<KeyInfo>
<KeyValue>
<DSAKeyValue>
<P>/KaCzo4Syrom78z3EQ5SbbB4sF7ey80etKII864WF64B81uRpH5t9jQTxeEu0ImbzRMqzVDZkVG9xD7nN1kuFw=</P>
<Q>li7dzDacuo67Jg7mtqEm2TRuOMU=</Q>
<G>Z4Rxsnqc9E7pGknFFH2xqaryRPBaQ01khpMdLRQnG541Awtx/XPaF5Bpsy4pNWMOHCBiNU0NogpsQW5QvnlMpA==</G>
<Y>POKkQtGuazaz6OEWi91P4C9z1tREpeP9f7L3piRD/3TiNFzvt0BmYzNO0CoPSjEVTXYKIRo/+HXK6MhBRk2eUw=</Y>
</DSAKeyValue>
</KeyValue>
</KeyInfo>
</Signature>
</Envelope>
Вот как я проверить подпись:
pkey = EVP_PKEY_new;
EVP_PKEY_set1_DSA(pkey, pdsa)
EVP_MD_CTX_init(ctx);
EVP_VerifyInit(@ctx, EVP_sha1)
EVP_VerifyUpdate(@ctx, digest of SignedInfo);
bytes = unbase64(text of SignatureValue)
EVP_VerifyFinal(@ctx, btes, length(bytes)}, pKey);
Verify окончательные возвращает следующие ошибки:
0D07207B:asn1 encoding routines:ASN1_get_object:header too long)
0D068066:asn1 encoding routines:ASN1_CHECK_TLEN:bad object header)
0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error)
Так как я загрузке сертификата или значение подписи Неправильно. Согласно спецификации, значение подписи «Значение подписи состоит из кодировки base64 конкатенации двух октетных потоков, которые соответственно являются результатом октетного кодирования значений r и s в этом порядке» - но я не могу найти нигде в документацию openSSL, которая должна быть передана EVP_VerifyInit для значения подписи для DSA-подписи. Я нашел одну ссылку в архиве электронной почты, которая указывала на RFC 3279, который, как мне кажется, указывает тот же формат (Dss-Sig-Value :: = SEQUENCE {r INTEGER, s INTEGER}
Это действительно здорово, спасибо. Я не мог найти, какую кодировку asn.1 я должен использовать, и я действительно ценю, что вы делаете для этого работу. Теперь я могу проверить подпись. Однако у меня есть один следующий вопрос: когда я подписываюсь, используя EVP_MD_CTX_init (ctx), EVP_SignInit (ctx, EVP_sha256), EVP_SignUpdate (@ctx, байты дайджеста), EVP_SignFinal (ctx, sig, len, pKey), я получаю len из 70, который представляет собой структуру asn.1, которая содержит 2 32 байтовых ключа, а не 20 байтовых ключей. Но они должны быть только 20 байтов? –
Возможно, зависит от используемого ключа. 20 байт относится к значению 160 бит для параметра q. Теперь вы, вероятно, используете ключ из 2048/256 бит. В течение долгого времени использовались только DSA-ключи с размерами 1024/160 бит, и спецификация XML, похоже, все еще живет в те времена :) –
отлично, спасибо, я очень ценю это –