PEM dosyası nasıl bölünür


37

Not: Bu gerçekten bir soru değil çünkü cevabı zaten buldum, ancak onu kolayca bulamadığım için başkalarına fayda sağlayabilmek için göndereceğim.

Soru: Birleştirilmiş bir PEM dosyasını apache / mod_ssl yönergesi SSLCACertificateFile tarafından kullanılan dosya olarak nasıl okunur ?

Cevap (orijinal) ( kaynak ):

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

Sonunda olduğu gibi, sonunda boş bir satır varsa, bu boş bir dosya bırakabilir openssl pkcs7 -outform PEM -in my-chain-file -print_certs. Bunu önlemek için, yazdırmadan önce hattın uzunluğunu kontrol edin:

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

Cevap 29.03.2016 :

@Slugchewer cevabını takiben , csplitdaha net bir seçenek olabilir:

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

Bu aptalca bir soru olabilir, fakat neden pem dosyamı bölmem gerekiyor?
Ashwani Agarwal

6
@AshwaniAgarwal Bir PEM dosyasını birkaç sertifika içerdiğinde ayırmak istersiniz ve opensslanaliz etmek için bir sertifika alan araçlar gibi araçları ayrı ayrı incelemek istersiniz .
Yasa 29,

Ek olarak, bazı araçlar veya sunucular sertifika ve anahtarla birleştirilmiş bir dosya isterken, diğerleri ayırmak ister.
captncraig

Boş bir dosyayı önlemek için csplit komut satırına '% ----- BEGIN CERTIFICATE -----%' eklemek zorunda kaldım. Man sayfasının belirttiği ile eşleşiyor gibi görünüyor: csplit -f ./tmp/cert- $ file '% ----- BAŞLANGIÇ BELGESİ -----%' '/ ----- BAŞLANGIÇ BELGESİ ----- / '' {*} '
Craig Hicks

2
boş dosyaları bırakmamak için "csplit -z" kullanın.
Paul M,

Yanıtlar:


23

Awk snippet'i, farklı parçaları çıkarmak için çalışır, ancak hala hangi bölümün / cert / zincirin anahtar olduğunu bilmeniz gerekir. Belirli bir bölümü çıkarmam gerekiyordu ve bunu OpenSSL posta listesinde buldum: 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

nice komut seti :) Gelecekte kullanmak için saklayacağım, ancak yukarıdaki kullanım durumumda, 50+ CA certs ==> pkey veya zincir içermeyen bir sertifika sadece dosyayla çalışıyorum
Cerber

2
Bunun awk çözümünden üstün olduğunu düşünüyorum, openssl ayrıştırmayı yapsın + dönüşümü alacaksın.
Paslı

Üzgünüm ama sadece pkey komutu doğru. İkinci ve üçüncü reklamlar ne yaparsanız yapmazlar - başka bir şey yaparlar. Bazı durumlarda sonuç, bazı durumlarda iyi sonuç verir, tüketicilerde gizemli davranışlar üretebilir. Biraz düzenlendi.
kubanczyk

Bu şekilde metinsel 3. sertifikanın nasıl alınacağı hakkında bir fikriniz var mı?
flickerfly


15

splitKomut çoğu sistemlerde kullanılabilir ve onun çağırma hatırlamak muhtemeldir kolaydır.

Dosyalara collection.pembölmek istediğiniz bir dosyanız varsa individual-*, şunu kullanın:

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

Eğer yoksa split, deneyebilirsiniz csplit:

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

2
Maalesef, sistemlerimden hiçbiri (meşgul kutusu, fedora, centos) split'te bir -pseçenek (ne de okuduğum manpages) göstermiyor . Belki özel bir ikili / paket kullanıyorsunuz
Cerber

1
@Cerber csplitBunun yerine deneyebilir ... (yukarıdaki düzenlemeye bakın)
squidpickles

1
ile iyi çalışıyor csplit!
Cerber

FreeBSD'de csplit'ten alıyorum: csplit: *}: bad repetition count(fakat bölünmüş iş görünüyor)
Gwyneth Llewelyn

4

Çok sertifikalu bir PEM paketinden tek bir sertifika almak istiyorsanız, şunu deneyin:

$ openssl crl2pkcs7 -nocrl -certfile INPUT.PEM | \
    openssl pkcs7 -print_certs | \
    awk '/subject.*CN=host.domain.com/,/END CERTIFICATE/'
  • İlk iki opensslkomut bir PEM dosyasını işleyecek "subject:"ve "issuer:"her bir sertifikadan önce önceden beklemekte olan satırlarla tükürecektir. PEM'iniz zaten bu şekilde biçimlendirilmişse, ihtiyacınız olan tek şey son awkkomuttur.
  • Awk komutu, CN (genel ad) dizgisine uyan bireysel PEM'i dağıtır.

kaynak1 , kaynak2


Bunu kaynağında göremiyorum. Bunun yanında, PEM Base64
kodludur

1
Evet, bu her PEM türü için işe yaramaz. Openssl kullanarak P7B'yi PEM'e çıkarırsanız, her sertifikadan önce listelenmiş bir konu satırı olacaktır. Veya PEM dosyanızı segmentlere ayırdığınız herhangi bir dizeyi değiştirebilirsiniz.
cmcginty 12:16

PEM "konusu" içermiyor koluna Güncelleme cevap
cmcginty

3

Ayrıca PEM dosyalarının sadece BEGIN/ ENDblokların içindeki bir anahtar / sertifika koleksiyonudur , bu nedenle bir veya iki ilginç varlık içeren tek bir dosya ise kesmek / yapıştırmak oldukça kolaydır ...


2

Sertifika ve sertifika yetkilisi zincirinin bir birleşimi olan tam zincir sertifikalarını (örneğin, letsencrypt / certbot vb. Tarafından oluşturulanlar) kullanıyorsanız, bash string manipülasyonunu kullanabilirsiniz.

Örneğin:

# 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-----

Sertifika ve sertifika yetkilisi zincirini değişkenlere çıkarmak için:

# 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')

Açıklama:

Awk veya openssl kullanmak yerine (ki bunlar güçlü araçlardır ancak her zaman kullanılamaz, yani Docker Alpine görüntülerinde), bash string manipülasyonunu kullanabilirsiniz.

"${FULLCHAIN%%-----END CERTIFICATE-----*}-----END CERTIFICATE-----": FULLCHAIN ​​içeriğinin sonundan en uzun alt dize eşleşmesini geri getirin, sonra sıyrılıncaya kadar eşleştirin -----END CERTIFICATE-----. Bundan *sonraki tüm karakterlerle eşleşir -----END CERTIFICATE-----.

$(echo -e "${FULLCHAIN#*-----END CERTIFICATE-----}" | sed '/./,$!d'): FULLCHAIN ​​içeriğinin başından itibaren en kısa alt dize eşleşmesini geri getirin, sonra yeni satırları soyun. Aynı şekilde, önceki *tüm karakterlerle eşleşir -----END CERTIFICATE-----.

Hızlı başvuru için ( burada bash'ta string manipülasyon hakkında daha fazla bilgi bulabilirsiniz ):

${VAR#substring}= VAR içeriğinin başından itibaren en kısa alt dize

${VAR%substring}= VAR içeriğinin sonundan en kısa alt dize

${VAR##substring}= VAR içeriğinin başından itibaren en uzun alt dize

${VAR%%substring}= VAR içeriğinin sonundan en uzun alt dize


Daha az bash meraklısı için, bu değişkenleri dışa aktardığınızda, çizgiyi kesmek için alışılmadıklarını korumak için değişkeni tırnak işaretleri içine alın. Bunun bana çok açık olmadığını hatırlıyorum. Fabio, bash string manipülasyonunun tatlı kullanımı!
flickerfly

0

Hmmm ... hemen hemen aynı şekilde, bu durumu pek çok insanın var gibi göründüğünü fark etmeden hazırladım. Benim çözümüm neredeyse aynı mantığı izlemekte ancak bazı temel komutları kullanmaktadır:

Bütün paralarım dosyada: certin.pem

c=0
while read line
  do
    if echo $line | grep END; then
    echo $line >> certout$c.pem
    c=`expr $c + 1`
    else
     echo $line
     echo $line >> certout$c.pem
    fi
done < /tmp/certin.pem

Bu, temel olarak "SON" ile karşılaşana kadar bir dosyada yazmaya devam eder ve ardından artımlı şekilde başka bir dosyaya yazmaya başlar. Bu şekilde , giriş pem dosyanızdaki ( certin.pem ) kaç tane sertifika bulunduğuna bağlı olarak "N" sayıdaki dosyalarınız ( certout0.pem, certout1.pem ve benzeri ..) dosyalarınız olacaktır .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.