Hoe genereer ik een zelfondertekend SSL-certificaat met OpenSSL?

Ik voeg HTTPS-ondersteuning toe aan een ingebouwd Linux-apparaat. Ik heb geprobeerd een zelfondertekend certificaat te genereren met deze stappen:

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

Dit werkt, maar ik krijg enkele fouten met bijvoorbeeld Google Chrome:

Dit is waarschijnlijk niet de site die u zoekt!
Het beveiligingscertificaat van de site wordt niet vertrouwd!

Mis ik iets? Is dit de juiste manier om een zelfondertekend certificaat te maken?


Antwoord 1, autoriteit 100%

Je kunt dat in één opdracht doen:

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

Je kunt ook -nodes(afkorting van no DES) toevoegen als je je privésleutel niet wilt beschermen met een wachtwoordzin. Anders wordt u om een wachtwoord van “minstens 4 tekens” gevraagd.

De parameter days(365) kunt u vervangen door een willekeurig getal om de vervaldatum te beïnvloeden. Het zal u dan vragen om zaken als “Landnaam”, maar u kunt gewoon op Enterdrukken en de standaardinstellingen accepteren.

Voeg -subj '/CN=localhost'toe om vragen over de inhoud van het certificaat te onderdrukken (vervang localhostdoor uw gewenste domein).

Zelfondertekende certificaten worden niet gevalideerd door derden, tenzij u ze eerder in de browsers importeert. Als u meer beveiliging nodig heeft, moet u een certificaat gebruiken dat is ondertekend door een certificaatautoriteit(CA).


Antwoord 2, autoriteit 24%

Mis ik iets? Is dit de juiste manier om een zelfondertekend certificaat te maken?

Het is eenvoudig om een zelfondertekend certificaat te maken. Je gebruikt gewoon de opdracht openssl req. Het kan lastig zijn om er een te maken die kan worden gebruikt door de grootste selectie clients, zoals browsers en opdrachtregelprogramma’s.

Het is moeilijk omdat de browsers hun eigen set vereisten hebben, en ze zijn strenger dan de IETF. De vereisten die door browsers worden gebruikt, zijn gedocumenteerd op de CA/Browser Forums(zie referenties hieronder). De beperkingen doen zich voor op twee belangrijke gebieden: (1) vertrouwensankers en (2) DNS-namen.

Moderne browsers (zoals de warez die we in 2014/2015 gebruiken) willen een certificaat dat teruggaat naar een trust anchor, en ze willen dat DNS-namen op bepaalde manieren in het certificaat worden weergegeven. En browsers bewegen zich actief tegen zelfondertekende servercertificaten.

Sommige browsers maken het niet echt gemakkelijk om een zelfondertekend servercertificaat te importeren. In feite kan dat niet met sommige browsers, zoals de browser van Android. Dus de complete oplossing is om je eigen autoriteit te worden.

Als je geen eigen autoriteit wordt, moet je de DNS-namen goed hebben om het certificaat de grootste kans op succes te geven. Maar ik zou je willen aanmoedigen om je eigen autoriteit te worden. Het is gemakkelijk om je eigen autoriteit te worden en het zal alle vertrouwensproblemen omzeilen (wie kan je beter vertrouwen dan jezelf?).


Dit is waarschijnlijk niet de site die u zoekt!
Het beveiligingscertificaat van de site wordt niet vertrouwd!

Dit komt omdat browsers een vooraf gedefinieerde lijst met vertrouwensankers gebruiken om servercertificaten te valideren. Een zelfondertekend certificaat is niet gekoppeld aan een vertrouwd anker.

De beste manier om dit te vermijden is:

  1. Creëer je eigen autoriteit (d.w.z. word een CA)
  2. Maak een certificaatondertekeningsverzoek (CSR) voor de server
  3. Onderteken de CSR van de server met uw CA-sleutel
  4. Installeer het servercertificaat op de server
  5. Installeer het CA-certificaat op de client

Stap 1 – Maak uw eigen autoriteitbetekent gewoon een zelfondertekend certificaat maken met CA: trueen correct sleutelgebruik. Dat betekent dat het Subjecten Issuerdezelfde entiteit zijn, CA is ingesteld op true in Basic Constraints(het moet ook als kritiek worden gemarkeerd), sleutelgebruik is keyCertSignen crlSign(als u CRL’s gebruikt), en de Subject Key Identifier(SKI) is hetzelfde als de Autoriteitssleutel-ID(AKI).

Als u uw eigen certificeringsinstantie wilt worden, raadpleegt u *Hoe onderteken je een certificaatondertekeningsverzoek bij je certificeringsinstantie?op Stack Overflow. Importeer vervolgens uw CA in de Trust Store die door de browser wordt gebruikt.

Stappen 2 – 4 zijn ongeveer wat u nu doet voor een openbare server wanneer u een beroep doet op de diensten van een CA zoals Startcom of CAcert. Met stap 1 en 5 kunt u de autoriteit van derden vermijden en als uw eigen autoriteit optreden (wie kunt u beter vertrouwen dan uzelf?).

De beste manier om de browserwaarschuwing te vermijden, is door het servercertificaat te vertrouwen. Maar sommige browsers, zoals de standaardbrowser van Android, laten u dit niet toe. Het zal dus nooit werken op het platform.

Het probleem van browsers (en andere soortgelijke user agents) die zelfondertekende certificaten nietvertrouwen, wordt een groot probleem in het Internet of Things (IoT). Wat gebeurt er bijvoorbeeld als je verbinding maakt met je thermostaat of koelkast om deze te programmeren? Het antwoord is: niets goeds wat de gebruikerservaring betreft.

De WebAppSec-werkgroep van het W3C begint het probleem te bekijken. Zie bijvoorbeeld Voorstel: HTTP markeren als niet-beveiligd.


Een zelfondertekend certificaat maken met OpenSSL

Met de onderstaande opdrachten en het configuratiebestand wordt een zelfondertekend certificaat gemaakt (het laat ook zien hoe u een ondertekeningsverzoek maakt). Ze verschillen in één opzicht van andere antwoorden: de DNS-namen die worden gebruikt voor het zelfondertekende certificaat staan in de Subject Alternate Name (SAN), en niet in de Common Name (CN).

De DNS-namen worden in het SAN geplaatst via het configuratiebestand met de regel subjectAltName = @alternate_names(het is niet mogelijk om dit via de opdrachtregel te doen). Dan is er een sectie alternate_namesin het configuratiebestand (u moet dit afstemmen op uw smaak):

[ 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

Het is belangrijk om de DNS-naam in het SAN te zetten en niet in de CN, omdat zowelde IETF als de CA/Browser Forums de praktijk specificeren. Ze specificeren ook dat DNS-namen in de CN verouderd zijn (maar niet verboden). Alsu een DNS-naam in de CN plaatst, dan moetdeze worden opgenomen in het SAN volgens het CA/B-beleid. U kunt dus niet vermijden om de alternatieve naam voor het onderwerp te gebruiken.

Als u geen DNS-namen in het SAN plaatst, kan het certificaat niet worden gevalideerd onder een browser en andere user agents die de CA/Browser Forum-richtlijnen volgen.

Gerelateerd: browsers volgen het CA/Browser Forum-beleid; en niet het IETF-beleid. Dat is een van de redenen waarom een certificaat gemaakt met OpenSSL (dat over het algemeen de IETF volgt) soms niet valideert onder een browser (browsers volgen de CA/B). Het zijn verschillende normen, ze hebben een ander uitgiftebeleid en verschillende validatievereisten.


Maak een zelfondertekend certificaat(let op de toevoeging van de optie -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

Maak een ondertekeningsverzoek(let op het ontbreken van de optie -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

Druk een zelfondertekend certificaat af:

openssl x509 -in example-com.cert.pem -text -noout

Druk een ondertekeningsverzoek af:

openssl req -in example-com.req.pem -text -noout

Configuratiebestand (doorgegeven via -configoptie)

[ 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        = [email protected]
# 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

Mogelijk moet u het volgende doen voor Chrome. Anders Chrome kan een klacht indienen bij Algemene naamis ongeldig (ERR_CERT_COMMON_NAME_INVALID). Ik weet niet zeker wat de relatie is tussen een IP-adres in het SAN en een CN in dit geval.

# IPv4 localhost
# IP.1       = 127.0.0.1
# IPv6 localhost
# IP.2     = ::1

Er zijn andere regels met betrekking tot de verwerking van DNS-namen in X.509/PKIX-certificaten. Raadpleeg deze documenten voor de regels:

RFC 6797 en RFC 7469 worden vermeld, omdat ze restrictiever zijn dan de andere RFC’s en CA/B-documenten. RFC’s 6797 en 7469 laten ook geeneen IP-adres toe.


Antwoord 3, autoriteit 18%

Vanaf 2021 met OpenSSL ≥ 1.1.1, voorziet de volgende opdracht in al uw behoeften, inclusief SAN:

openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes \
  -keyout example.key -out example.crt -subj "/CN=example.com" \
  -addext "subjectAltName=DNS:example.com,DNS:www.example.net,IP:10.0.0.1"

Op oude systemen met OpenSSL ≤ 1.1.0, zoals Debian ≤ 9 of CentOS ≤ 7, moet een langere versie van dit commando worden gebruikt:

openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes \
  -keyout example.key -out example.crt -extensions san -config \
  <(echo "[req]"; 
    echo distinguished_name=req; 
    echo "[san]"; 
    echo subjectAltName=DNS:example.com,DNS:www.example.net,IP:10.0.0.1
    ) \
  -subj "/CN=example.com"

Beide opdrachten maken een certificaat aan dat

  • geldig voor de (sub)domeinen example.comen www.example.net(SAN),
  • ook geldig voor het IP-adres 10.0.0.1(SAN),
  • relatief sterk (vanaf 2021) en
  • geldig voor 3650dagen (~10 jaar).

De volgende bestanden worden gegenereerd:

  • Privésleutel: example.key
  • Certificaat: example.crt

Alle informatie wordt verstrekt op de opdrachtregel. Er is geen interactieve inputwaar je je aan ergert. Er zijn geen configuratiebestandenwaar je mee moet rommelen. Alle noodzakelijke stappen worden uitgevoerd door een enkele OpenSSL-aanroep: van het genereren van een persoonlijke sleutel tot het zelfondertekende certificaat.

Opmerking #1: Crypto-parameters

Aangezien het certificaat zelfondertekend is en handmatig door gebruikers moet worden geaccepteerd, heeft het geen zin om een korte vervaldatum of zwakke cryptografie te gebruiken.

In de toekomst wil je misschien meer dan 4096bits gebruiken voor de RSA-sleutel en een hash-algoritme dat sterker is dan sha256, maar vanaf 2021 zijn dit normale waarden . Ze zijn voldoende sterk en worden door alle moderne browsers ondersteund.

Opmerking #2: Parameter “-nodes

Theoretisch zou je de parameter -nodes(wat betekent “geen DES-codering”) weglaten, in welk geval example.keyzou worden versleuteld met een wachtwoord. Dit is echter bijna nooit handig voor een serverinstallatie, omdat u ofwel het wachtwoord ook op de server moet opslaan, of dat u het bij elke herstart handmatig moet invoeren.

Opmerking #3: Zie ook


Antwoord 4, autoriteit 17%

Hier zijn de opties beschreven in het antwoord van @diegows, in meer detail beschreven, van de documentatie:

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

PKCS#10 certificaatverzoek en hulpprogramma voor het genereren van certificaten.

-x509

deze optie voert een zelfondertekend certificaat uit in plaats van een certificaatverzoek.
Dit wordt meestal gebruikt om een testcertificaat of een zelfondertekende root-CA te genereren.

-newkey arg

met deze optie wordt een nieuw certificaatverzoek en een nieuwe persoonlijke sleutel gemaakt. het argument
neemt een van de verschillende vormen aan. rsa:nbits, waarbij nbitshet aantal bits is,
genereert een RSA-sleutel nbitsin grootte.

-keyout filename

dit geeft de bestandsnaam waarnaar de nieuw aangemaakte privésleutel moet worden geschreven.

-out filename

Dit specificeert de naam van het uitvoerbestand waarnaar standaard moet worden geschreven.

-days n

wanneer de optie -x509wordt gebruikt, specificeert dit het aantal dagen om te certificeren
het certificaat voor. De standaard is 30 dagen.

-nodes

als deze optie is opgegeven, wordt deze niet versleuteld als er een privésleutel wordt gemaakt.

De documentatie is eigenlijk gedetailleerder dan het bovenstaande; Ik heb het hier even samengevat.


Antwoord 5, autoriteit 6%

Ik kan geen commentaar geven, dus ik zal dit als een apart antwoord plaatsen. Ik heb een paar problemen gevonden met het geaccepteerde one-liner-antwoord:

  • De oneliner bevat een wachtwoordzin in de sleutel.
  • De one-liner gebruikt SHA-1 die in veel browsers waarschuwingen in de console gooit.

Hier is een vereenvoudigde versie die de wachtwoordzin verwijdert, de beveiliging verhoogt om waarschuwingen te onderdrukken en een suggestie in opmerkingen bevat om door te geven in -subj om de volledige vragenlijst te verwijderen:

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

Vervang ‘localhost’ door het domein dat je nodig hebt. U moet de eerste twee opdrachten één voor één uitvoeren omdat OpenSSL om een wachtwoordzin vraagt.

Om de twee te combineren in een .pem-bestand:

cat server.crt server.key > cert.pem

Antwoord 6, autoriteit 3%

Moderne browsers geven nu een beveiligingsfout voor anders goed gevormde, zelfondertekende certificaten als ze een SAN (Subject Alternate Name) missen. OpenSSL biedt geen opdrachtregelmethode om dit te specificeren, dus veel tutorials en bladwijzers voor ontwikkelaars zijn plotseling verouderd.

De snelste manier om weer aan de slag te gaan is een kort, op zichzelf staand configuratiebestand:

  1. Maak een OpenSSL-configuratiebestand (voorbeeld: 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. Maak het certificaat dat verwijst naar dit configuratiebestand

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

Voorbeeldconfiguratie van https://support.citrix.com/article/CTX135602


Antwoord 7, autoriteit 3%

Ik zou aanraden om de parameter -sha256toe te voegen om het SHA-2 hash-algoritme te gebruiken, omdat grote browsers overwegen om “SHA-1-certificaten” als onveilig weer te geven.

Dezelfde opdrachtregel van het geaccepteerde antwoord – @diegows met toegevoegde -sha256

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

Meer informatie in Google-beveiligingsblog.

Update mei 2018.Zoals velen in de opmerkingen hebben opgemerkt, voegt het gebruik van SHA-2 geen enkele beveiliging toe aan een zelfondertekend certificaat. Maar ik raad het nog steeds aan om het te gebruiken als een goede gewoonte om geen verouderde / onveilige cryptografische hash-functies te gebruiken. Volledige uitleg is beschikbaar in Waarom is het prima dat certificaten boven het eindentiteitscertificaat op SHA-1 zijn gebaseerd?.


Antwoord 8

Dit is het script dat ik op lokale dozen gebruik om het SAN (subjectAltName) in zelfondertekende certificaten in te stellen.

Dit script neemt de domeinnaam (example.com) en genereert het SAN voor *.example.com en example.com in hetzelfde certificaat. De onderstaande secties zijn becommentarieerd. Geef het script een naam (bijv. generate-ssl.sh) en geef het uitvoerbare machtigingen. De bestanden worden naar dezelfde map geschreven als het script.

Chrome 58 en hoger vereist dat SAN wordt ingesteld in zelfondertekende certificaten.

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

Dit script schrijft ook een informatiebestand, zodat u het nieuwe certificaat kunt inspecteren en kunt controleren of het SAN correct is ingesteld.

               ...
                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:
     ...

Als u Apache gebruikt, kunt u als volgt verwijzen naar het bovenstaande certificaat in uw configuratiebestand:

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

Vergeet niet om uw Apache- (of Nginx- of IIS)-server opnieuw te starten om het nieuwe certificaat van kracht te laten worden.


Antwoord 9

Ik kan geen commentaar geven, dus voeg ik een apart antwoord toe.
Ik probeerde een zelfondertekend certificaat voor NGINX te maken en dat was eenvoudig, maar toen ik het aan de witte lijst van Chrome wilde toevoegen, had ik een probleem. En mijn oplossing was om een rootcertificaat te maken en daarmee een onderliggend certificaat te ondertekenen.

Dus stap voor stap.
Maak bestand config_ssl_ca.cnf
Merk op dat het configuratiebestand een optie basicConstraints=CA:trueheeft, wat betekent dat dit certificaat root moet zijn.

Dit is een goede gewoonte, omdat je het één keer maakt en opnieuw kunt gebruiken.

[ req ]
default_bits = 2048
prompt = no
distinguished_name=req_distinguished_name
req_extensions = v3_req
[ req_distinguished_name ]
countryName=UA
stateOrProvinceName=root region
localityName=root city
organizationName=Market(localhost)
organizationalUnitName=roote department
commonName=market.localhost
[email protected]
[ alternate_names ]
DNS.1        = market.localhost
DNS.2        = www.market.localhost
DNS.3        = mail.market.localhost
DNS.4        = ftp.market.localhost
DNS.5        = *.market.localhost
[ v3_req ]
keyUsage=digitalSignature
basicConstraints=CA:true
subjectKeyIdentifier = hash
subjectAltName = @alternate_names

Het volgende configuratiebestand voor uw onderliggende certificaat is config_ssl.cnf.

[ req ]
default_bits = 2048
prompt = no
distinguished_name=req_distinguished_name
req_extensions = v3_req
[ req_distinguished_name ]
countryName=UA
stateOrProvinceName=Kyiv region
localityName=Kyiv
organizationName=market place
organizationalUnitName=market place department
commonName=market.localhost
[email protected]
[ alternate_names ]
DNS.1        = market.localhost
DNS.2        = www.market.localhost
DNS.3        = mail.market.localhost
DNS.4        = ftp.market.localhost
DNS.5        = *.market.localhost
[ v3_req ]
keyUsage=digitalSignature
basicConstraints=CA:false
subjectAltName = @alternate_names
subjectKeyIdentifier = hash

De eerste stap – root-sleutel en certificaat maken

openssl genrsa -out ca.key 2048
openssl req -new -x509 -key ca.key -out ca.crt -days 365 -config config_ssl_ca.cnf

De tweede stap maakt een onderliggende sleutel en bestand CSR – Certificaatondertekeningsverzoek. Omdat het de bedoeling is om het onderliggende certificaat door root te ondertekenen en een correct certificaat te krijgen

openssl genrsa -out market.key 2048
openssl req -new -sha256 -key market.key -config config_ssl.cnf -out market.csr

Open Linux-terminal en voer deze opdracht uit

echo 00 > ca.srl
touch index.txt

Het ca.srltekstbestand met het volgende serienummer dat in hex moet worden gebruikt.
Verplicht. Dit bestand moet aanwezig zijn en een geldig serienummer bevatten.

Laatste stap, maak nog een configuratiebestand en noem het config_ca.cnf

# we use 'ca' as the default section because we're usign the ca command
[ ca ]
default_ca = my_ca
[ my_ca ]
#  a text file containing the next serial number to use in hex. Mandatory.
#  This file must be present and contain a valid serial number.
serial = ./ca.srl
# the text database file to use. Mandatory. This file must be present though
# initially it will be empty.
database = ./index.txt
# specifies the directory where new certificates will be placed. Mandatory.
new_certs_dir = ./
# the file containing the CA certificate. Mandatory
certificate = ./ca.crt
# the file contaning the CA private key. Mandatory
private_key = ./ca.key
# the message digest algorithm. Remember to not use MD5
default_md = sha256
# for how many days will the signed certificate be valid
default_days = 365
# a section with a set of variables corresponding to DN fields
policy = my_policy
# MOST IMPORTANT PART OF THIS CONFIG
copy_extensions = copy
[ my_policy ]
# if the value is "match" then the field value must match the same field in the
# CA certificate. If the value is "supplied" then it must be present.
# Optional means it may be present. Any fields not mentioned are silently
# deleted.
countryName = match
stateOrProvinceName = supplied
organizationName = supplied
commonName = market.localhost
organizationalUnitName = optional
commonName = supplied

Je vraagt je misschien af, waarom zo moeilijk, waarom we nog een configuratie moeten maken om het onderliggende certificaat door root te ondertekenen. Het antwoord is eenvoudig omdat het onderliggende certificaat een SAN-blok moet hebben – alternatieve namen voor onderwerpen.
Als we het onderliggende certificaat ondertekenen met “openssl x509” utils, verwijdert het basiscertificaat het SAN-veld in het onderliggende certificaat.
We gebruiken dus “openssl ca” in plaats van “openssl x509” om het verwijderen van het SAN-veld te voorkomen. We maken een nieuw configuratiebestand en vertellen het om alle uitgebreide velden copy_extensions = copyte kopiëren.

openssl ca -config config_ca.cnf -out market.crt -in market.csr

Het programma stelt je 2 vragen:

  1. Het certificaat ondertekenen? Zeg “J”
  2. 1 op 1 certificaataanvragen gecertificeerd, commit? Zeg “J”

In terminal zie je een zin met het woord “Database”, het betekent bestand index.txt dat je aanmaakt met het commando “touch”. Het zal alle informatie bevatten van alle certificaten die u aanmaakt door “openssl ca” util.
Om het geldige certificaat te controleren, gebruikt u:

openssl rsa -in market.key -check

Als je wilt zien wat er in CRT zit:

openssl x509 -in market.crt -text -noout

Als je wilt zien wat er in MVO zit:

openssl req -in market.csr -noout -text 

Antwoord 10

One-liner 2017:

openssl req \
-newkey rsa:2048 \
-x509 \
-nodes \
-keyout server.pem \
-new \
-out server.pem \
-subj /CN=localhost \
-reqexts SAN \
-extensions SAN \
-config <(cat /System/Library/OpenSSL/openssl.cnf \
    <(printf '[SAN]\nsubjectAltName=DNS:localhost')) \
-sha256 \
-days 3650

Dit werkt ook in Chrome 57, omdat het het SAN levert, zonder een ander configuratiebestand.
Het is afkomstig uit een antwoord hier.

Hiermee wordt een enkel .pem-bestand gemaakt dat zowel de persoonlijke sleutel als het certificaat bevat. Je kunt ze indien nodig naar aparte .pem-bestanden verplaatsen.


Antwoord 11

One-liner versie 2017:

CentOS:

openssl req -x509 -nodes -sha256 -newkey rsa:2048 \
-keyout localhost.key -out localhost.crt \
-days 3650 \
-subj "CN=localhost" \
-reqexts SAN -extensions SAN \
-config <(cat /etc/pki/tls/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=IP:127.0.0.1,DNS:localhost"))

Ubuntu:

openssl req -x509 -nodes -sha256 -newkey rsa:2048 \
-keyout localhost.key -out localhost.crt \
-days 3650 \
-subj "/CN=localhost" \
-reqexts SAN -extensions SAN \
-config <(cat /etc/ssl/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=IP:127.0.0.1,DNS:localhost"))

Bewerken: voorafgaande Slash toegevoegd aan de optie ‘subj’ voor Ubuntu.


Antwoord 12

Je hebt de algemene procedure correct. De syntaxis voor de opdracht staat hieronder.

openssl req -new -key {private key file} -out {output file}

De waarschuwingen worden echter weergegeven, omdat de browser de identiteit niet kon verifiëren door het certificaat te valideren bij een bekende certificeringsinstantie (CA).

Omdat dit een zelfondertekend certificaat is, is er geen CA en kunt u de waarschuwing veilig negeren en doorgaan. Als u een echt certificaat wilt krijgen dat door iedereen op het openbare internet kan worden herkend, staat de procedure hieronder.

  1. Genereer een privésleutel
  2. Gebruik die privésleutel om een CSR-bestand te maken
  3. CSR indienen bij CA (Verisign of anderen, enz.)
  4. Installeer ontvangen certificaat van CA op webserver
  5. Voeg andere certificaten toe aan de authenticatieketen, afhankelijk van het type cert

Ik heb hier meer informatie over in een bericht op De verbinding beveiligen: een beveiligingscertificaat maken met OpenSSL


Antwoord 13

One-liner FTW. Ik hou het graag simpel. Waarom gebruik je niet één commando dat ALLE benodigde argumenten bevat? Dit is hoe ik het leuk vind – dit creëert een x509-certificaat en zijn PEM-sleutel:

openssl req -x509 \
 -nodes -days 365 -newkey rsa:4096 \
 -keyout self.key.pem \
 -out self-x509.crt \
 -subj "/C=US/ST=WA/L=Seattle/CN=example.com/[email protected]"

Die enkele opdracht bevat alle antwoorden die u normaal gesproken zou geven voor de certificaatgegevens. Op deze manier kun je de parameters instellen en de opdracht uitvoeren, je output krijgen – ga dan voor koffie.

>> Meer hier <<


Antwoord 14

Sleutels genereren

Ik gebruik /etc/mysqlvoor certificaatopslag omdat /etc/apparmor.d/usr.sbin.mysqld/etc/mysql/*.pem r.

sudo su -
cd /etc/mysql
openssl genrsa -out ca-key.pem 2048;
openssl req -new -x509 -nodes -days 1000 -key ca-key.pem -out ca-cert.pem;
openssl req -newkey rsa:2048 -days 1000 -nodes -keyout server-key.pem -out server-req.pem;
openssl x509 -req -in server-req.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem;
openssl req -newkey rsa:2048 -days 1000 -nodes -keyout client-key.pem -out client-req.pem;
openssl x509 -req -in client-req.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem;

Configuratie toevoegen

/etc/mysql/my.cnf

[client]
ssl-ca=/etc/mysql/ca-cert.pem
ssl-cert=/etc/mysql/client-cert.pem
ssl-key=/etc/mysql/client-key.pem
[mysqld]
ssl-ca=/etc/mysql/ca-cert.pem
ssl-cert=/etc/mysql/server-cert.pem
ssl-key=/etc/mysql/server-key.pem

Bij mijn installatie logde de Ubuntu-server in op: /var/log/mysql/error.log

Vervolgnotities:

  • SSL error: Unable to get certificate from '...'

    MySQL kan de leestoegang tot uw certificaatbestand worden geweigerd als dit het geval is niet in apparmors-configuratie. Zoals vermeld in de vorige stappen^, sla al onze certificaten op als .pem-bestanden in de map /etc/mysql/die standaard is goedgekeurd door apparmor (of pas uw apparmor aan /SELinux om toegang te geven tot waar je ze ook hebt opgeslagen.)

  • SSL error: Unable to get private key

    Uw MySQL-serverversie ondersteunt mogelijk niet de standaard rsa:2048-indeling

    Converteer gegenereerde rsa:2048naar gewone rsamet:

    openssl rsa -in server-key.pem -out server-key.pem
    openssl rsa -in client-key.pem -out client-key.pem
    
  • Controleer of lokale server ondersteunt SSL:

    mysql -u root -p
    mysql> show variables like "%ssl%";
    +---------------+----------------------------+
    | Variable_name | Value                      |
    +---------------+----------------------------+
    | have_openssl  | YES                        |
    | have_ssl      | YES                        |
    | ssl_ca        | /etc/mysql/ca-cert.pem     |
    | ssl_capath    |                            |
    | ssl_cert      | /etc/mysql/server-cert.pem |
    | ssl_cipher    |                            |
    | ssl_key       | /etc/mysql/server-key.pem  |
    +---------------+----------------------------+
    
  • Controleren of een verbinding met de database SSL-versleuteld is:

    Verbinding verifiëren

    Als u bent aangemeld bij de MySQL-instantie, kunt u de volgende query uitvoeren:

    show status like 'Ssl_cipher';
    

    Als je verbinding niet versleuteld is, is het resultaat leeg:

    mysql> show status like 'Ssl_cipher';
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | Ssl_cipher    |       |
    +---------------+-------+
    1 row in set (0.00 sec)
    

    Anders zou het een string met een lengte van niet-nul laten zien voor het gebruikte cijfer:

    mysql> show status like 'Ssl_cipher';
    +---------------+--------------------+
    | Variable_name | Value              |
    +---------------+--------------------+
    | Ssl_cipher    | DHE-RSA-AES256-SHA |
    +---------------+--------------------+
    1 row in set (0.00 sec)
    
  • SSL vereisen voor de verbinding van een specifieke gebruiker(‘ssl vereist’):

    • SSL

    Instrueert de server om alleen SSL-gecodeerde verbindingen voor het account toe te staan.

    GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
      REQUIRE SSL;
    

    Om verbinding te maken, moet de client de optie –ssl-ca specificeren om het servercertificaat te verifiëren, en kan daarnaast de opties –ssl-key en –ssl-cert specificeren. Als de optie –ssl-ca noch –ssl-capath is opgegeven, verifieert de client het servercertificaat niet.


Alternatieve link: uitgebreide tutorial in Beveiligde PHP-verbindingen met MySQL met SSL.


Antwoord 15

Zoals in detail is besproken, zelfondertekende certificatenworden niet vertrouwd voor internet. U kunt uw zelfondertekend certificaat aan veel, maar niet aan alle browsers toevoegen. Als alternatief kunt u worden uw eigen certificeringsinstantie.

De belangrijkste reden waarom men geen ondertekend certificaat van een certificeringsinstantie wil krijgen, zijn de kosten — Symantec kosten tussen de $ 995 – $ 1.999 per jaar voor de certificaten – alleen voor een!!!! certificaat bedoeld voor intern netwerk, rekent Symantec $ 399 per jaar. Die kosten zijn gemakkelijk te rechtvaardigen als u creditcardbetalingen verwerkt of werkt voor het winstcentrum van een zeer winstgevend bedrijf. Het is meer dan velen zich kunnen veroorloven voor een persoonlijk project dat men op internet maakt, of voor een non-profitorganisatie met een minimaal budget, of als men in een kostenplaats van een organisatie werkt – kostenplaatsen proberen altijd meer te doen met minder.

Een alternatief is om certbotte gebruiken (zie over certbot). Certbot is een gebruiksvriendelijke automatische client die SSL/TLS-certificaten ophaalt en implementeert voor uw webserver.

Als u certbot instelt, kunt u deze inschakelen om een certificaat voor u te maken en te onderhouden dat is uitgegeven door de Let’s Encryptcertificeringsinstantie.

Ik heb dit dit weekend gedaan voor mijn organisatie. Ik heb de vereiste pakketten voor certbot op mijn server (Ubuntu 16.04) geïnstalleerd en vervolgens de opdracht uitgevoerd die nodig is om certbot in te stellen en in te schakelen. Je hebt waarschijnlijk een DNS-plug-innodig voor certbot – we gebruiken momenteel DigitalOceankan echter binnenkort naar een andere service migreren.

Houd er rekening mee dat sommige instructies niet helemaal juist waren en dat het even puzzelen en tijd kostte met Google om erachter te komen. Dit kostte me de eerste keer behoorlijk wat tijd, maar nu denk ik dat ik het in een paar minuten zou kunnen doen.

Voor DigitalOcean had ik een probleem toen ik werd gevraagd om het pad naar je DigitalOcean-inloggegevens INI-bestand in te voeren. Waar het script naar verwijst is de Applicaties & API-pagina en het tabblad Tokens/Sleutel op die pagina. U moet een persoonlijk toegangstoken (lezen en schrijven) hebben of genereren voor de API van DigitalOcean — dit is een hexadecimale tekenreeks van 65 tekens. Deze string moet dan in een bestand worden geplaatst op de webserver van waaruit je certbot draait. Dat bestand kan een opmerking als eerste regel hebben (opmerkingen beginnen met #). De tweede regel is:

dns_digitalocean_token = 0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff

Toen ik erachter kwam hoe ik een lees- en schrijftoken voor de API van DigitalOcean moest instellen, was het vrij eenvoudig om certbot te gebruiken om een wildcardcertificaat. Merk op dat men geen wildcard-certificaat hoeft in te stellen, maar dat men in plaats daarvan elk domein en subdomein kan specificeren waarop men het certificaat wil toepassen. Het was het wildcard-certificaat waarvoor het INI-bestand met inloggegevens nodig was dat het persoonlijke toegangstoken van DigitalOcean bevatte.

Houd er rekening mee dat openbare-sleutelcertificaten (ook wel identiteitscertificaten of SSL-certificaten genoemd) verlopen en moeten worden vernieuwd. U moet uw certificaat dus periodiek (terugkerend) vernieuwen. De certbot-documentatie behandelt verlengende certificaten.

Mijn plan is om een script te schrijven om het openssl-commando te gebruiken om de vervaldatum van mijn certificaat op te halen en om verlenging te activeren wanneer het 30 dagen of minder duurt voordat het verloopt. Ik zal dan dit script aan cron toevoegen en het eenmaal per dag uitvoeren.

Hier is de opdracht om de vervaldatum van uw certificaat te lezen:

root@prod-host:~# /usr/bin/openssl x509 -enddate -noout -in path-to-certificate-pem-file
notAfter=May 25 19:24:12 2019 GMT

Antwoord 16

opensslmaakt het mogelijk om een zelfondertekend certificaat te genereren met een enkele opdracht (-newkey
geeft opdracht om een persoonlijke sleutel te genereren en -x509geeft opdracht om een zelfondertekende
certificaat in plaats van een ondertekeningsverzoek)::

openssl req -x509 -newkey rsa:4096 \
-keyout my.key -passout pass:123456 -out my.crt \
-days 365 \
-subj /CN=localhost/O=home/C=US/[email protected] \
-addext "subjectAltName = DNS:localhost,DNS:web.internal,email:[email protected]" \
-addext keyUsage=digitalSignature -addext extendedKeyUsage=serverAuth

U kunt in afzonderlijke stappen een persoonlijke sleutel genereren en een zelfondertekenend certificaat maken::

openssl genrsa -out my.key -passout pass:123456 2048
openssl req -x509 \
-key my.key -passin pass:123456 -out my.csr \
-days 3650 \
-subj /CN=localhost/O=home/C=US/[email protected] \
-addext "subjectAltName = DNS:localhost,DNS:web.internal,email:[email protected]" \
-addext keyUsage=digitalSignature -addext extendedKeyUsage=serverAuth

Bekijk het resulterende certificaat::

openssl x509 -text -noout -in my.crt

Java keytoolmaakt PKCS#12-winkel::

keytool -genkeypair -keystore my.p12 -alias master \
-storetype pkcs12 -keyalg RSA -keysize 2048 -validity 3650 \
-storepass 123456 \
-dname "CN=localhost,O=home,C=US" \
-ext 'san=dns:localhost,dns:web.internal,email:[email protected]'

Het zelfondertekende certificaat exporteren::

keytool -exportcert -keystore my.p12 -file my.crt \
-alias master -rfc -storepass 123456

Bekijk het resulterende certificaat::

keytool -printcert -file my.crt

certtoolvan GnuTLS staat het doorgeven van verschillende attributen van CLI niet toe. Ik hou er niet van om met configuratiebestanden te knoeien ((


Antwoord 17

dit werkte voor mij

openssl req -x509 -nodes -subj '/CN=localhost'  -newkey rsa:4096 -keyout ./sslcert/key.pem -out ./sslcert/cert.pem -days 365

server.js

var fs = require('fs');
var path = require('path');
var http = require('http');
var https = require('https');
var compression = require('compression');
var express = require('express');
var app = express();
app.use(compression());
app.use(express.static(__dirname + '/www'));    
app.get('/*', function(req,res) {
  res.sendFile(path.join(__dirname+'/www/index.html'));
});
// your express configuration here
var httpServer = http.createServer(app);
var credentials = {
    key: fs.readFileSync('./sslcert/key.pem', 'utf8'),
    cert: fs.readFileSync('./sslcert/cert.pem', 'utf8')
};
var httpsServer = https.createServer(credentials, app);
httpServer.listen(8080);
httpsServer.listen(8443);
console.log(`RUNNING ON  http://127.0.0.1:8080`);
console.log(`RUNNING ON  http://127.0.0.1:8443`);

Other episodes