66 votes

Comment diviser un fichier PEM

Note : Ce n'est pas vraiment une question car j'ai déjà trouvé la réponse mais comme je ne l'ai pas trouvée facilement ici, je vais la poster pour qu'elle puisse profiter à d'autres.

Question : Comment lire un fichier PEM concaténé comme celui utilisé par la directive apache/mod_ssl ? SSLCACertificateFile ?

Réponse (originale) ( fuente ) :

cat $file|awk 'split_after==1{n++;split_after=0} /-----END CERTIFICATE-----/ {split_after=1} {print > "cert" n ".pem"}'

Cela peut laisser un fichier vide s'il y a une ligne vierge à la fin, comme dans le cas suivant openssl pkcs7 -outform PEM -in my-chain-file -print_certs . Pour éviter cela, vérifiez la longueur de la ligne avant d'imprimer :

cat $file|awk 'split_after==1{n++;split_after=0}
   /-----END CERTIFICATE-----/ {split_after=1}
   {if(length($0) > 0) print > "cert" n ".pem"}' 

Réponse 29/03/2016 :

Suivre @slugchewer responder , csplit pourrait être une option plus claire avec :

csplit -f cert- $file '/-----BEGIN CERTIFICATE-----/' '{*}'

43voto

Le snippet awk fonctionne pour extraire les différentes parties, mais vous avez toujours besoin de savoir quelle section est la clé / le cert / la chaîne. J'avais besoin d'extraire une section spécifique, et j'ai trouvé ceci sur la liste de diffusion d'OpenSSL : http://openssl.6102.n7.nabble.com/Convert-pem-to-crt-and-key-files-tp47681p47697.html

# Extract key
openssl pkey -in foo.pem -out foo-key.pem

# Extract all the certs
openssl crl2pkcs7 -nocrl -certfile foo.pem |
  openssl pkcs7 -print_certs -out foo-certs.pem

# Extract the textually first cert as DER
openssl x509 -in foo.pem -outform DER -out first-cert.der

35voto

Maria Points 1

Les split est disponible sur la plupart des systèmes, et son invocation est probablement plus facile à mémoriser.

Si vous avez un fichier collection.pem que vous souhaitez diviser en individual-* utiliser :

split -p "-----BEGIN CERTIFICATE-----" collection.pem individual-

Si vous n'avez pas split Vous pouvez essayer csplit :

csplit -s -z -f individual- collection.pem '/-----BEGIN CERTIFICATE-----/' '{*}'

-s ne pas imprimer la taille des fichiers

-z ne crée pas de fichiers vides

19voto

d34dfish Points 21

Il s'agissait précédemment répondu sur StackOverflow :

awk '
  split_after == 1 {n++;split_after=0}
  /-----END CERTIFICATE-----/ {split_after=1}
  {print > "cert" n ".pem"}' < $file

Editer le 29/03/2016 : Voir @slugchewer responder

9voto

Peteter Points 448

Si vous souhaitez obtenir un seul certificat à partir d'un paquet PEM multicertificat, essayez :

$ openssl crl2pkcs7 -nocrl -certfile INPUT.PEM | \
    openssl pkcs7 -print_certs | \
    awk '/subject.*CN=host.domain.com/,/END CERTIFICATE/'
  • Les deux premiers openssl traitera un fichier PEM et le recrachera avec les informations suivantes "subject:" y "issuer:" lignes avant chaque certitude. Si votre PEM est déjà formaté de cette manière, tout ce dont vous avez besoin est la ligne finale awk commandement.
  • La commande awk recréera les PEM individuels correspondant à la chaîne CN (nom commun).

source1 , source2

7voto

Fabio Points 151

Si vous manipulez des certificats à chaîne complète (c'est-à-dire ceux générés par letsencrypt / certbot etc), qui sont une concaténation du certificat et de la chaîne de l'autorité de certification, vous pouvez utiliser la manipulation de chaînes de bash.

Par exemple :

# content of /path/to/fullchain.pem
-----BEGIN CERTIFICATE-----
some long base64 string containing
the certificate
-----END CERTIFICATE-----

-----BEGIN CERTIFICATE-----
another base64 string
containing the first certificate
in the authority chain
-----END CERTIFICATE-----

-----BEGIN CERTIFICATE-----
another base64 string
containing the second certificate
in the authority chain
(there might be more...)
-----END CERTIFICATE-----

Pour extraire le certificat et la chaîne de l'autorité de certification dans des variables :

# load the certificate into a variable
FULLCHAIN=$(</path/to/fullchain.pem)
CERTIFICATE="${FULLCHAIN%%-----END CERTIFICATE-----*}-----END CERTIFICATE-----"
CHAIN=$(echo -e "${FULLCHAIN#*-----END CERTIFICATE-----}" | sed '/./,$!d')

Explication :

Au lieu d'utiliser awk ou openssl (qui sont des outils puissants mais pas toujours disponibles, par exemple dans les images Docker Alpine), vous pouvez utiliser la manipulation de chaînes de caractères bash.

"${FULLCHAIN%%-----END CERTIFICATE-----*}-----END CERTIFICATE-----" à partir de la fin du contenu de FULLCHAIN, retourner la plus longue correspondance de sous-chaîne, puis concaténer -----END CERTIFICATE----- et qu'il est dépouillé. Les * correspond à tous les caractères après -----END CERTIFICATE----- .

$(echo -e "${FULLCHAIN#*-----END CERTIFICATE-----}" | sed '/./,$!d') : à partir du début du contenu de FULLCHAIN, renvoie la sous-chaîne la plus courte, puis supprime les nouvelles lignes qui la précèdent. De même, la fonction * correspond à tous les caractères précédant -----END CERTIFICATE----- .

Pour une référence rapide (bien que vous puissiez trouver plus d'informations sur la manipulation des chaînes de caractères dans bash) aquí ):

${VAR#substring} = la chaîne la plus courte du début du contenu de VAR

${VAR%substring} = la chaîne la plus courte à partir de la fin du contenu de VAR

${VAR##substring} = la plus longue chaîne de caractères à partir du début du contenu de VAR

${VAR%%substring} = la plus longue chaîne de caractères à partir de la fin du contenu de VAR

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X