終了日が過去の自己署名証明書を作成する

終了日が過去の自己署名証明書を作成する

任意の開始日と終了日(終了日を含む)を指定した自己署名証明書を即座に作成したいのですが、過去OpenSSL などの標準ツールを使用することをお勧めしますが、目的を達成できるものであれば何でも結構です。

Stack Overflowの質問有効期限が 1 日未満の OpenSSL 証明書を生成するにはどうすればよいでしょうか?同様の質問をしますが、証明書を自己署名にしたいです。

ご参考までに、自動テストには証明書が必要です。

答え1

これまで証明書を作成する方法は2つありました。時間を偽造する方法(1)(2)、または証明書に署名するときに時間間隔を定義する方法(3)です。

1) まず、時間を偽装することについて: あるプログラムにシステムとは異なる日付であると思わせるにはlibfaketimefaketime

Debian にインストールするには:

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 は libfaketime の単純なラッパーであり、LD_PRELOAD メカニズムを使用して、time(2) や fstat(2) などの関数へのシステム呼び出しをインターセプトする小さなライブラリをロードします。

したがって、たとえば、あなたの場合、2008 年の日付を定義して、2010 年までの 2 年間の有効期間を持つ証明書を作成することができます。

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

ちなみに、このユーティリティは、MacOS を含むいくつかの Unix バージョンで、あらゆる種類のプログラム (コマンド ラインに限定されません) のラッパーとして使用できます。

明確に言うと、このメソッドでロードされたバイナリ (およびその子) のみの時刻が変更され、偽の時刻はシステムの残りの部分の現在の時刻には影響しません。

datefudge2) @Wyzard が述べているように、と使用方法が非常によく似ているパッケージもあります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 ソースによると、これら 2 つのオプションの日付形式はopenssl/crypto/x509/x509_vfy.cASN1_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."
     */

そして、変更ログ(2038 バグ?)から - この変更ログは、API を直接使用するユーザーのみに関係するため、単なる追加の脚注です。

1.1.0e と 1.1.1 の間の変更点 [xx XXX xxxx]

*) ASN.1 型 INT32、UINT32、INT64、UINT64 および Z で始まるバリアントを追加します。これらは LONG および ZLONG を置き換え、サイズが安全になるように意図されています。LONG および ZLONG の使用は推奨されておらず、OpenSSL 1.2.0 で廃止される予定です。

したがって、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ソースと CHANGE ログに表示され-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から参照してください:それは一般的に悪いアイデア特に実稼働システムでは、システム時刻を変更するために使用します。この回答の方法を使用する場合、ルート権限は必要ありません。

答え2

明らかなことが機能することに驚きました。openssl引数として証明書の有効日数を指定する代わりに、負の数を指定するだけです。

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

これは実際には非常に奇妙な結果になることに注意してください。有効期限のタイムスタンプが先行する有効期間の開始タイムスタンプです。奇妙なので、自動テストにこれを使用することは実際にはお勧めしません。有効期間の開始タイムスタンプを遡る方法も必要になるでしょう。

答え3

または、この短い Python プログラムのようなものを使用することもできます... (注意事項が適用されます)

開始時刻が 10 年前 (-10*365*24*60*60 秒は -10 年)、有効期限が 5 年前 (-5*365*24*60*60) のキー (test.key) と証明書 (test.crt) を作成します。

これは最小限のデモ プログラムであるため、拡張機能 (例: 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))

答え4

ステップ1。フェイクタイムをインストールする

sudo apt-get install faketime

ステップ2。現在の日付の 1 日前に期限切れの証明書を生成します。

faketime 'last friday 5 pm' /bin/bash -c 'openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 6 -nodes'

ステップ3証明書の有効期限を確認する

openssl x509 -noout -text -in cert.pem

証明書の有効期限 - スクリーンショット

関連情報