Pertanyaan Bagaimana cara membuat sertifikat yang ditandatangani sendiri dengan openssl?


Saya menambahkan dukungan https ke perangkat linux tertanam. Saya telah mencoba membuat sertifikat yang ditandatangani sendiri dengan langkah-langkah ini:

openssl req -new > cert.csr
openssl rsa -in privkey.pem -out key.pem
openssl x509 -in cert.csr -out cert.pem -req -signkey key.pem -days 1001
cat key.pem>>cert.pem

Ini berfungsi, tetapi saya mendapatkan beberapa kesalahan dengan, misalnya, google chrome:

Ini mungkin bukan situs yang Anda cari!
  Sertifikat keamanan situs tidak tepercaya!

Apakah saya kehilangan sesuatu? Apakah ini cara yang benar untuk membuat sertifikat yang ditandatangani sendiri?


854
2018-04-16 14:14


asal


Jawaban:


Anda dapat melakukannya dalam satu perintah:

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

Anda juga bisa menambahkan -nodes jika Anda tidak ingin melindungi kunci pribadi Anda dengan frasa sandi, selain itu akan meminta Anda untuk kata sandi "setidaknya 4 karakter". Parameter hari (365) Anda dapat mengganti dengan nomor apa pun untuk memengaruhi tanggal kedaluwarsa. Kemudian akan meminta Anda untuk hal-hal seperti "Nama Negara" tetapi Anda cukup menekan enter dan menerima default.

Menambahkan -subj '/CN=localhost' untuk menekan pertanyaan tentang isi sertifikat (ganti localhost dengan domain yang Anda inginkan)

Sertifikat yang ditandatangani sendiri tidak divalidasi dengan pihak ketiga kecuali Anda mengimpornya ke browser sebelumnya. Jika Anda membutuhkan lebih banyak keamanan, Anda harus menggunakan sertifikat yang ditandatangani oleh CA.


1485
2018-04-16 15:04



Apakah saya kehilangan sesuatu? Apakah ini cara yang benar untuk membuat sertifikat yang ditandatangani sendiri?

Mudah untuk membuat sertifikat yang ditandatangani sendiri. Anda cukup menggunakan openssl req perintah. Ini dapat menjadi rumit untuk membuat satu yang dapat dikonsumsi oleh pilihan klien terbesar, seperti browser dan alat baris perintah.

Ini sulit karena browser memiliki persyaratannya sendiri, dan mereka lebih ketat daripada IETF. Persyaratan yang digunakan oleh peramban didokumentasikan di Forum CA / Browser (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 mengembalikan 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 memudahkan untuk mengimpor sertifikat server yang ditandatangani sendiri. Bahkan, Anda tidak bisa dengan beberapa browser, seperti browser Android. Jadi solusi lengkapnya adalah menjadi otoritas Anda sendiri.

Dengan tidak adanya otoritas Anda sendiri, Anda harus mendapatkan nama DNS yang tepat untuk memberikan sertifikat peluang terbesar untuk sukses. Tetapi saya akan mendorong Anda untuk menjadi otoritas Anda sendiri. Mudah untuk menjadi otoritas Anda sendiri dan akan memihak semua masalah kepercayaan (siapa yang lebih baik untuk percaya daripada diri sendiri?).


Ini mungkin bukan situs yang Anda cari!
  Sertifikat keamanan situs tidak tepercaya!

Ini karena peramban menggunakan daftar jangkar kepercayaan yang telah ditetapkan untuk memvalidasi sertifikat server. Sertifikat yang ditandatangani sendiri tidak berantai kembali ke jangkar tepercaya.

Cara terbaik untuk menghindari ini adalah:

  1. Buat otoritas Anda sendiri (mis., Menjadi CA)
  2. Buat permintaan penandatanganan sertifikat (CSR) untuk server
  3. Tandatangani CSR server dengan kunci CA Anda
  4. Instal sertifikat server di server
  5. 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 diatur ke true dalam Kendala Dasar (itu juga harus ditandai sebagai kritis), penggunaan utamanya adalah keyCertSign dan crlSign (jika Anda menggunakan CRL), dan Subjek Pengenal Kunci (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? di 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 Startcom atau CAcert. Langkah 1 dan 5 memungkinkan Anda untuk menghindari otoritas pihak ketiga, dan bertindak sebagai otoritas Anda sendiri (yang lebih baik untuk percaya daripada diri sendiri?).

Cara terbaik berikutnya untuk menghindari peringatan browser adalah mempercayai sertifikat server. Tetapi beberapa browser, seperti peramban bawaan Android, tidak membiarkan Anda melakukannya. Jadi itu tidak akan berfungsi di platform.

Masalah peramban (dan agen pengguna serupa lainnya) tidak percaya diri menandatangani sertifikat akan menjadi masalah besar di Internet of Things (IoT). Misalnya, apa yang akan terjadi ketika Anda terhubung ke termostat atau kulkas untuk memprogramnya? Jawabannya, 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.


Bagaimana cara membuat sertifikat yang ditandatangani sendiri dengan openssl?

Perintah di bawah dan file konfigurasi membuat sertifikat yang ditandatangani sendiri (itu 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 berada di Nama Alternatif Subjek (SAN), dan bukan Nama Umum (CN).

Nama-nama DNS ditempatkan di SAN melalui file konfigurasi dengan garis subjectAltName = @alternate_names (tidak ada cara untuk melakukannya melalui baris perintah). Lalu ada sebuah alternate_names bagian dalam file konfigurasi (Anda harus menyesuaikan 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
# DNS.7       = 127.0.0.1

# IPv6 localhost
# DNS.8     = ::1

Penting untuk memasukkan nama DNS di SAN dan bukan CN karena kedua IETF dan CA / Browser Forum menentukan praktiknya. Mereka juga menentukan bahwa nama DNS di CN tidak berlaku lagi (tetapi tidak dilarang). Jika Anda memasukkan nama DNS di CN, lalu itu harus dimasukkan dalam SAN berdasarkan kebijakan CA / B. Jadi Anda tidak dapat menghindari menggunakan Nama Alternatif Subjek.

Jika Anda tidak menaruh 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 Forum CA / Browser; dan bukan kebijakan IETF. Itulah salah satu alasan mengapa sertifikat dibuat dengan OpenSSL (yang umumnya mengikuti IETF) terkadang tidak memvalidasi di bawah Browser (browser mengikuti CA / B). Standar mereka berbeda, mereka memiliki kebijakan penerbitan yang berbeda dan persyaratan validasi yang berbeda.


Buat sertifikat yang ditandatangani sendiri (perhatikan penambahan -x509 pilihan):

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 pilihan)

[ 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 its 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 hal-hal berikut untuk Chrome. Jika tidak Chrome mungkin mengeluh a Nama yang umum 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-dokumen ini untuk aturan:

RFC 6797 dan RFC 7469 terdaftar karena mereka lebih ketat daripada dokumen RFC dan CA / B lainnya. RFC 6797 dan 7469 tidak biarkan alamat IP juga.


390
2018-01-13 21:12



Berikut adalah opsi yang dijelaskan di Jawaban @ diegows, dijelaskan lebih detail, dari dokumentasi:

openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days XXX
req

Permintaan sertifikat PKCS # 10 dan utilitas pembuat sertifikat.

-x509

opsi ini mengeluarkan sertifikat yang ditandatangani sendiri alih-alih permintaan sertifikat.   Ini biasanya digunakan untuk menghasilkan sertifikat uji atau CA akar yang ditandatangani sendiri.

-newkey arg

opsi ini membuat permintaan sertifikat baru dan kunci pribadi baru. Argumen   mengambil satu dari beberapa bentuk. rsa: nbits, dimana nbits adalah jumlah bit,   menghasilkan kunci RSA nbits dalam ukuran.

-keyout filename

ini memberi nama file untuk menulis kunci privat yang baru dibuat.

-out filename

Ini menentukan nama file output untuk menulis ke atau output standar secara default.

-days n

ketika -x509 opsi yang digunakan ini menentukan jumlah hari untuk sertifikasi   sertifikat untuk. Standarnya adalah 30 hari.

-nodes

jika opsi ini ditentukan maka jika kunci privat dibuat maka tidak akan dienkripsi.

Dokumentasi sebenarnya lebih rinci daripada di atas, saya hanya meringkasnya di sini.


353
2018-04-13 01:48



Saya tidak bisa berkomentar, jadi akan menempatkan ini sebagai jawaban terpisah. Saya menemukan beberapa masalah dengan jawaban satu baris yang diterima:

  • Satu-liner termasuk kata sandi dalam kunci.
  • Satu-liner menggunakan SHA1 yang di banyak browser melempar peringatan di konsol.

Berikut ini adalah versi sederhana yang menghapus frasa sandi, meningkatkan keamanan untuk menekan peringatan dan menyertakan saran di komentar untuk dilewatkan dalam -subj untuk menghapus daftar pertanyaan lengkap:

openssl genrsa -out server.key 2048
openssl rsa -in server.key -out server.key
openssl req -sha256 -new -key server.key -out server.csr -subj '/CN=localhost'
openssl x509 -req -sha256 -days 365 -in server.csr -signkey server.key -out server.crt

Ganti 'localhost' dengan domain apa pun yang Anda inginkan. Anda harus menjalankan dua perintah pertama satu per satu sebagai openssl akan meminta kata sandi.

Untuk menggabungkan keduanya menjadi file .pem:

cat server.crt server.key > cert.pem

106
2017-08-13 09:44



Perintah berikut:

openssl req -x509 -newkey rsa:4096 -sha256 -nodes -keyout example.key -out example.crt -subj "/CN=example.com" -days 3650

membuat sertifikat untuk domain example.com itu adalah

  • relatif kuat (pada 2018) dan
  • berlaku untuk 3650 hari (~ 10 tahun).

Ini menciptakan file-file berikut:

  • Kunci pribadi: example.key
  • Sertifikat: example.crt

Karena semua informasi disediakan pada baris perintah, tidak ada masukan interaktif yang mengganggu. Selain itu, semua langkah yang diperlukan dijalankan oleh satu permintaan OpenSSL ini: dari pembuatan kunci privat hingga sertifikat yang ditandatangani sendiri.

Karena sertifikat ditandatangani sendiri dan harus diterima oleh pengguna secara manual, tidak masuk akal untuk menggunakan kedaluwarsa singkat atau crypto yang lemah.

Di masa depan, Anda mungkin ingin menggunakan lebih dari 4096 bit untuk kunci RSA dan algoritma hash yang lebih kuat dari sha256, tetapi pada 2018 ini adalah nilai-nilai waras. Mereka cukup kuat saat didukung oleh semua browser modern.

Catatan sampingan: Secara teoritis Anda bisa meninggalkan -nodes parameter (yang berarti "tidak enkripsi DES"), dalam hal ini example.key akan dienkripsi dengan kata sandi. Namun, ini hampir tidak pernah berguna untuk instalasi server, karena Anda harus menyimpan kata sandi di server juga, atau Anda harus memasukkannya secara manual pada setiap reboot.


105
2017-12-28 17:30



Saya akan merekomendasikan untuk menambahkan -sha256 parameter, untuk menggunakan SHA-2 algoritma hash, karena browser utama sedang mempertimbangkan untuk menunjukkan "SHA-1 sertifikat" sebagai tidak aman.

Baris perintah yang sama dari jawaban yang diterima - @diegows dengan menambahkan -sha256

openssl req -x509 -sha256 -newkey rsa: 2048 -keluar kunci.pem -out cert.pem-hari XXX

Info selengkapnya di Blog Google Security.

Perbarui Mei 2018. Seperti yang banyak dicatat dalam komentar bahwa menggunakan SHA-2 tidak menambahkan keamanan apa pun ke sertifikat yang ditandatangani sendiri. Tetapi saya tetap menyarankan untuk menggunakannya sebagai kebiasaan yang baik untuk tidak menggunakan fungsi hash kriptografi yang usang / tidak aman. Penjelasan lengkap tersedia di: https://security.stackexchange.com/questions/91913/why-is-it-fine-for-certificates-above-the-end-entity-certificate-to-be-sha1-base


63
2017-10-20 09:52



Peramban modern kini memberikan kesalahan keamanan untuk sertifikat yang ditandatangani sendiri jika tidak ada SAN (Nama Alternatif Subjek). OpenSSL tidak menyediakan cara baris perintah untuk menentukan ini, begitu banyak tutorial dan bookmark pengembang tiba-tiba kedaluwarsa.

Cara tercepat untuk menjalankannya lagi adalah file conf yang pendek dan berdiri sendiri:

  1. Buat file konfigurasi OpenSSL (contoh: req.cnf)

    [req]
    distinguished_name = req_distinguished_name
    x509_extensions = v3_req
    prompt = no
    [req_distinguished_name]
    C = US
    ST = VA
    L = SomeCity
    O = MyCompany
    OU = MyDivision
    CN = www.company.com
    [v3_req]
    keyUsage = critical, digitalSignature, keyAgreement
    extendedKeyUsage = serverAuth
    subjectAltName = @alt_names
    [alt_names]
    DNS.1 = www.company.com
    DNS.2 = company.com
    DNS.3 = company.net
    
  2. Buat sertifikat yang merujuk file konfigurasi ini

    openssl req -x509 -nodes -days 730 -newkey rsa:2048 \
     -keyout cert.key -out cert.pem -config req.cnf -sha256
    

Contoh konfigurasi dari https://support.citrix.com/article/CTX135602


53
2018-05-09 02:37



Ini adalah skrip yang saya gunakan pada kotak lokal untuk mengatur SAN (subjectAltName) dalam sertifikat yang ditandatangani sendiri.

Skrip ini mengambil nama domain (example.com) dan menghasilkan SAN untuk * .example.com dan example.com dalam sertifikat yang sama. Bagian di bawah ini dikomentari. Beri nama skrip (mis. generate-ssl.sh) dan memberikan izin yang dapat dieksekusi. File-file akan ditulis ke direktori yang sama dengan skrip.

Chrome 58 dan seterusnya memerlukan SAN untuk diatur dalam sertifikat yang ditandatangani sendiri.

#!/usr/bin/env bash

# Set the TLD domain we want to use
BASE_DOMAIN="example.com"

# Days for the cert to live
DAYS=1095

# A blank passphrase
PASSPHRASE=""

# Generated configuration file
CONFIG_FILE="config.txt"

cat > $CONFIG_FILE <<-EOF
[req]
default_bits = 2048
prompt = no
default_md = sha256
x509_extensions = v3_req
distinguished_name = dn

[dn]
C = CA
ST = BC
L = Vancouver
O = Example Corp
OU = Testing Domain
emailAddress = webmaster@$BASE_DOMAIN
CN = $BASE_DOMAIN

[v3_req]
subjectAltName = @alt_names

[alt_names]
DNS.1 = *.$BASE_DOMAIN
DNS.2 = $BASE_DOMAIN
EOF

# The file name can be anything
FILE_NAME="$BASE_DOMAIN"

# Remove previous keys
echo "Removing existing certs like $FILE_NAME.*"
chmod 770 $FILE_NAME.*
rm $FILE_NAME.*

echo "Generating certs for $BASE_DOMAIN"

# Generate our Private Key, CSR and Certificate
# Use SHA-2 as SHA-1 is unsupported from Jan 1, 2017

openssl req -new -x509 -newkey rsa:2048 -sha256 -nodes -keyout "$FILE_NAME.key" -days $DAYS -out "$FILE_NAME.crt" -passin pass:$PASSPHRASE -config "$CONFIG_FILE"

# OPTIONAL - write an info to see the details of the generated crt
openssl x509 -noout -fingerprint -text < "$FILE_NAME.crt" > "$FILE_NAME.info"

# Protect the key
chmod 400 "$FILE_NAME.key"

Skrip ini juga menulis file info sehingga Anda dapat memeriksa sertifikat baru dan memverifikasi SAN diatur dengan benar.

                ...
                28:dd:b8:1e:34:b5:b1:44:1a:60:6d:e3:3c:5a:c4:
                da:3d
            Exponent: 65537 (0x10001)
    X509v3 extensions:
        X509v3 Subject Alternative Name: 
            DNS:*.example.com, DNS:example.com
Signature Algorithm: sha256WithRSAEncryption
     3b:35:5a:d6:9e:92:4f:fc:f4:f4:87:78:cd:c7:8d:cd:8c:cc:
     ...

Jika Anda menggunakan Apache, maka Anda dapat mereferensikan sertifikat di atas dalam file konfigurasi Anda seperti:

<VirtualHost _default_:443>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/htdocs

    SSLEngine on
    SSLCertificateFile path/to/your/example.com.crt
    SSLCertificateKeyFile path/to/your/example.com.key
</VirtualHost>

Ingatlah untuk me-restart server Apache (atau Nginx, atau IIS) Anda agar sertifikat baru berlaku.


11
2018-05-13 20:21