PEM 파일을 분할하는 방법


37

참고 : 이것은 이미 답을 찾았 기 때문에 실제로는 질문이 아니지만 여기서 쉽게 찾을 수 없으므로 다른 사람들에게 도움이 될 수 있도록 게시 할 것입니다.

질문 : 연결된 PEM 파일을 apache / 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-----/' '{*}'

이것은 멍청한 질문 일 수 있지만 왜 내 pem 파일을 분할해야합니까?
Ashwani Agarwal

6
@AshwaniAgarwal 여러 인증서가 포함되어있을 때 PEM 파일을 분할하고 openssl하나의 인증서를 분석하는 데 사용되는 도구를 사용하여 인증서를 개별적으로 검사하려고합니다 .
법률 29

또한 일부 도구 나 서버는 인증서와 키가 결합 된 파일을 원하지만 다른 도구 나 서버는 별도의 파일을 원합니다.
captncraig

빈 파일을 방지하기 위해 csplit 명령 줄에 '% ----- BEGIN CERTIFICATE ----- %'를 추가해야했습니다. 매뉴얼 페이지에서 지정한 것과 일치하는 것 같습니다 : csplit -f ./tmp/cert- $ file '% ----- BEGIN CERTIFICATE ----- %' '/ ----- BEGIN CERTIFICATE ----- / ''{*} '
Craig는

2
빈 파일을 남기지 않으려면 "csplit -z"를 사용하십시오.
Paul M

답변:


23

awk 스 니펫은 다른 부분을 추출하는 데 사용되지만 여전히 키 / 인증서 / 체인 섹션을 알아야합니다. 특정 섹션을 추출해야했고 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

nice command set :) 나중에 사용하기 위해 보관할 것이지만 위의 유스 케이스에서는 50 개 이상의 CA 인증서가 포함 된 인증서 전용 파일로 작업하고 있습니다. ==> pkey 또는 chain 없음
Cerber

2
나는 이것이 awk 솔루션보다 우수하다고 생각합니다. openssl이 구문 분석을 수행하게하고 변환을하십시오.
Rusty

죄송하지만 pkey 명령 만 정확합니다. 두 번째와 세 번째는 광고하는 것을하지 않습니다. 그들은 다른 것을합니다. 어떤 경우에는 결과가 좋으며 어떤 경우에는 소비자에게 신비한 행동을 일으킬 수 있습니다. 조금 편집했습니다.
kubanczyk 2016 년

이 방법으로 텍스트로 된 세 번째 인증서를 얻는 방법에 대한 아이디어가 있습니까?
깜박임

15

이것은 이전에 StackOverflow에서 답변되었습니다 .

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

29/03/2016 수정 : @slugchewer answer 참조


Linux에서만 작동하며 FreeBSD에서는 작동하지 않습니다.
Michael-O

3
이것에 영감을 받아 인증서와 키를 별도의 파일로 분리하는 awk 스크립트를 만들었습니다. gist.github.com/jinnko/d6867ce326e8b6e88975
JinnKo

15

split명령은 대부분의 시스템에서 사용 가능하며 호출이 기억하기 쉬울 것입니다.

파일 collection.pem로 분할하려는 파일 이 있으면 다음을 individual-*사용하십시오.

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

이 없으면 다음을 split시도해보십시오 csplit.

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

2
죄송합니다, 내 시스템 (busybox, fedora, centos) 중 어느 것도 -p옵션으로 ( 내가 읽은 맨 페이지 도 ) 표시 하지 않습니다 . 어쩌면 당신은 특별한 바이너리 / 패키지를 사용하고있을 것입니다
Cerber

1
@Cerber csplit대신 시도해 볼 수 있습니다 ... (위의 편집 참조)
squidpickles

1
잘 작동합니다 csplit!
Cerber

FreeBSD에서 나는 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 (일반 이름) 문자열과 일치하는 개별 PEM을 분리합니다.

source1 , source2


나는 당신의 출처에서 이것을 보지 못했습니다. 게다가, PEM은 Base64로 인코딩되어 "주제", "CN"등의 텍스트를 찾지 못합니다. awk
Cerber

1
예, 모든 유형의 PEM에서 작동하지는 않습니다. openssl을 사용하여 P7B를 PEM으로 추출하면 각 인증서 앞에 제목 줄이 표시됩니다. 또는 PEM 파일을 분류하는 문자열을 수정할 수 있습니다.
cmcginty

PEM에 "대상"이 포함되지 않은 경우 처리하도록 응답이 업데이트되었습니다.
cmcginty

3

또한 PEM 파일BEGIN/ END블록 내부의 키 / 인증서 모음 일 뿐이 므로 하나 또는 두 개의 흥미로운 엔티티가있는 단일 파일 인 경우 잘라 내기 / 붙여 넣기가 쉽습니다 ...


2

인증서와 인증 기관 체인을 연결하는 전체 체인 인증서 (즉, letencrypt / certbot 등에서 생성 된 인증서)를 처리하는 경우 bash 문자열 조작을 사용할 수 있습니다.

예를 들면 다음과 같습니다.

# 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 또는 openssl (강력한 도구이지만 항상 사용 가능한 것은 아님) (예 : Docker Alpine 이미지) 대신 bash 문자열 조작을 사용할 수 있습니다.

"${FULLCHAIN%%-----END CERTIFICATE-----*}-----END CERTIFICATE-----": FULLCHAIN의 내용 끝에서 가장 긴 부분 문자열 일치를 반환 한 다음 -----END CERTIFICATE-----제거 되면 연결 됩니다. 는 *이후의 모든 문자와 일치합니다 -----END CERTIFICATE-----.

$(echo -e "${FULLCHAIN#*-----END CERTIFICATE-----}" | sed '/./,$!d'): FULLCHAIN의 내용 시작 부분에서 가장 짧은 부분 문자열 일치를 반환 한 다음 선행하는 새 줄을 제거합니다. 마찬가지로, *이전의 모든 문자와 일치합니다 -----END CERTIFICATE-----.

빠른 참조를 위해 (bash 에서 문자열 조작에 대한 자세한 내용은 here ) :

${VAR#substring}= VAR 내용의 시작 부분에서 가장 짧은 부분 문자열

${VAR%substring}= VAR 내용의 끝에서 가장 짧은 부분 문자열

${VAR##substring}= VAR 내용의 시작 부분에서 가장 긴 부분 문자열

${VAR%%substring}= VAR 내용의 끝에서 가장 긴 부분 문자열


덜 bash 정통한 경우, 이러한 변수를 반향하면 변수를 따옴표로 묶어 줄 바꿈을 유지하여 변수를 보는 데 사용되는 방식을 유지하십시오. 그게 나에게 분명하지 않은 때를 기억합니다. Fabio, bash 문자열 조작의 달콤한 사용!
깜박임

0

흠 ...이 상황이 많은 사람들이 가지고 있다는 것을 깨닫지 않고 솔루션을 준비한 것과 거의 같은 방법입니다 (@ @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"가 나타날 때까지 파일에 기록한 다음 증가 된 방식으로 다른 파일에 기록을 시작합니다. 이 방법으로 입력 pem 파일 ( certin.pem ) 에 몇 개의 인증서가 있는지에 따라 "N"개의 출력 파일 ( certout0.pem, certout1.pem 등) 파일을 갖게 됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.