Buat sertifikat yang ditandatangani sendiri dengan tanggal akhir di masa lalu


24

Saya ingin membuat sertifikat yang ditandatangani sendiri dengan cepat dengan tanggal mulai dan akhir yang sewenang-wenang, termasuk tanggal akhir di masa lalu . Saya lebih suka menggunakan alat standar, misalnya, OpenSSL, tetapi apa pun yang menyelesaikan pekerjaan akan sangat bagus.

Pertanyaan Stack Overflow Bagaimana cara menghasilkan sertifikat openssl dengan masa berlaku kurang dari satu hari? mengajukan pertanyaan serupa, tetapi saya ingin sertifikat saya ditandatangani sendiri.

Jika Anda bertanya-tanya, sertifikat diperlukan untuk pengujian otomatis.

Jawaban:


32

Anda memiliki dua cara membuat sertifikat di masa lalu. Baik memalsukan waktu (1) (2), atau menentukan interval waktu saat menandatangani sertifikat (3).

1) Pertama, tentang berpura-pura waktu: untuk membuat satu program berpikir itu berbeda dengan sistem, lihat libfaketimedanfaketime

Untuk menginstalnya di Debian:

sudo apt-get install faketime

Anda kemudian akan menggunakan faketimesebelum opensslperintah.

Sebagai contoh penggunaan:

$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

Dari man faketime:

Perintah yang diberikan akan diperdaya untuk meyakini bahwa waktu sistem saat ini adalah yang ditentukan dalam timestamp. Jam dinding akan terus berjalan dari tanggal dan waktu ini kecuali ditentukan lain (lihat opsi lanjutan). Sebenarnya, faketime adalah pembungkus sederhana untuk libfaketime, yang menggunakan mekanisme LD_PRELOAD untuk memuat pustaka kecil yang memotong panggilan sistem ke fungsi seperti waktu (2) dan fstat (2).

Jadi misalnya, dalam kasus Anda, Anda dapat menentukan tanggal 2008, dan kemudian membuat sertifikat dengan masa berlaku 2 tahun hingga 2010.

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

Sebagai catatan tambahan, utilitas ini dapat digunakan dalam beberapa versi Unix, termasuk MacOS, sebagai pembungkus untuk segala jenis program (tidak eksklusif untuk baris perintah).

Sebagai klarifikasi, hanya binari yang dimuat dengan metode ini (dan anak-anak mereka) yang waktu mereka berubah, dan waktu palsu tidak mempengaruhi waktu saat ini dari sisa sistem.

2) Seperti yang dinyatakan @ Wyzard, Anda juga memiliki datefudgepaket yang sangat mirip digunakan faketime.

Sebagai perbedaan, datefudgetidak mempengaruhi fstat(yaitu tidak mengubah pembuatan waktu file). Ia juga memiliki perpustakaannya sendiri, datefudge.so, yang dimuat menggunakan LD_PRELOAD.

Ini juga memiliki -s static timetempat waktu yang dirujuk selalu dikembalikan meskipun berapa detik ekstra telah berlalu.

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

3) Selain memalsukan waktu, dan bahkan lebih sederhana, Anda juga dapat menentukan titik awal dan titik akhir validitas sertifikat saat menandatangani sertifikat di OpenSSL.

Kesalahpahaman dari pertanyaan yang Anda tautkan dalam pertanyaan Anda, adalah bahwa validitas sertifikat tidak didefinisikan pada waktu permintaan (pada permintaan CSR), tetapi ketika menandatanganinya.

Saat menggunakan openssl cauntuk membuat sertifikat yang ditandatangani sendiri, tambahkan opsi -startdatedan -enddate.

Format tanggal dalam dua opsi tersebut, menurut sumber openssl di openssl/crypto/x509/x509_vfy.c, adalah ASN1_TIME alias ASN1UTCTime: formatnya harus YYMMDDHHMMSSZ atau YYYYMMDDHHMMSSZ.

Mengutip 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."
     */

Dan dari log CHANGE (2038 bug?) - Log perubahan ini hanya sebagai catatan kaki tambahan, karena hanya menyangkut mereka yang menggunakan langsung API.

Perubahan antara 1.1.0e dan 1.1.1 [xx XXX xxxx]

*) Tambahkan ASN.1 jenis INT32, UINT32, INT64, UINT64 dan varian yang diawali dengan Z. Ini dimaksudkan untuk menggantikan LONG dan ZLONG dan agar ukurannya aman. Penggunaan LONG dan ZLONG tidak disarankan dan dijadwalkan untuk penghentian dalam OpenSSL 1.2.0.

Jadi, membuat sertifikat dari 1 Januari 2008 hingga 1 Januari 2010, dapat dilakukan sebagai:

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

atau

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

-startdatedan -enddatemuncul di opensslsumber dan GANTI log; seperti yang dicatat @guntbert, walaupun mereka tidak muncul di man opensslhalaman utama , mereka juga muncul di 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).

Mengutip openssl/CHANGE:

Perubahan antara 0.9.3a dan 0.9.4 [09 Agu 1999]

*) Perbaiki argumen -startdate dan -enddate (yang tidak ada) untuk program 'ca'.

PS Adapun jawaban yang dipilih dari pertanyaan yang Anda referensi dari StackExchange: umumnya merupakan ide yang buruk untuk mengubah waktu sistem, terutama dalam sistem produksi; dan dengan metode dalam jawaban ini Anda tidak perlu hak akses root saat menggunakannya.


1
+1. Saya tahu seseorang akan datang dengan sesuatu yang lebih baik dari apa yang saya tulis :)
Celada

2
Ada juga program serupa yang disebut datefudge.
Wyzard --Hentikan Harming Monica--

@ Wyzard Terima kasih, memang saya menemukannya di Debian; cukup menarik, manual menyatakan bahwa sementara itu juga mengubah panggilan sistem ke fungsi seperti waktu (2), itu tidak mempengaruhi fstat (2).
Rui F Ribeiro

1
Keduanya faketimedan datefudgebekerja dengan baik pada sistem jessie Debian saya.
rlandster

1
OTOH: +5 untuk mencari tahu di mana mengatur tanggal-tanggal itu!
guntbert

8

Saya hampir terkejut menemukan bahwa hal yang jelas berhasil: sedangkan opensslsebagai argumen berapa hari sertifikat harus valid, cukup berikan angka negatif!

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

Perhatikan bahwa ini sebenarnya menghasilkan sesuatu yang sangat aneh: sertifikat yang cap waktu kedaluwarsanya mendahului cap waktu dimulainya validitasnya. Saya sebenarnya tidak menyarankan Anda menggunakan ini untuk pengujian otomatis Anda, karena ini aneh. Anda mungkin ingin cara untuk meng-backest timestamp dimulainya validitas juga.


Agar adil, saya tidak tahu Anda bisa menggunakan hari-hari negatif.
Rui F Ribeiro

Bisakah Anda tidak menentukan tanggal mulai?
FreeSoftwareServers

@FreeSoftwareServers Dalam CSR Anda tidak bisa; lihat bagian terakhir dari jawaban saya.
Rui F Ribeiro

Lebih menarik lagi, tidakkah kode barf menemukan sertifikat seperti itu? btw, saya memperluas jawaban saya
Rui F Ribeiro

3

Atau Anda dapat menggunakan sesuatu seperti program python pendek ini ... (peringatan berlaku)

Itu menciptakan kunci (test.key) dan sertifikat (test.crt) dengan waktu awal 10 tahun di masa lalu (-10 * 365 * 24 * 60 * 60 detik adalah -10 tahun) dan waktu kedaluwarsa 5 tahun di masa lalu (-5 * 365 * 24 * 60 * 60).

Harap perhatikan bahwa ini adalah program demonstrasi minimal, jadi tidak perlu mengatur ekstensi apa pun, (mis. Kendala dasar) dan menggunakan serial tetap.

#!/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))

kode tampaknya hilang bidang standar penting X.509.
Rui F Ribeiro

2
Ini sangat membantu. Ini memberi saya kontrol terprogram yang lebih mudah atas pembuatan sertifikat.
rlandster
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.