과거에 종료일이있는 자체 서명 인증서 작성


24

과거의 종료 날짜를 포함하여 임의의 시작 날짜와 종료 날짜를 사용하여 자체 서명 인증서를 즉석에서 작성하고 싶습니다 . OpenSSL과 같은 표준 도구를 사용하고 싶지만 작업을 수행하는 모든 것이 좋습니다.

스택 오버플로 질문 하루가 만료되지 않는 openssl 인증서를 생성하는 방법은 무엇입니까? 비슷한 질문을하지만 인증서에 자체 서명을 원합니다.

궁금한 점이 있으면 자동화 된 테스트에 인증서가 필요합니다.

답변:


32

과거에는 인증서를 작성하는 두 가지 방법이 있습니다. 시간을 가짜로하거나 (1) (2) 또는 인증서에 서명 할 때 시간 간격을 정의합니다 (3).

1) 첫째, 시간을 날조에 대해 : 하나 개의 프로그램이이 시스템에서 다른 날짜에 생각하게 좀보고 libfaketimefaketime

데비안에서 설치하려면 :

sudo apt-get install faketime

그런 다음 명령 faketime전에 사용 합니다 openssl.

사용 예 :

$faketime 'last friday 5 pm' /bin/date
Fri Apr 14 17:00:00 WEST 2017
$faketime '2008-12-24 08:15:42' /bin/date
Wed Dec 24 08:15:42 WET 2008

보낸 사람 man faketime:

주어진 명령은 현재 시스템 시간이 타임 스탬프에 지정된 시간임을 믿도록 속입니다. 벽시계는 달리 지정하지 않는 한이 날짜와 시간부터 계속 실행됩니다 (고급 옵션 참조). 실제로, faketime은 LD_PRELOAD 메커니즘을 사용하여 time (2) 및 fstat (2)와 같은 함수에 대한 시스템 호출을 가로채는 작은 라이브러리를로드하는 libfaketime의 간단한 래퍼입니다.

예를 들어, 경우에 따라 2008 년 날짜를 잘 정의한 다음 2 년에서 2010 년까지 유효한 인증서를 작성할 수 있습니다.

faketime '2008-12-24 08:15:42' openssl ... 

참고로,이 유틸리티는 MacOS를 포함한 여러 유닉스 버전에서 모든 종류의 프로그램 (명령 줄 전용)의 래퍼로 사용할 수 있습니다.

설명을 위해이 방법 (및 해당 자식)으로로드 된 바이너리 만 시간이 변경되었으며 가짜 시간은 나머지 시스템의 현재 시간에 영향을 미치지 않습니다.

2) @Wyzard 상태와 같이 사용중인 datefudge패키지와 매우 유사합니다 faketime.

차이점 datefudge은 영향을 미치지 않습니다 fstat(예 : 파일 시간 작성을 변경하지 않음). LD_PRELOAD를 사용하여로드 할 수있는 자체 라이브러리 인 datefudge.so도 있습니다.

또한 -s static time몇 초가 지나도 참조 시간이 항상 반환 되는 위치가 있습니다.

$ datefudge --static "2007-04-01 10:23" sh -c "sleep 3; date -R"
Sun, 01 Apr 2007 10:23:00 +0100

3) 시간을 허비하는 것 외에도 OpenSSL에서 인증서에 서명 할 때 인증서의 시작점과 끝점을 정의 할 수 있습니다 .

질문에서 연결하는 질문의 오해는 인증서 유효 기간이 요청 시간 (CSR 요청시)이 아니라 서명 할 때 정의된다는 것입니다.

사용하는 경우 openssl ca자체 서명 된 인증서를 만들려면 옵션을 추가 -startdate하고 -enddate.

의 openssl 소스에 따르면이 두 옵션의 날짜 형식 openssl/crypto/x509/x509_vfy.c은 ASN1_TIME, 즉 ASN1UTCTime입니다. 형식은 YYMMDDHHMMSSZ 또는 YYYYMMDDHHMMSSZ 여야합니다.

인용 openssl/crypto/x509/x509_vfy.c:

int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time)
{
    static const size_t utctime_length = sizeof("YYMMDDHHMMSSZ") - 1;
    static const size_t generalizedtime_length = sizeof("YYYYMMDDHHMMSSZ") - 1;
    ASN1_TIME *asn1_cmp_time = NULL;
    int i, day, sec, ret = 0;

    /*
     * Note that ASN.1 allows much more slack in the time format than RFC5280.
     * In RFC5280, the representation is fixed:
     * UTCTime: YYMMDDHHMMSSZ
     * GeneralizedTime: YYYYMMDDHHMMSSZ
     *
     * We do NOT currently enforce the following RFC 5280 requirement:
     * "CAs conforming to this profile MUST always encode certificate
     *  validity dates through the year 2049 as UTCTime; certificate validity
     *  dates in 2050 or later MUST be encoded as GeneralizedTime."
     */

그리고 CHANGE 로그 (2038 버그?)에서-이 변경 로그는 API를 직접 사용하는 사용자에게만 해당되므로 추가 각주와 같습니다.

1.1.0e와 1.1.1 사이의 변경 [xx XXX xxxx]

*) ASN.1 유형 INT32, UINT32, INT64, UINT64 및 Z 접두어를 추가하십시오. LONG 및 ZLONG을 대체하고 크기가 안전합니다. OpenSSL 1.2.0에서는 LONG 및 ZLONG을 사용하지 않는 것이 좋습니다.

따라서 2008 년 1 월 1 일부터 2010 년 1 월 1 일까지의 인증서 작성은 다음과 같이 수행 할 수 있습니다.

openssl ca -config /path/to/myca.conf -in req.csr -out ourdomain.pem \
-startdate 200801010000Z -enddate 201001010000Z

또는

openssl ca -config /path/to/myca.conf -in req.csr -out ourdomain.pem \
-startdate 0801010000Z -enddate 1001010000Z

-startdate-enddate에 나타나지 않는 openssl소스 및 변경 로그; @guntbert가 지적했듯이 메인 man openssl페이지 에는 나타나지 않지만 다음에 도 나타납니다 man ca.

-startdate date
       this allows the start date to be explicitly set. The format of the date is
       YYMMDDHHMMSSZ (the same as an ASN1 UTCTime structure).

   -enddate date
       this allows the expiry date to be explicitly set. The format of the date is
       YYMMDDHHMMSSZ (the same as an ASN1 UTCTime structure).

인용 openssl/CHANGE:

0.9.3a와 0.9.4 사이의 변화 [1999 년 8 월 9 일]

*) 'ca'프로그램의 -startdate 및 -enddate (없었던) 인수를 수정하십시오.

PS StackExchange에서 언급 한 질문 에 대한 답변 은 일반적으로 시스템 시간, 특히 프로덕션 시스템에서 변경하는 것이 좋지 않습니다 . 이 답변의 방법을 사용하면 루트 권한이 필요하지 않습니다.


1
+1. 나는 누군가가 내가 쓴 것보다 더 좋은 것을 가지고 올 것이라는 것을 알았습니다.
Celada

2
비슷한 프로그램도 있습니다 datefudge.
Wyzard --Sharming Monica 중지-4

@Wyzard 감사합니다. 사실 데비안에서 찾았습니다. 흥미롭게도 매뉴얼은 time (2)와 같은 함수에 대한 시스템 호출도 변경하지만 fstat (2)에는 영향을 미치지 않는다고 설명합니다.
Rui F Ribeiro

1
모두 faketimedatefudge작업 아름답게 내 데비안 제시 시스템.
rlandster

1
OTOH : 날짜를 설정할 위치 를 찾기 위해 +5 !
guntbert

8

나는 명백한 것이 효과가 있다는 사실에 거의 놀랐습니다 openssl. 인증서가 유효 해야하는 일 수를 인수로 취하면 음수를 입력하십시오!

openssl req -x509 -newkey rsa:4096 \
    -keyout key.pem -out cert.pem -days -365

유효 기간이 타임 스탬프 보다 유효 시작 타임 스탬프 보다 앞에 있는 인증서는 실제로 매우 이상한 결과를 낳습니다 . 실제로는 자동화 된 테스트에 이것을 사용하지 않는 것이 좋습니다. 이상하기 때문입니다. 유효 시작 타임 스탬프도 최신으로 유지하는 방법을 원할 것입니다.


글쎄, 공정하게, 나는 네가 부정적인 날을 사용할 수 있다는 것을 몰랐다.
Rui F Ribeiro

시작일을 지정할 수 없습니까?
FreeSoftwareServers

@FreeSoftwareServers CSR에서는 할 수 없습니다. 내 대답의 마지막 부분을 참조하십시오.
Rui F Ribeiro

더 간결하게 아직 코드 바가 그러한 인증서를 찾지 않습니까? btw, 나는 대답을 확장
Rui F Ribeiro

3

또는이 짧은 파이썬 프로그램과 같은 것을 사용할 수 있습니다 ... (캐비티 적용)

시작 시간이 지난 10 년 (-10 * 365 * 24 * 60 * 60 초는 -10 년)이고 만료 시간은 5 년인 키 (test.key)와 인증서 (test.crt)를 생성합니다. (-5 * 365 * 24 * 60 * 60).

이 프로그램은 최소한의 데모 프로그램이므로 확장명 (예 : basicConstraints)을 설정하지 않고 고정 된 직렬을 사용합니다.

#!/usr/bin/env python

from OpenSSL import crypto

key = crypto.PKey()
key.generate_key(crypto.TYPE_RSA, 2048)
cert = crypto.X509()
cert.get_subject().CN = "Test"
cert.set_serial_number(666)
cert.gmtime_adj_notBefore(-10*365*24*60*60)
cert.gmtime_adj_notAfter(-5*365*24*60*60)
cert.set_issuer(cert.get_subject())
cert.set_pubkey(key)
cert.sign(key, 'sha384')

open("test.crt", "wb").write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert))
open("test.key", "wb").write(crypto.dump_privatekey(crypto.FILETYPE_PEM, key))

코드에 필수 X.509 표준 필드가없는 것 같습니다.
Rui F Ribeiro

2
이것은 매우 도움이됩니다. 인증서 생성을보다 쉽게 ​​프로그래밍 방식으로 제어 할 수 있습니다.
rlandster
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.