Ошибка декодирования BER - PullRequest
0 голосов
/ 21 мая 2018

Я делаю проверку подписи RSA, я всегда получаю эту ошибку

terminate called after throwing an instance of 'CryptoPP::BERDecodeErr'
  what():  BER decode error
Aborted (core dumped)

Я не понимаю, почему я получаю эту ошибку, я никогда раньше не вызывал код BERDecode.

Это мой сегмент кода, я пытался отследить ошибку, которая возникает во второй строке кода:

FileSource pubFile(publicKey_file.c_str(), true, new HexDecoder);
RSASS<PSSR, SHA1>::Verifier pub(pubFile);

FileSource signatureFile(sig_file.c_str(), true, new HexDecoder);   
if (signatureFile.MaxRetrievable() != pub.SignatureLength()) {
    return false;
}

SecByteBlock signature(pub.SignatureLength());
signatureFile.Get(signature, signature.size());

bool result = pub.VerifyMessage((const byte*)messages_file.c_str(),
messages_file.length(), signature, signature.size());

return result;

Я мог бы определить, что происходит, надеюсь получить некоторую помощь.Спасибо.

Ответы [ 2 ]

0 голосов
/ 22 мая 2018

Согласно:

$ echo "30819D300D06092A864886F70D010101050003818B0030818702818100DD2CED773D6F9A
E4A63F2DAEEF9019C056D4A35F338764FAAE85EDCBFB13FC9E53F13CEFADEF58C65B501C3D2D13DC
DE65282B7781C45259065F991C4184E6E6DEDB3087472B4AC4BDD74FDF4D3C893257D68722326516
53A4882588C61C0F4FB096C5906F2F88E0480513A2B1BA6418869DB01C9D9A2FB4BECADE54658D55
2F020111" | xxd -r -p > key.ber

А затем:

$ dumpasn1 key.ber
  0 157: SEQUENCE {
  3  13:   SEQUENCE {
  5   9:     OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1)
 16   0:     NULL
       :     }
 18 139:   BIT STRING, encapsulates {
 22 135:     SEQUENCE {
 25 129:       INTEGER
       :         00 DD 2C ED 77 3D 6F 9A E4 A6 3F 2D AE EF 90 19
       :         C0 56 D4 A3 5F 33 87 64 FA AE 85 ED CB FB 13 FC
       :         9E 53 F1 3C EF AD EF 58 C6 5B 50 1C 3D 2D 13 DC
       :         DE 65 28 2B 77 81 C4 52 59 06 5F 99 1C 41 84 E6
       :         E6 DE DB 30 87 47 2B 4A C4 BD D7 4F DF 4D 3C 89
       :         32 57 D6 87 22 32 65 16 53 A4 88 25 88 C6 1C 0F
       :         4F B0 96 C5 90 6F 2F 88 E0 48 05 13 A2 B1 BA 64
       :         18 86 9D B0 1C 9D 9A 2F B4 BE CA DE 54 65 8D 55
       :         2F
157   1:       INTEGER 17
       :       }
       :     }
       :   }

У вас есть subjectPublicKeyInfo.Я считаю, что все, что вам нужно сделать, это позвонить по номеру Load, но он предполагает, что у вас есть правильно сформированный ключ:

RSASS<PSSR, SHA1>::Verifier pub;
pub.AccessKey().Load(pubFile);

Вот и вся программа:

$ cat test.cxx
#include "cryptlib.h"
#include "filters.h"
#include "pssr.h"
#include "sha.h"
#include "rsa.h"
#include "hex.h"

#include <string>
#include <iostream>

int main()
{
    using namespace CryptoPP;
    std::string encodedKey = "30819D300D06092A864886F70D010101050003818B00"
        "30818702818100DD2CED773D6F9AE4A63F2DAEEF9019C056D4A35F338764FAAE8"
        "5EDCBFB13FC9E53F13CEFADEF58C65B501C3D2D13DCDE65282B7781C45259065F"
        "991C4184E6E6DEDB3087472B4AC4BDD74FDF4D3C893257D6872232651653A4882"
        "588C61C0F4FB096C5906F2F88E0480513A2B1BA6418869DB01C9D9A2FB4BECADE"
        "54658D552F020111";

    StringSource hexKey(encodedKey, true, new HexDecoder);

    RSASS<PSSR, SHA1>::Verifier pub;
    pub.AccessKey().Load(hexKey);

    std::cout << "n: " << std::hex << pub.AccessKey().GetModulus() << std::endl;
    std::cout << "e: " << std::dec << pub.AccessKey().GetPublicExponent() << std::endl;

    return 0;
}

И наконец:

$ ./test.exe
n: dd2ced773d6f9ae4a63f2daeef9019c056d4a35f338764faae85edcbfb13fc9e53f13cefadef5
8c65b501c3d2d13dcde65282b7781c45259065f991c4184e6e6dedb3087472b4ac4bdd74fdf4d3c8
93257d6872232651653a4882588c61c0f4fb096c5906f2f88e0480513a2b1ba6418869db01c9d9a2
fb4becade54658d552fh
e: 17.

Это может быть слишком ограничительным:

if (signatureFile.MaxRetrievable() != pub.SignatureLength()) {
    return false;
}

Фактическая длина подписи может быть немного меньше, чем MaxSignatureLength(), в зависимости от того, сколько ведущих 0 равноВозведение в степень дает.

Вы можете рассмотреть возможность следования одному из примеров вики.Например, из Схемы подписи RSA :

...

// Signing      
RSASS<PSSR, SHA1>::Signer signer(privateKey);
RSASS<PSSR, SHA1>::Verifier verifier(publicKey);

// Setup
byte message[] = "RSA-PSSR Test";
size_t messageLen = sizeof(message);      

////////////////////////////////////////////////
// Sign and Encode
SecByteBlock signature(signer.MaxSignatureLength(messageLen));

size_t signatureLen = signer.SignMessageWithRecovery(rng, message, messageLen, NULL, 0, signature);

// Resize now we know the true size of the signature
signature.resize(signatureLen);

////////////////////////////////////////////////
// Verify and Recover
SecByteBlock recovered(
    verifier.MaxRecoverableLengthFromSignatureLength(signatureLen)
);

DecodingResult result = verifier.RecoverMessage(recovered, NULL, 0, signature, signatureLen);

if (!result.isValidCoding) {
    throw Exception(Exception::OTHER_ERROR, "Invalid Signature");
}

////////////////////////////////////////////////
// Use recovered message
//  MaxSignatureLength is likely larger than messageLength
recovered.resize(result.messageLength);
...
0 голосов
/ 21 мая 2018

Вы пытаетесь загрузить открытый ключ, который необходимо проанализировать перед выполнением какой-либо проверки.Для этого вы передаете данные открытого ключа конструктору Verifier.Этот конструктор пытается проанализировать открытые ключи.

Теперь открытые ключи обычно представляют собой закодированные структуры данных.Эти структуры данных описываются языком описания данных, называемым ASN.1 или абстрактной синтаксической нотацией 1, и кодируются с использованием схемы, называемой BER, базовых правил кодирования для ASN.1.

Так что происходит, когда конструктор пытаетсячитать открытый ключ и, следовательно, вызывает BERDecode, так что имейте смысл ввода.К сожалению, ввод, скорее всего, не двоичный BER-кодированный вообще.

Поэтому для решения этой проблемы вам нужно либо использовать дополнительные вызовы в вашем приложении для преобразования в BER или объект открытого ключа, либо вам нужноконвертировать ваш ключ в BER.Если ключ защищен ASCII (формат PEM), вы можете использовать:

$ openssl rsa -pubin -inform PEM -in <filename of key in PEM format> -outform DER -out <filename of key in DER format>

Если это не сработает, пожалуйста, включите открытый ключ в ваш вопрос, чтобы мы могли проверить, почему он не анализируется.

...