PEM फ़ाइल को कैसे विभाजित करें


38

नोट: यह वास्तव में एक सवाल नहीं है क्योंकि मुझे पहले से ही जवाब मिल गया था, लेकिन जब से मुझे यह आसानी से नहीं मिला, तो मैं इसे यहां पोस्ट कर दूंगा ताकि यह दूसरों को लाभ पहुंचा सके।

प्रश्न: अपाचे / mod_ssl निर्देश SSLCACertificateFile द्वारा उपयोग किए गए के रूप में एक संक्षिप्त पीईएम फ़ाइल कैसे पढ़ें ?

उत्तर (मूल) ( स्रोत ):

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

यह एक खाली फ़ाइल छोड़ सकता है अगर वहाँ अंत में एक रिक्त रेखा है, जैसे कि openssl pkcs7 -outform PEM -in my-chain-file -print_certs। इसे रोकने के लिए, छपाई से पहले लाइन की लंबाई जांचें:

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

उत्तर 29/03/2016 :

@Slugchewer उत्तर के बाद , इसके csplitसाथ एक स्पष्ट विकल्प हो सकता है:

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

यह एक गूंगा सवाल हो सकता है, लेकिन मुझे अपनी पीएम फाइल को विभाजित करने की आवश्यकता क्यों होगी?
अश्वनी अग्रवाल

6
@AshwaniAgarwal आप एक PEM फ़ाइल को विभाजित करना चाहते हैं जब इसमें कई प्रमाण पत्र होते हैं और आप ऐसे प्रमाणपत्रों के साथ व्यक्तिगत रूप से प्रमाणपत्रों की जांच करना चाहते हैं जैसे opensslविश्लेषण करने के लिए एक प्रमाणपत्र लें।
Law29

इसके अतिरिक्त, कुछ उपकरण या सर्वर प्रमाणित और कुंजी के साथ एक संयुक्त फ़ाइल चाहते हैं, जबकि अन्य उन्हें अलग करना चाहते हैं।
५५ पर captncraig

मुझे एक खाली फ़ाइल को रोकने के लिए csplit कमांड लाइन में '% ----- BEGIN CERTIFICATE -----%' जोड़ना था। यह दिखाने के लिए कि मैन पेज क्या निर्दिष्ट करता है: csplit -f/tmp/cert- $ फ़ाइल '% ----- BEGIN CERTIFICATE -----%' '/ ----- BEGIN CERTIFICATE ----- / '' {*} '
क्रेग हिक्स

2
खाली फ़ाइलों को न छोड़ने के लिए "csplit -z" का उपयोग करें।
पॉल एम

जवाबों:


23

Awk स्निपेट अलग-अलग हिस्सों को निकालने के लिए काम करता है, लेकिन आपको अभी भी यह जानने की जरूरत है कि किस सेक्शन की कुंजी / सर्टिफिकेट / चेन है। मुझे एक विशिष्ट अनुभाग निकालने की आवश्यकता थी, और ओपनएसएसएल मेलिंग सूची पर यह पाया गया: http://openssl.6102.n7.nabble.com/Convert-pem-to-crt-and-key-files-tp56868pp69697.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

अच्छा कमांड सेट :) मैं इसे भविष्य में उपयोग के लिए रखूंगा, लेकिन ऊपर दिए गए मेरे उपयोग के मामले में, मैं एक प्रमाण-पत्र के साथ काम कर रहा हूं, जिसमें केवल 50+ सीए
सेर्ट्स

2
मुझे लगता है कि यह समाधान को जगाने के लिए बेहतर है, खुलने को पार्सिंग करने दें + आपको रूपांतरण मिलता है।
रस्टी

मुझे खेद है, लेकिन केवल pkey कमांड सही है। दूसरा और तीसरा वह नहीं करते जो आप करते हैं - वे कुछ और करते हैं। कुछ मामलों में परिणाम अच्छा है कुछ मामलों में यह उपभोक्ताओं में रहस्यमय व्यवहार उत्पन्न कर सकता है। थोड़ा एड किया।
कुबंज़िक

किसी भी विचार कैसे इस तरह से 3 जी प्रमाण पत्र प्राप्त करने के लिए?
झिलमिलाहट

16

यह पहले StackOverflow पर उत्तर दिया गया था :

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

संपादित करें 29/03/2016 : देखें @slugchewer जवाब


केवल लिनक्स पर काम करता है, FreeBSD पर विफल रहता है।
माइकल-ओ

3
इससे प्रेरित होकर मैंने एक अजीब स्क्रिप्ट बनाई है जो अलग-अलग फाइलों में सेर्ट्स
जिंको

15

splitआदेश सबसे सिस्टम पर उपलब्ध है, और उसके मंगलाचरण संभावना याद रखना अधिक आसान है।

यदि आपके पास कोई फ़ाइल है collection.pemजिसे आप individual-*फ़ाइलों में विभाजित करना चाहते हैं , तो उपयोग करें:

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

यदि आपके पास नहीं है split, तो आप कोशिश कर सकते हैं csplit:

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

2
क्षमा करें, मेरे कोई भी सिस्टम (बिजीबॉक्स, फेडोरा, सेंटो) विभाजन पर एक -pविकल्प नहीं दिखाते हैं (और न ही मैं पढ़ता हूं )। शायद आप एक विशेष बाइनरी / पैकेज का उपयोग कर रहे हैं
सेबर

1
@Cerber csplitइसके बजाय प्रयास कर सकता है ... (ऊपर संपादित देखें)
स्क्वीडपल्स

1
के साथ ठीक काम करता है csplit!
सेर्बर

फ्रीबीएसडी पर मुझे सीएसपीएलटी से मिलता है: csplit: *}: bad repetition count(लेकिन विभाजन काम करने लगता है)
Gwyneth Llewelyn

4

यदि आप एक बहु-प्रमाणपत्र PEM बंडल से एकल प्रमाणपत्र प्राप्त करना चाहते हैं, तो प्रयास करें:

$ openssl crl2pkcs7 -nocrl -certfile INPUT.PEM | \
    openssl pkcs7 -print_certs | \
    awk '/subject.*CN=host.domain.com/,/END CERTIFICATE/'
  • पहले दो opensslकमांड एक PEM फाइल को प्रोसेस करेंगे "subject:"और "issuer:"प्रत्येक सर्टिफिकेशन से पहले प्री-पेंडिंग और लाइनों के साथ इसे वापस थूक देंगे । यदि आपका PEM पहले से ही इस तरह से स्वरूपित है, तो आपको केवल अंतिम awkकमांड की आवश्यकता है ।
  • Awk कमांड CN (सामान्य नाम) स्ट्रिंग से मेल खाने वाले व्यक्तिगत पीईएम को थूक देगा।

source1 , source2


मैं इसे आपके स्रोत में नहीं देखता। इसके अलावा, PEM Base64 एनकोडेड हैं, जिसमें आपको "सब्जेक्ट", "CN", ... जैसे
aw नहीं मिलेंगे

1
हां, यह हर प्रकार के पीईएम के लिए काम नहीं करता है। यदि आप ओप्सनल का उपयोग करके P7B को PEM में निकालते हैं, तो यह प्रत्येक प्रमाणपत्र से पहले सूचीबद्ध एक विषय रेखा होगी। या आप अपनी PEM फाइल को सेगमेंट में बदल सकते हैं।
cmcginty

जब पीईएम में "विषय" नहीं होता है तो संभाल करने के लिए अद्यतित उत्तर
अक्टूबर को '22

3

यह भी ध्यान देने योग्य है कि PEM फाइलेंBEGIN / ENDब्लॉक के अंदर कीज़ / सर्टिफिकेट्स का एक संग्रह है , इसलिए इसे सिर्फ कट या पेस्ट करना बहुत आसान है यदि यह एक या दो दिलचस्प संस्थाओं के साथ एक सिंगल फ़ाइल है ...


2

यदि आप फुल चेन सर्टिफिकेट (यानी लेटेन्सक्रिप्ट / सर्टिफिकेट आदि द्वारा जेनरेट किए गए हैं) को हैंडल कर रहे हैं, जो सर्टिफिकेट और सर्टिफिकेट अथॉरिटी चेन का एक कॉनसेप्ट हैं, तो आप बैश स्ट्रिंग मैनिपुलेशन का उपयोग कर सकते हैं।

उदाहरण के लिए:

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

प्रमाणपत्र और प्रमाणपत्र प्राधिकरण श्रृंखला को चर में निकालने के लिए:

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

स्पष्टीकरण:

इसके बजाय awk या opsl (जो शक्तिशाली उपकरण हैं, लेकिन हमेशा उपलब्ध नहीं हैं, यानी डॉकर अल्पाइन छवियों में) का उपयोग करने के बजाय, आप बैश स्ट्रिंग हेरफेर का उपयोग कर सकते हैं।

"${FULLCHAIN%%-----END CERTIFICATE-----*}-----END CERTIFICATE-----": फुलचैन की सामग्री के अंत से, सबसे लंबे समय तक प्रतिस्थापित होने वाले मैच को वापस लौटाएं, फिर -----END CERTIFICATE-----इसे हटा दें। के *बाद सभी पात्रों से मेल खाता है -----END CERTIFICATE-----

$(echo -e "${FULLCHAIN#*-----END CERTIFICATE-----}" | sed '/./,$!d'): फुलचैन की सामग्री की शुरुआत से, सबसे छोटा सबरिंग मैच लौटाएं, फिर नई लाइनों को लीड करें। इसी तरह, *पहले सभी पात्रों से मेल खाता है -----END CERTIFICATE-----

एक त्वरित संदर्भ के लिए (जब आप यहां बैश में स्ट्रिंग हेरफेर के बारे में अधिक जान सकते हैं ):

${VAR#substring}= VAR की सामग्री की शुरुआत से सबसे छोटा प्रतिस्थापन

${VAR%substring}= VAR की सामग्री के अंत से सबसे छोटा विकल्प

${VAR##substring}= VAR की सामग्री की शुरुआत से सबसे लंबा प्रतिस्थापन

${VAR%%substring}= VAR की सामग्री के अंत से सबसे लंबा प्रतिस्थापन


कम बैश सेवी के लिए, जब आप इन चर को प्रतिध्वनित करते हैं, तो लाइन को संरक्षित करने के लिए उद्धरणों के साथ चर को घेर लेते हैं, जिस तरह से आप उन्हें देखने के लिए उपयोग किए जाते हैं। मुझे याद है कि जब यह मेरे लिए इतना स्पष्ट नहीं था। फैबियो, बैश स्ट्रिंग हेरफेर का मीठा उपयोग!
झिलमिलाहट

0

हम्म् ... लगभग उसी तरह से मैंने बिना किसी एहसास के समाधान तैयार किया (जैसा कि y @Cerber ने सुझाव दिया है) कि यह स्थिति बहुत से लोगों की है। मेरा समाधान लगभग एक ही तर्क का पालन करता है लेकिन कुछ और मूल आदेशों का उपयोग करें:

मेरे सभी सेर्ट फाइल में हैं: 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

यह मूल रूप से "END" का सामना करने तक एक फाइल में लिखता रहता है और फिर बढ़े हुए तरीके से दूसरी फाइल पर लिखना शुरू करता है। इस तरह आपके पास आउटपुट नंबर्स ( certout0.pem, certout1.pem इत्यादि ) की "एन" संख्या होगी । आपकी इनपुट पीएम फाइल ( सर्टिफिकेट.पेम ) में कितने सर्टिफिकेट हैं, इस पर निर्भर करती है ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.