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


24

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

Stack Overflowの質問有効期限が1日未満のopenssl証明書を生成する方法は?同様の質問をしますが、証明書に自己署名してもらいたいです。

あなたが疑問に思っている場合、自動テストには証明書が必要です。

回答:


32

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

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

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

sudo apt-get install faketime

その後faketimeopensslコマンドの前に使用します。

使用例:

$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

違いとして、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

これら2つのオプションの日付形式は、のopensslソースによると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-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ありがとう、確かにDebianで見つけました。興味深いことに、マニュアルには、time(2)などの関数へのシステムコールも変更されますが、fstat(2)には影響しないと記載されています。
ルイFリベイロ

1
両方faketimedatefudge仕事美しく、私のDebianジェシーシステム上。
ランドスター

1
OTOH:これらの日付を設定する場所を見つけるため +5 !
guntbert

8

明白なことが機能することを知って驚くopensslことです。証明書が有効な日数を引数として取るので、負の数を入力してください!

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

これにより、実際には非常に奇妙な結果が生じることに注意してください。有効期限のタイムスタンプの前に有効期限のタイムスタンプを持つ証明書。奇妙だから、自動テストにこれを使うことは実際にはお勧めしません。おそらく、有効期限のタイムスタンプもバックデートする方法が必要でしょう。


まあ、公平にするために、私はあなたが否定的な日を使うことができるとは思いもしませんでした。
ルイFリベイロ

開始日を指定できませんか?
FreeSoftwareServers

@FreeSoftwareServers CSRではできません。私の答えの最後の部分を見てください。
ルイFリベイロ

さらに興味深いことに、このような証明書を見つけることはできませんか?ところで、私は答えを拡大しました
ルイFリベイロ

3

または、この短い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))

コードには必須のX.509標準フィールドが欠落しているようです。
ルイFリベイロ

2
これは非常に役立ちます。証明書の作成をプログラムで簡単に制御できます。
rlandster
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.