Apakah saya melewatkan sesuatu? Apakah ini cara yang benar untuk membangun sertifikat yang ditandatangani sendiri?
Sangat mudah untuk membuat sertifikat yang ditandatangani sendiri. Anda cukup menggunakan openssl req
perintah. Mungkin sulit untuk membuatnya yang bisa dikonsumsi oleh pilihan klien terbesar, seperti browser dan alat baris perintah.
Ini sulit karena browser memiliki set persyaratan sendiri, dan mereka lebih ketat daripada IETF . Persyaratan yang digunakan oleh browser didokumentasikan di CA / Browser Forum (lihat referensi di bawah). Pembatasan muncul dalam dua bidang utama: (1) jangkar kepercayaan, dan (2) nama DNS.
Peramban modern (seperti warez yang kami gunakan pada 2014/2015) menginginkan sertifikat yang menghubungkan kembali ke jangkar kepercayaan, dan mereka ingin nama DNS disajikan dengan cara tertentu dalam sertifikat. Dan browser secara aktif bergerak melawan sertifikat server yang ditandatangani sendiri.
Beberapa browser tidak benar-benar membuatnya mudah untuk mengimpor sertifikat server yang ditandatangani sendiri. Faktanya, Anda tidak dapat menggunakan beberapa peramban, seperti peramban Android. Jadi solusi lengkapnya adalah menjadi otoritas Anda sendiri.
Dengan tidak adanya otoritas Anda sendiri, Anda harus mendapatkan hak nama DNS untuk memberikan sertifikat peluang sukses terbesar. Tetapi saya akan mendorong Anda untuk menjadi otoritas Anda sendiri. Sangat mudah untuk menjadi otoritas Anda sendiri, dan itu akan menghindari semua masalah kepercayaan (siapa yang lebih baik untuk dipercaya daripada diri Anda sendiri?).
Ini mungkin bukan situs yang Anda cari!
Sertifikat keamanan situs tidak tepercaya!
Ini karena browser menggunakan daftar jangkar trust yang telah ditentukan untuk memvalidasi sertifikat server. Sertifikat yang ditandatangani sendiri tidak mengikat kembali ke jangkar tepercaya.
Cara terbaik untuk menghindari ini adalah:
- Buat otoritas Anda sendiri (yaitu, menjadi CA )
- Buat permintaan penandatanganan sertifikat (CSR) untuk server
- Tandatangani CSR server dengan kunci CA Anda
- Instal sertifikat server di server
- Instal sertifikat CA pada klien
Langkah 1 - Buat otoritas Anda sendiri hanya berarti membuat sertifikat yang ditandatangani sendiri dengan CA: true
dan penggunaan kunci yang tepat. Itu berarti Subjek dan Penerbit adalah entitas yang sama, CA disetel ke true dalam Kendala Dasar (itu juga harus ditandai sebagai kritis), penggunaan kunci adalah keyCertSign
dan crlSign
(jika Anda menggunakan CRL), dan Subjek Key Identifier (SKI) adalah sama dengan Pengidentifikasi Kunci Otoritas (AKI).
Untuk menjadi otoritas sertifikat Anda sendiri, lihat * Bagaimana Anda menandatangani permintaan penandatanganan sertifikat dengan otoritas sertifikasi Anda? pada Stack Overflow. Kemudian, impor CA Anda ke Trust Store yang digunakan oleh browser.
Langkah 2 - 4 kira-kira apa yang Anda lakukan sekarang untuk server yang menghadap publik ketika Anda mendaftar layanan CA seperti Startcom atau CAcert . Langkah 1 dan 5 memungkinkan Anda untuk menghindari otoritas pihak ketiga, dan bertindak sebagai otoritas Anda sendiri (siapa yang lebih bisa dipercaya daripada diri Anda sendiri?).
Cara terbaik berikutnya untuk menghindari peringatan browser adalah dengan mempercayai sertifikat server. Tetapi beberapa browser, seperti browser default Android, jangan biarkan Anda melakukannya. Jadi itu tidak akan bekerja pada platform.
Masalah browser (dan agen pengguna serupa lainnya) tidak mempercayai sertifikat yang ditandatangani sendiri akan menjadi masalah besar di Internet of Things (IoT). Misalnya, apa yang akan terjadi ketika Anda terhubung ke termostat atau kulkas untuk memprogramnya? Jawabannya adalah, tidak ada yang baik sejauh pengalaman pengguna yang bersangkutan.
Kelompok Kerja WebAppSec W3C mulai melihat masalah ini. Lihat, misalnya, Proposal: Menandai HTTP Sebagai Tidak Aman .
Cara membuat sertifikat yang ditandatangani sendiri dengan OpenSSL
Perintah di bawah ini dan file konfigurasi membuat sertifikat yang ditandatangani sendiri (ini juga menunjukkan kepada Anda cara membuat permintaan penandatanganan). Mereka berbeda dari jawaban lain dalam satu hal: nama DNS yang digunakan untuk sertifikat yang ditandatangani sendiri adalah dalam Nama Alternatif Subjek (SAN) , dan bukan Nama Umum (CN) .
Nama DNS ditempatkan di SAN melalui file konfigurasi dengan baris subjectAltName = @alternate_names
(tidak ada cara untuk melakukannya melalui baris perintah). Lalu ada alternate_names
bagian dalam file konfigurasi (Anda harus menyetel ini sesuai dengan selera Anda):
[ alternate_names ]
DNS.1 = example.com
DNS.2 = www.example.com
DNS.3 = mail.example.com
DNS.4 = ftp.example.com
# Add these if you need them. But usually you don't want them or
# need them in production. You may need them for development.
# DNS.5 = localhost
# DNS.6 = localhost.localdomain
# IP.1 = 127.0.0.1
# IP.2 = ::1
Penting untuk menempatkan nama DNS di SAN dan bukan CN, karena baik IETF dan CA / Browser Forum menentukan praktiknya. Mereka juga menentukan bahwa nama-nama DNS di CN sudah usang (tetapi tidak dilarang). Jika Anda memasukkan nama DNS di CN, maka itu harus dimasukkan dalam SAN di bawah kebijakan CA / B. Jadi, Anda tidak dapat menghindari menggunakan Nama Alternatif Subjek.
Jika Anda tidak memasukkan nama DNS di SAN, maka sertifikat akan gagal divalidasi di bawah browser dan agen pengguna lain yang mengikuti pedoman CA / Browser Forum.
Terkait: browser mengikuti kebijakan CA / Browser Forum; dan bukan kebijakan IETF. Itulah salah satu alasan sertifikat yang dibuat dengan OpenSSL (yang umumnya mengikuti IETF) kadang-kadang tidak divalidasi di bawah browser (browser mengikuti CA / B). Mereka adalah standar yang berbeda, mereka memiliki kebijakan penerbitan yang berbeda dan persyaratan validasi yang berbeda.
Buat sertifikat yang ditandatangani sendiri (perhatikan penambahan -x509
opsi):
openssl req -config example-com.conf -new -x509 -sha256 -newkey rsa:2048 -nodes \
-keyout example-com.key.pem -days 365 -out example-com.cert.pem
Buat permintaan penandatanganan (perhatikan kurangnya -x509
pilihan):
openssl req -config example-com.conf -new -sha256 -newkey rsa:2048 -nodes \
-keyout example-com.key.pem -days 365 -out example-com.req.pem
Cetak sertifikat yang ditandatangani sendiri :
openssl x509 -in example-com.cert.pem -text -noout
Cetak permintaan penandatanganan :
openssl req -in example-com.req.pem -text -noout
File konfigurasi (diteruskan melalui -config
opsi)
[ req ]
default_bits = 2048
default_keyfile = server-key.pem
distinguished_name = subject
req_extensions = req_ext
x509_extensions = x509_ext
string_mask = utf8only
# The Subject DN can be formed using X501 or RFC 4514 (see RFC 4519 for a description).
# Its sort of a mashup. For example, RFC 4514 does not provide emailAddress.
[ subject ]
countryName = Country Name (2 letter code)
countryName_default = US
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = NY
localityName = Locality Name (eg, city)
localityName_default = New York
organizationName = Organization Name (eg, company)
organizationName_default = Example, LLC
# Use a friendly name here because it's presented to the user. The server's DNS
# names are placed in Subject Alternate Names. Plus, DNS names here is deprecated
# by both IETF and CA/Browser Forums. If you place a DNS name here, then you
# must include the DNS name in the SAN too (otherwise, Chrome and others that
# strictly follow the CA/Browser Baseline Requirements will fail).
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_default = Example Company
emailAddress = Email Address
emailAddress_default = test@example.com
# Section x509_ext is used when generating a self-signed certificate. I.e., openssl req -x509 ...
[ x509_ext ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
# You only need digitalSignature below. *If* you don't allow
# RSA Key transport (i.e., you use ephemeral cipher suites), then
# omit keyEncipherment because that's key transport.
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
subjectAltName = @alternate_names
nsComment = "OpenSSL Generated Certificate"
# RFC 5280, Section 4.2.1.12 makes EKU optional
# CA/Browser Baseline Requirements, Appendix (B)(3)(G) makes me confused
# In either case, you probably only need serverAuth.
# extendedKeyUsage = serverAuth, clientAuth
# Section req_ext is used when generating a certificate signing request. I.e., openssl req ...
[ req_ext ]
subjectKeyIdentifier = hash
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
subjectAltName = @alternate_names
nsComment = "OpenSSL Generated Certificate"
# RFC 5280, Section 4.2.1.12 makes EKU optional
# CA/Browser Baseline Requirements, Appendix (B)(3)(G) makes me confused
# In either case, you probably only need serverAuth.
# extendedKeyUsage = serverAuth, clientAuth
[ alternate_names ]
DNS.1 = example.com
DNS.2 = www.example.com
DNS.3 = mail.example.com
DNS.4 = ftp.example.com
# Add these if you need them. But usually you don't want them or
# need them in production. You may need them for development.
# DNS.5 = localhost
# DNS.6 = localhost.localdomain
# DNS.7 = 127.0.0.1
# IPv6 localhost
# DNS.8 = ::1
Anda mungkin perlu melakukan yang berikut untuk Chrome. Kalau tidak, Chrome mungkin mengeluh Nama Biasa tidak valid ( ERR_CERT_COMMON_NAME_INVALID
) . Saya tidak yakin apa hubungan antara alamat IP di SAN dan CN dalam hal ini.
# IPv4 localhost
# IP.1 = 127.0.0.1
# IPv6 localhost
# IP.2 = ::1
Ada aturan lain tentang penanganan nama DNS di sertifikat X.509 / PKIX. Lihat dokumen ini untuk aturan:
RFC 6797 dan RFC 7469 terdaftar, karena mereka lebih membatasi daripada RFC lain dan dokumen CA / B. RFC 6797 dan 7469 juga tidak mengizinkan alamat IP.