ฉันพลาดอะไรไปรึเปล่า? นี่เป็นวิธีที่ถูกต้องในการสร้างใบรับรองที่ลงชื่อด้วยตนเองหรือไม่
ง่ายในการสร้างใบรับรองที่ลงชื่อด้วยตัวเอง คุณเพียงแค่ใช้openssl req
คำสั่ง มันอาจเป็นเรื่องยากที่จะสร้างสิ่งที่ลูกค้าสามารถเลือกได้มากที่สุดเช่นเบราว์เซอร์และเครื่องมือบรรทัดคำสั่ง
มันเป็นเรื่องยากเพราะเบราว์เซอร์ที่มีชุดของตัวเองของความต้องการและพวกเขามีข้อ จำกัด มากขึ้นกว่าIETF ข้อกำหนดที่ใช้โดยเบราว์เซอร์มีการบันทึกไว้ที่CA / Browser Forums (ดูข้อมูลอ้างอิงด้านล่าง) ข้อ จำกัด เกิดขึ้นในสองประเด็นสำคัญ: (1) แองเคอร์ที่เชื่อถือได้และ (2) ชื่อ DNS
เบราว์เซอร์สมัยใหม่ (เช่น warez ที่เราใช้ใน 2014/2015) ต้องการใบรับรองที่โยงกลับไปยังจุดยึดที่เชื่อถือได้และพวกเขาต้องการให้ชื่อ DNS ถูกนำเสนอในรูปแบบเฉพาะในใบรับรอง และเบราว์เซอร์กำลังเคลื่อนไหวต่อต้านใบรับรองเซิร์ฟเวอร์ที่ลงชื่อด้วยตนเอง
เบราว์เซอร์บางตัวไม่สามารถนำเข้าใบรับรองเซิร์ฟเวอร์ที่ลงนามด้วยตนเองได้อย่างง่ายดาย ที่จริงแล้วคุณไม่สามารถใช้เบราว์เซอร์บางตัวได้เช่นเบราว์เซอร์ของ Android ดังนั้นทางออกที่สมบูรณ์คือการเป็นผู้มีอำนาจของคุณเอง
ในกรณีที่ไม่มีอำนาจของคุณเองคุณจะต้องได้รับชื่อ DNS ที่ถูกต้องเพื่อให้ใบรับรองมีโอกาสประสบความสำเร็จสูงสุด แต่ฉันขอแนะนำให้คุณเป็นผู้มีอำนาจของคุณเอง มันง่ายที่จะกลายเป็นผู้มีอำนาจของคุณเองและมันจะก้าวเท้าเลี่ยงปัญหาความไว้วางใจทั้งหมด
นี่อาจจะไม่ใช่เว็บไซต์ที่คุณกำลังมองหา!
ใบรับรองความปลอดภัยของเว็บไซต์ไม่น่าเชื่อถือ!
นี่เป็นเพราะเบราว์เซอร์ใช้รายการจุดยึดความน่าเชื่อถือที่กำหนดไว้ล่วงหน้าเพื่อตรวจสอบใบรับรองเซิร์ฟเวอร์ ใบรับรองที่ลงนามเองไม่โยงกลับไปยังจุดยึดที่เชื่อถือได้
วิธีที่ดีที่สุดในการหลีกเลี่ยงปัญหานี้คือ:
- สร้างสิทธิ์ของคุณเอง (เช่นกลายเป็นCA )
- สร้างคำขอลงนามใบรับรอง (CSR) สำหรับเซิร์ฟเวอร์
- ลงชื่อ CSR ของเซิร์ฟเวอร์ด้วยคีย์ CA ของคุณ
- ติดตั้งใบรับรองเซิร์ฟเวอร์บนเซิร์ฟเวอร์
- ติดตั้งใบรับรอง CA บนไคลเอนต์
ขั้นตอนที่ 1 - สร้างสิทธิ์ของคุณเองเพียงแค่หมายถึงการสร้างใบรับรองที่ลงชื่อด้วยตัวเองด้วยCA: true
และการใช้คีย์ที่เหมาะสม นั่นหมายความว่าหัวเรื่องและผู้ออกเป็นนิติบุคคลเดียวกัน CA ถูกตั้งค่าเป็นจริงในข้อ จำกัด พื้นฐาน (ควรถูกทำเครื่องหมายว่าสำคัญ), การใช้คีย์คือkeyCertSign
และcrlSign
(ถ้าคุณใช้ CRL), และSubject Key Identifier (SKI) คือ เช่นเดียวกับAuthority Key Identifier (AKI)
หากต้องการเป็นผู้ออกใบรับรองของคุณเองโปรดดู * คุณจะลงนามในคำขอลงนามใบรับรองกับผู้ออกใบรับรองของคุณได้อย่างไร บน Stack Overflow จากนั้นนำเข้า CA ของคุณไปยัง Trust Store ที่ใช้โดยเบราว์เซอร์
ขั้นตอนที่ 2-4 ประมาณสิ่งที่คุณทำในขณะนี้สำหรับประชาชนหันหน้าไปทางเซิร์ฟเวอร์เมื่อคุณเกณฑ์บริการของแคลิฟอร์เนียเช่นStartcomหรือCAcert ขั้นตอนที่ 1 และ 5 อนุญาตให้คุณหลีกเลี่ยงสิทธิ์บุคคลที่สามและทำหน้าที่เป็นสิทธิ์ของคุณเอง (ใครจะไว้ใจได้ดีกว่าตัวคุณเอง)
วิธีที่ดีที่สุดถัดไปเพื่อหลีกเลี่ยงคำเตือนเบราว์เซอร์คือการเชื่อถือใบรับรองของเซิร์ฟเวอร์ แต่เบราว์เซอร์บางตัวเช่นเบราว์เซอร์เริ่มต้นของ Android ไม่อนุญาตให้คุณทำ ดังนั้นมันจะไม่ทำงานบนแพลตฟอร์ม
ปัญหาของเบราว์เซอร์ (และตัวแทนผู้ใช้ที่คล้ายกันอื่น ๆ ) ที่ไม่เชื่อถือใบรับรองที่ลงนามด้วยตนเองจะเป็นปัญหาใหญ่ใน Internet of Things (IoT) ตัวอย่างเช่นจะเกิดอะไรขึ้นเมื่อคุณเชื่อมต่อกับเทอร์โมสแตทหรือตู้เย็นเพื่อตั้งโปรแกรม คำตอบคือไม่มีอะไรดีเท่าประสบการณ์ของผู้ใช้ที่เกี่ยวข้อง
WebAppSec Working Group ของ W3C เริ่มมองปัญหาแล้ว ดูตัวอย่างเช่นข้อเสนอ: การทำเครื่องหมายในฐานะที่เป็น HTTP ที่ไม่ปลอดภัย
วิธีสร้างใบรับรองที่ลงนามเองด้วย OpenSSL
คำสั่งด้านล่างและไฟล์กำหนดค่าสร้างใบรับรองแบบลงนามด้วยตนเอง (นอกจากนี้ยังแสดงวิธีสร้างคำขอเซ็นชื่อด้วย) พวกเขาแตกต่างจากคำตอบอื่น ๆ ในแง่หนึ่ง: ชื่อ DNS ที่ใช้สำหรับใบรับรอง self ลงนามอยู่ในชื่อเรื่องสำรองข้อมูล (SAN)และไม่ได้เป็นชื่อสามัญ (CN)
ชื่อ DNS จะถูกวางไว้ใน SAN ผ่านไฟล์การกำหนดค่าที่มีบรรทัดsubjectAltName = @alternate_names
(ไม่มีวิธีที่จะทำผ่านบรรทัดคำสั่ง) จากนั้นมีalternate_names
ส่วนหนึ่งในไฟล์กำหนดค่า (คุณควรปรับให้เหมาะกับรสนิยมของคุณ):
[ 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
สิ่งสำคัญคือต้องใส่ชื่อ DNS ใน SAN ไม่ใช่ CN เพราะทั้ง IETF และ CA / เบราว์เซอร์ฟอรัมจะระบุวิธีปฏิบัติ พวกเขายังระบุว่าชื่อ DNS ใน CN นั้นเลิกใช้แล้ว (แต่ไม่ห้าม) หากคุณใส่ชื่อ DNS ใน CN จะต้องรวมอยู่ใน SAN ภายใต้นโยบาย CA / B ดังนั้นคุณไม่สามารถหลีกเลี่ยงการใช้ชื่อสำรองของหัวเรื่องได้
หากคุณไม่ใส่ชื่อ DNS ใน SAN ใบรับรองจะไม่ผ่านการตรวจสอบภายใต้เบราว์เซอร์และตัวแทนผู้ใช้อื่น ๆ ซึ่งเป็นไปตามแนวทาง CA / เบราว์เซอร์ฟอรัม
ที่เกี่ยวข้อง: เบราว์เซอร์ปฏิบัติตามนโยบาย CA / เบราว์เซอร์ฟอรัม ไม่ใช่นโยบายของ IETF นี่คือหนึ่งในเหตุผลที่ใบรับรองที่สร้างด้วย OpenSSL (ซึ่งตามหลัง IETF) บางครั้งไม่ได้ตรวจสอบภายใต้เบราว์เซอร์ (เบราว์เซอร์เป็นไปตาม CA / B) พวกเขาเป็นมาตรฐานที่แตกต่างกันพวกเขามีนโยบายการออกที่แตกต่างกันและข้อกำหนดการตรวจสอบที่แตกต่างกัน
สร้างใบรับรองที่ลงชื่อด้วยตนเอง (สังเกตเห็นการเพิ่ม-x509
ตัวเลือก):
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
สร้างคำขอเซ็น (สังเกตเห็นว่าไม่มี-x509
ตัวเลือก):
openssl req -config example-com.conf -new -sha256 -newkey rsa:2048 -nodes \
-keyout example-com.key.pem -days 365 -out example-com.req.pem
พิมพ์ใบรับรองที่ลงนามเอง :
openssl x509 -in example-com.cert.pem -text -noout
พิมพ์คำขอลงนาม :
openssl req -in example-com.req.pem -text -noout
ไฟล์การกำหนดค่า (ผ่าน-config
ตัวเลือก)
[ 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
คุณอาจต้องทำสิ่งต่อไปนี้สำหรับ Chrome มิฉะนั้นChrome อาจบ่นชื่อสามัญไม่ถูกต้อง (ERR_CERT_COMMON_NAME_INVALID
) ฉันไม่แน่ใจว่าความสัมพันธ์ระหว่างที่อยู่ IP ใน SAN และ CN ในกรณีนี้คืออะไร
# IPv4 localhost
# IP.1 = 127.0.0.1
# IPv6 localhost
# IP.2 = ::1
มีกฎอื่น ๆ ที่เกี่ยวข้องกับการจัดการชื่อ DNS ในใบรับรอง X.509 / PKIX อ้างถึงเอกสารเหล่านี้สำหรับกฎ:
RFC 6797 และ RFC 7469 อยู่ในรายการเนื่องจากมีข้อ จำกัด มากกว่าเอกสาร RFC และ CA / B อื่น ๆ RFCs 6797 และ 7469 ไม่อนุญาตให้ใช้ที่อยู่ IP เช่นกัน