2015-11-09 1 views
0

J'ai travaillé sur le signataire et le vérificateur numérique en utilisant Crypto ++. J'ai rencontré le problème suivant: mon signataire et vérificateur fonctionne bien sur les clés publiques et privées que j'ai générées par programmation en utilisant le premier exemple (Générer une paire de clés RSA et l'enregistrer) à partir de ce wiki. Mais quand j'utilise une autre paire de clés de test que j'ai été fourni pour tester, j'ai l'erreur suivante: "erreur de décodage de BER" ​​en essayant de charger la clé pour la signature. J'ai cherché sur Internet, mais je n'arrive pas à résoudre le problème. Voici mes classes:Erreur de décodage BER lors du chargement de la clé

class DSUtility 
{ 
protected: 
    DSUtility() = default; 
    template<typename KeyType, typename KeySourceType> 
    KeyType PrepareKey_(const std::string& key_source);  
}; 

template<typename KeyType, typename KeySourceType> 
KeyType DSUtility::PrepareKey_(const std::string& key_source) 
{ 
    CryptoPP::ByteQueue key_bytes; 
    KeySourceType(key_source.c_str(), true, new CryptoPP::Base64Decoder).TransferTo(key_bytes); 
    key_bytes.MessageEnd(); 
    KeyType key; 
    key.Load(key_bytes); // FAILS WHEN TRYING TO SIGN WITH ANOTHER PRIVATE KEY 
    return key; 
} 


class Signer : private DSUtility 
{ 
public:  
    Signer(const std::string& private_key); 

    std::string Sign(const std::string& data); 

private: 
    typedef CryptoPP::RSA::PrivateKey PrivateKey; 
    CryptoPP::RSASS<CryptoPP::PKCS1v15, CryptoPP::SHA256>::Signer signer_; 
}; 


Signer::Signer(const std::string& private_key) : 
signer_(PrepareKey_<PrivateKey, CryptoPP::StringSource>(private_key)) 
{ 
} 

std::string Signer::Sign(const std::string& data) 
{ 
    CryptoPP::SecByteBlock signature(signer_.SignatureLength()); 
    signer_.SignMessage(CryptoPP::AutoSeededRandomPool(), (byte const*)data.c_str(), data.size(), signature); 
    return std::string(signature.begin(), signature.end()); 
} 

une de mes clés (qui fonctionne) ressemble à ceci:

MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAILkZnFV77ckeZkepDk1fvsE 
qli05im29PTZq0ayWZsSgis+tpzP2KpSigWimAfkOCF36Y1Zb9E8VcxBaRbEEH0ObQTQdOl0 
z1Cf0mViD2dQgH+8ZucU2gKy0YDpjIJ6wZM55azNZBg1s5J9PuDyM+nMRh5RiJqEpaXSXzgV... 

autre regarde les éléments suivants:

-----BEGIN RSA PRIVATE KEY----- 
MIICXAIBAAKBgQDGwB5n/xMsDoqo+bGaws15FYGGjsJxCM2deHJZqV2QKfvkmStf 
8HntPqaJ+mc9UA6ghN1uGndChg1PuHSNVaRU2x8fem/mFUhfOJaZcYich8JAy0nm 
sJUOwoRqLfKjLWmqy0QZHXDDVw+sD5uq/oOvfFFjuYIcsskHQmGTfkdJrQIDAQAB... 
+0

Avez-vous essayé de supprimer cette ligne '----- BEGIN RSA PRIVATE KEY -----', évidemment différente? – mkl

+0

Oui, je l'ai fait à la première étape :) –

Répondre

1

But when I use another test key pair I was provided to test, I have the following error: "BER decode error" when trying to load key for signing.

Il est difficile de dire ce qui ne va pas ... Vous devez fournir réel touches de test. Cela ne vaut pas le temps d'essayer de décoder un faux avec "..." parce que nous savons que ça va échouer. Je ne fais que deviner, mais il peut s'agir d'une clé brute (c'est-à-dire, la clé publique ou privée, sans l'identificateur) plutôt qu'une information clé (la séquence externe et l'identificateur avec le public interne ou privé). clé). Ce dernier (l'info clé) est parfois appelé subjectPublicKeyIdnfo lorsqu'il s'agit d'une clé publique.

Vous voudrez peut-être jeter un oeil à Keys and Formats sur le wiki Crypto ++. Le guide que vous avez cité est un peu vieux, et il est fourni à des fins historiques.Voici le 3-deuxième tour:

  • Lorsque vous chargez un raw key, appelez BERDecode
  • Lorsque vous chargez un key info, appelez Load
  • Lorsque vous enregistrez un raw key, appelez DEREecode
  • Lorsque vous enregistrez un key info, appelez Save

template<typename KeyType, typename KeySourceType> KeyType 
DSUtility::PrepareKey_(const std::string& key_source) 
{ 
    CryptoPP::ByteQueue key_bytes; 
    KeySourceType(key_source.c_str(), true, new CryptoPP::Base64Decoder).TransferTo(key_bytes); 
    key_bytes.MessageEnd(); 
    KeyType key; 
    key.Load(key_bytes); // FAILS WHEN TRYING TO SIGN WITH ANOTHER PRIVATE KEY 
    return key; 
} 

Cela peut probablement être un peu simplifié:

template<typename KeyType, typename KeySourceType> KeyType 
DSUtility::PrepareKey_(const std::string& key_source) 
{ 
    ArraySource as((const byte*)key_source.data(), key_source.size(), 
           true, new Base64Decoder()); 
    key.Load(as); 
    return key; 
} 

Et si c'est un raw key, vous pouvez essayer:

key.BERDecode(as); 

"... another one looks the following: -----BEGIN RSA PRIVATE KEY----- ..."

Pour les clés codées PEM, voir PEM Pack sur le wiki du Crypto.

Voici une référence à une question de dépassement de pile, mais elle ne fait que citer la page wiki de Crypto ++ (en plus des autres réponses): Load PEM encoded private RSA key in Crypto++.


FAILS WHEN TRYING TO SIGN WITH ANOTHER PRIVATE KEY

En outre, « échoue en essayant de signer une autre clé privée » est différent de « échoue en essayant de charger ». J'ai essayé de rester concentré sur la question que vous avez posée, donc ce n'est peut-être pas la réponse que vous espériez.

Une fois que vous passez un peu de temps sur Stack Overflow, vous pourriez lassez des personnes qui ont répondu à la question qu'ils espéraient que ce serait plutôt que la question qui a été effectivement demandé. Je me suis fatigué très vite, donc j'essaie de rester très concentré en répondant (c'est la raison pour laquelle je cite tout ce que je réponds, même si c'est un commentaire).