Charger la clé RSA privée codée PEM dans Crypto ++

Souvent, l’utilisateur aura des clés privées RSA codées PEM. Crypto ++ nécessite que ces clés soient au format DER pour être chargées. J’ai déjà demandé aux gens de convertir manuellement leurs fichiers PEM en DER en utilisant openssl comme ceci:

openssl pkcs8 -in in_file.pem -out out_file.der -topk8 -nocrypt -outform der 

Cela fonctionne bien, mais certaines personnes ne comprennent pas comment faire cela et ne veulent pas le faire. Je voudrais donc convertir les fichiers PEM en fichiers DER automatiquement dans le programme.

Est-ce aussi simple que de rayer les mots “—– BEGIN CERTIFICATE —–” et “—– END CERTIFICATE —–” du PEM ou faut-il une autre transformation? On m’a dit qu’entre ces marqueurs, il s’agissait simplement de DER codé en b64. Voici un code qui illustre le problème:

 // load the private key CryptoPP::RSA::PrivateKey PK; CryptoPP::ByteQueue bytes; try { CryptoPP::FileSource File( rsa.c_str(), true, new CryptoPP::Base64Decoder() ); File.TransferTo( bytes ); bytes.MessageEnd(); // This line Causes BERDecodeError when a PEM encoded file is used PK.Load( bytes ); } catch ( CryptoPP::BERDecodeErr ) { // Convert PEM to DER and try to load the key again } 

J’aimerais éviter de passer des appels système à openssl et effectuer la transformation entièrement en Crypto ++ afin que les utilisateurs puissent fournir le format et les éléments “fonctionnant simplement”. Merci pour tout conseil.

Oui, c’est un stream DER codé avec Base64. Notez que, outre le marquage des marqueurs BEGIN et END, dans le cas du format de clé RSA, vous devez également supprimer tout indicateur pouvant être inséré entre le marqueur BEGIN et les données codées. Seule la partie restante peut être décodée en Base64 avec succès. Il semble que vous transmettiez le fichier de certificate complet au décodeur et que cela nécessite une réparation.

Je sais que c’est une vieille question, mais d’autres pourraient trouver cela utile. Une fois que vous enlevez les marqueurs, vous vous retrouvez avec le matériau de la clé «intérieure» Selon http://www.cryptopp.com/wiki/Keys_and_Formats#BER_and_DER_Encoding, vous pouvez utiliser BERDecodePrivateKey pour le charger. Donc, pour charger une clé openssl dont les marqueurs ont été enlevés, vous pouvez faire quelque chose comme:

 bool LoadKey(RandomNumberGenerator& rng, const std::ssortingng& file, RSA::PrivateKey& key) { ByteQueue q; FileSource KeyFile(file.c_str(), true, new Base64Decoder); KeyFile.TransferTo(q); key.BERDecodePrivateKey(q,false,0); // last 2 params unused return key.Validate(rng, 2); } 

… Je voudrais convertir les fichiers PEM en fichiers DER automatiquement dans le programme.

En juillet 2014, un pack PEM a été fourni pour la bibliothèque Crypto ++. Le pack PEM est une implémentation partielle du cryptage des messages qui vous permet de lire et d’écrire des clés et des parameters codés PEM, y compris des clés privées cryptées. Les fichiers supplémentaires incluent la prise en charge des clés RSA, DSA, EC, ECDSA et des parameters Diffie-Hellman.

C’est un ajout à la bibliothèque et ne fait pas partie de la bibliothèque proprement dite. Vous téléchargez un ZIP et ajoutez cinq fichiers sources à la bibliothèque. Ensuite, vous construisez la bibliothèque (Crypto ++ les récupère automatiquement). Le fichier ZIP contient cinq fichiers sources supplémentaires, un script pour créer des clés de test à l’aide d’OpenSSL, un programme C ++ pour tester la lecture et l’écriture des clés, et un script pour vérifier les clés écrites par Crypto ++ à l’aide d’OpenSSL.

Voici comment vous l’utiliseriez:

 CryptoPP::RSA::PrivateKey pk; CryptoPP::FileSource file("", true); CryptoPP::PEM_Load(file, pk); CryptoPP::AutoSeededRandomPool prng; bool = pk.Validate(prng, 3); if (! valid) throw ... 

Si les clés sont cryptées, voici comment vous les charger. Le module PEM ré-implémente EVP_BytesToKey d’OpenSSL, de sorte que la dérivation de clé fonctionne et que vous puissiez interopérer:

 CryptoPP::RSA::PrivateKey pk; CryptoPP::FileSource file("", true); std::ssortingng pass = ""; CryptoPP::PEM_Load(file, pk, pass.data(), pass.size()); CryptoPP::AutoSeededRandomPool prng; bool = pk.Validate(prng, 3); if (! valid) throw ... 

Il y a aussi un PEM_Save , vous pouvez donc écrire les clés directement à partir de Crypto ++. Par exemple:

 // Generate it or load it from somewhere CryptoPP::RSA::PrivateKey pk = ...; CryptoPP::FileSink file("", true); CryptoPP::PEM_Save(file, pk); 

Et PEM_Save pour une clé chiffrée (ou la clé que vous souhaitez chiffrer):

 // Generate it or load it from somewhere CryptoPP::RSA::PrivateKey pk = ...; CryptoPP::FileSink file("", true); std::ssortingng pass = ""; CryptoPP::PEM_Save(file, pk, "AES-128-CBC", pass.data(), pass.size()); 

PEM_Load n’a pas besoin d’algorithme car il est codé dans l’en-tête encapsulé. PEM_Save besoin d’un algorithme car il n’y a pas d’algorithme par défaut.