web-dev-qa-db-ja.com

過去の終了日を使用して自己署名証明書を作成する

pastに終了日を含め、任意の開始日と終了日を使用して自己署名証明書をその場で作成したいと思います。私はOpenSSLなどの標準的なツールを使用したいと思いますが、仕事を成し遂げるものなら何でも素晴らしいでしょう。

スタックオーバーフローの質問 有効期限が1日未満のopenssl証明書を生成する方法 は同様の質問をしますが、自分の証明書に自己署名させたいです。

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

24
rlandster

過去に証明書を作成する方法は2つあります。時間を偽装するか(1)(2)、または証明書に署名するときの時間間隔を定義します(3)。

1)最初に、時間の偽装について: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バージョンで、あらゆる種類のプログラム(コマンドライン専用ではない)のラッパーとして使用できます。

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

2)@Wyzardが述べているように、datefudgeと非常によく似たfaketimeパッケージもあります。

違いとして、datefudgefstatに影響しません(つまり、ファイル時間の作成は変更されません)。また、LD_PRELOADを使用してロードする独自のライブラリdatefudge.soもあります。

また、-sstatic timeがあり、余分な秒数が経過したにもかかわらず、参照されている時間が常に返されます。

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

3)時間を偽造することに加えて、さらに簡単に、signingで証明書の有効期限の開始点と終了点を定義することもできます。 OpenSSL。

質問にリンクする質問の誤解は、証明書の有効性はリクエスト時(CSRリクエスト時)ではなく、署名時に定義されるということです。

openssl caを使用して自己署名証明書を作成する場合は、オプション-startdateおよび-enddateを追加します。

これら2つのオプションの日付形式は、openssl/crypto/x509/x509_vfy.cのopensslソースによれば、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."
     */

また、変更ログから(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-enddateopensslソースとCHANGEログに表示されます。 @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(欠落していた)引数を修正しました。

追伸 question の選択された回答については、StackExchangeから参照します。通常、システム時刻を変更するのは悪い考えです。特に生産システムでは。この回答のメソッドを使用すると、それらを使用するときにroot権限は必要ありません。

34
Rui F Ribeiro

明白なことが機能していることに私はほとんど驚いています:opensslは、証明書が有効である必要がある日数を引数として取りますが、負の数を指定するだけです!

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

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

8
Celada

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

それは、過去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))
3
Edheldil