Вопрос по openssl, certificate, x509certificate, ssl, ssl-certificate – Как создать самозаверяющий сертификат с OpenSSL

1013

Я добавляю поддержку HTTPS на встроенное устройство Linux. Я попытался создать самозаверяющий сертификат с помощью этих шагов:

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

Это работает, но я получаю некоторые ошибки, например, с Google Chrome:

This is probably not the site you are looking for!
The site's security certificate is not trusted!

Я что-то пропустил? Это правильный способ создания самозаверяющего сертификата?

В дополнение к комментарию @jww. В мае 2017 года Chrome больше не принимает сертификаты без (emtpy) SAN: «Сертификат для этого сайта не содержит расширения альтернативного имени субъекта, содержащего доменное имя или IP-адрес». GerardJP
В настоящее время, если ваш веб-сервер доступен по его FQDN через порт 80 через Интернет, вы можете использовать LetsEncrypt и получать бесплатные полные сертификаты CA (действительные в течение 90 дней, обновление может быть автоматизировано), которые не будут давать предупреждений браузеру / Сообщения. www.letsencrypt.com barny
Вам необходимо импортировать сертификат CA в ваши браузеры и сообщить браузерам, что вы доверяете сертификату, или подписать его одной из крупных организаций, которым уже доверяют браузеры, или игнорировать предупреждение и нажать кнопку. мимо него. Мне нравится последний вариант сам. trojanfoe
Вы не должны использовать & quot; акции & quot; Настройки OpenSSL такие. Это потому, что вы не можете поместить DNS-имена в дополнительное имя субъекта (SAN). Вам необходимо предоставить файл конфигурации сalternate_names раздел и передать его с-config вариант. Кроме того, размещение имени DNS в общем имени (CN) не рекомендуется (но не запрещено) как IETF, так и CA / Browser Forums. Любое DNS-имя в CN также должно присутствовать в SAN. Нет способа избежать использования SAN. Смотрите ответ ниже. jww
Самоподписанные сертификаты считаются небезопасными для Интернета. Firefox будет рассматривать сайт как имеющий недействительный сертификат, в то время как Chrome будет действовать так, как если бы соединение было простым HTTP. Больше деталей:gerv.net/security/self-signed-certs user1202136

Ваш Ответ

14   ответов
430

Am I missing something? Is this the correct way to build a self-signed certificate?

Создать самозаверяющий сертификат легко. Вы просто используетеopenssl req команда. Это может быть сложно создать тот, который будет использоваться самым большим выбором клиентов, таких как браузеры и инструменты командной строки.

Это трудно, потому что браузеры имеют свой собственный набор требований, и они более строгие, чемIETF, Требования, используемые браузерами, документированы наCA / Браузерные форумы (см. ссылки ниже). Ограничения возникают в двух ключевых областях: (1) якоря доверия и (2) имена DNS.

Современные браузеры (например, товары, которые мы используем в 2014/2015 гг.) Хотят получить сертификат, привязанный к доверительной привязке, и хотят, чтобы DNS-имена были представлены в сертификате определенным образом. И браузеры активно движутся против самозаверяющих серверных сертификатов.

Некоторые браузеры не позволяют легко импортировать самозаверяющий сертификат сервера. Фактически, вы не можете использовать некоторые браузеры, такие как браузер Android. Таким образом, полное решение - стать вашим собственным авторитетом.

Если вы не обладаете собственными полномочиями, вы должны правильно присвоить DNS-имена, чтобы сертификат имел наибольшие шансы на успех. Но я бы посоветовал вам стать вашим собственным авторитетом. Легко стать вашим собственным авторитетом, и это обойдет все вопросы доверия (кому лучше доверять, чем вам?).


This is probably not the site you are looking for!
The site's security certificate is not trusted!

Это связано с тем, что браузеры используют предварительно определенный список якорей доверия для проверки сертификатов сервера. Самозаверяющий сертификат не связывается с доверенным якорем.

Лучший способ избежать этого:

  1. Create your own authority (i.e., become a CA)
  2. Create a certificate signing request (CSR) for the server
  3. Sign the server's CSR with your CA key
  4. Install the server certificate on the server
  5. Install the CA certificate on the client

Шаг 1 -Create your own authority просто означает создать самозаверяющий сертификат сCA: true и правильное использование ключа. Это означает, чтоSubject а такжеIssuer один и тот же объект, CA имеет значение true вBasic Constraints (это также должно быть помечено как критическое), использование ключаkeyCertSign а такжеcrlSign (если вы используете CRL), иSubject Key Identifier (SKI) такой же, какAuthority Key Identifier (ОПП).

Чтобы стать вашим собственным центром сертификации, см. *Как вы подписываете запрос на подпись сертификата в вашем центре сертификации? Переполнение стека. Затем импортируйте свой CA в Trust Store, используемый браузером.

Шаги 2 - 4 - это примерно то, что вы делаете сейчас для общедоступного сервера, когда вы подключаетесь к службам CA, напримерStartcom или жеCAcert, Шаги 1 и 5 позволяют вам избежать сторонних полномочий и действовать как свои собственные полномочия (кому лучше доверять, чем себе?).

Следующий лучший способ избежать предупреждения браузера - это доверять сертификату сервера. Но некоторые браузеры, такие как браузер Android по умолчанию, не позволяют вам сделать это. Так что это никогда не будет работать на платформе.

Проблема браузеров (и других подобных пользовательских агентов)not доверие к самоподписанным сертификатам станет большой проблемой в Интернете вещей (IoT). Например, что произойдет, когда вы подключитесь к своему термостату или холодильнику, чтобы запрограммировать его? Ответ: ничего хорошего в отношении пользовательского опыта.

Рабочая группа W3C WebAppSec начинает изучать эту проблему. Смотрите, например,Предложение: пометить HTTP как незащищенный.


How to create a self-signed certificate with OpenSSL

Приведенные ниже команды и файл конфигурации создают самозаверяющий сертификат (он также показывает, как создать запрос на подпись). Они отличаются от других ответов в одном отношении: имена DNS, используемые для самозаверяющего сертификата, находятся вSubject Alternate Name (SAN)и неCommon Name (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
# DNS.7       = 127.0.0.1

# IPv6 localhost
# DNS.8     = ::1

Важно поместить DNS-имя в SAN, а не CN, потому чтоboth IETF и CA / Browser Forums определяют практику. Они также указывают, что DNS-имена в CN устарели (но не запрещены).If Вы помещаете DNS-имя в CN, затем оноmust быть включенным в SAN в соответствии с политиками CA / B. Таким образом, вы не можете избежать использования альтернативного имени субъекта.

Если вы не добавите DNS-имена в SAN, то сертификат не будет проверен в браузере и других пользовательских агентах, которые следуют рекомендациям CA / Browser Forum.

Связано: браузеры следуют политикам CA / Browser Forum; а не политики IETF. Это одна из причин, по которой сертификат, созданный с помощью OpenSSL (который обычно следует IETF), иногда не проверяется в браузере (браузеры следуют CA / B). Это разные стандарты, разные политики выдачи и разные требования к валидации.


Create a self signed certificate (обратите внимание на добавление-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

Create a signing request (обратите внимание на отсутствие-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

Print a self-signed certificate:

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

Print a signing request:

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

Configuration file (passed via -config option)

[ 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            = Ema,il 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

Возможно, вам придется сделать следующее для Chrome. ИначеХром может пожаловатьсяCommon Name is invalid (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. RFC 6797 и 7469do not разрешить IP-адрес, либо.

Я только что ответил на его конкретный вопрос. Я думаю, что не имеет смысла добавлять это длинное описание безопасности, когда ответ был настолько прост
Можно ли использовать подстановочные знаки вalternate_names раздел? Особенно суб-субдомены. У меня есть вопрос, ссылающийся на этот ответ здесь:serverfault.com/questions/711596/…
@ Diegows - ваш ответ не является полным или правильным. Причина, по которой это неверно, обсуждается в длинном посте, который вы не хотите читать :)
Спасибо! Я нашел ваш пост очень полезным. К вашему сведению: я недавно играл с хранилищем и обнаружил, что он настаивал на IP.x 127.0.0.1, а не на DNS.x 127 ... Я не проверял, в стандарте это или нет.
Спасибо @jww. Вы сказали,"1. Create your own authority (i.e, become a CA)"затем сказал:"5. Install the CA certificate on the client", Если корневой ключ был скомпрометирован, злоумышленник может подписать сертификат для любого домена с этим ключом, и если он обманом заставит вас перейти на свой веб-сайт, он может теперь выполнить атаку «человек посередине». Есть ли способ создать корневой ЦС так, чтобы он мог подписывать только промежуточные ЦС, а не сертификаты? Тогда вы можете защитить свой промежуточный центр сертификации с помощью ограничения имени.
381

Вот варианты, описанные вответ @ diegows, описанный более подробно, издокументация:

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

PKCS#10 certificate request and certificate generating utility.

-x509

this option outputs a self signed certificate instead of a certificate request. This is typically used to generate a test certificate or a self signed root CA.

-newkey arg

this option creates a new certificate request and a new private key. The argument takes one of several forms. rsa:nbits, where nbits is the number of bits, generates an RSA key nbits in size.

-keyout filename

this gives the filename to write the newly created private key to.

-out filename

This specifies the output filename to write to or standard output by default.

-days n

when the -x509 option is being used this specifies the number of days to certify the certificate for. The default is 30 days.

-nodes

if this option is specified then if a private key is created it will not be encrypted.

Документация на самом деле более подробная, чем выше; Я просто резюмировал это здесь.

Что такое ХХХ в твоей команде?
XXX в исходной команде должно быть указано «количество дней для сертификации сертификата». По умолчанию 30 дней. Например,-days XXX становится-days 365 если вы хотите, чтобы ваш сертификат действовал в течение 365 дней.See the docs for more.
Спасибо за добавление документации. Эта ссылка IBM на создание самозаверяющего сертификата с использованиемcommand which seems identical to this answer
66

Я бы порекомендовал добавить-sha256 параметр, чтобы использовать алгоритм хеширования SHA-2, поскольку основные браузеры рассматривают возможность отображения «сертификатов SHA-1»; как не безопасно.

Та же самая командная строка из принятого ответа - @diegows с добавленным -sha256

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

Больше информации вБлог безопасности Google.

Update May 2018. Как многие отмечали в комментариях, использование SHA-2 не добавляет никакой безопасности к самозаверяющему сертификату. Но я все же рекомендую использовать его как хорошую привычку не использовать устаревшие / небезопасные криптографические хеш-функции. Полное объяснение доступно вПочему нормально, если сертификаты выше сертификата конечного объекта основаны на SHA-1?.

@ Марк, это важно, потому что SHA-2 более безопасен
& quot; Шифрование мирового класса * нулевая аутентификация = нулевая безопасность & quot;gerv.net/security/self-signed-certs
Открытие сертификата в Windows после переименования cert.pem в cert.cer говорит, что алгоритм отпечатка пальца все еще - Sha1, но алгоритм хэша подписи - sha256.
Следует отметить, что алгоритм подписи, используемый на самозаверяющем сертификате, не имеет значения при принятии решения о том, заслуживает ли он доверия или нет. Корневые сертификаты CA являются самозаверяющими. и по состоянию на май 2018 года все еще существует много активных корневых сертификатов CA, которые подписаны SHA-1. Потому что не имеет значения, доверяет ли сертификат самому себе или как этот сертификат проверяет это доверие. Вы либо доверяете корневому / самозаверяющему сертификату дляwho он говорит, что это так или нет. Увидетьsecurity.stackexchange.com/questions/91913/…
Если он является самозаверяющим ключом, он все равно будет генерировать ошибки браузера, так что это действительно не имеет значения
9

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

Это также работает в Chrome 57, так как он предоставляет SAN, не имея другого файла конфигурации. Это было взято из ответаВот.

Это создает один файл .pem, который содержит как закрытый ключ, так и сертификат. Вы можете переместить их в отдельные файлы .pem, если это необходимо.

Для однострочника, который не требует указывать местоположение openssl.cnf, смотрите:stackoverflow.com/a/41366949/19163
Дали вверх, но нужно обновить как писал @declension.
Для пользователей Linux вам нужно изменить этот путь для конфигурации. например на текущей Ubuntu/etc/ssl/openssl.conf работает
16

Это сценарий, который я использую на локальных компьютерах для установки SAN (subjectAltName) в самозаверяющих сертификатах.

Этот сценарий берет имя домена (example.com) и создает SAN для * .example.com и example.com в одном сертификате. Разделы ниже комментируются. Назовите сценарий (например,generate-ssl.sh) и дать ему исполняемые разрешения. Файлы будут записаны в тот же каталог, что и скрипт.

Chrome 58 и более поздних версий требует, чтобы SAN был установлен в самозаверяющих сертификатах.

#!/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 = [email protected]$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"

Этот сценарий также записывает информационный файл, чтобы вы могли проверить новый сертификат и убедиться, что SAN настроен правильно.

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

Если вы используете Apache, вы можете сослаться на вышеуказанный сертификат в файле конфигурации следующим образом:

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

Не забудьте перезапустить сервер Apache (или Nginx, или IIS), чтобы новый сертификат вступил в силу.

Отлично, я с этим мог бы проголосовать больше, чем один раз!
Я до сих пор не уверен, как CN влияет на общую настройку? Я пытаюсь запустить это какlocalhost или же127.0.0.1:port# что будет соответствующимCN за что-то вроде этого.
@ DJ2 Я бы установил BASE_DOMAIN = & # x201C; localhost & # x201D;
Работает на macOS High Siera и Chrome 58
3

Generate keys

I am using /etc/mysql for cert storage because /etc/apparmor.d/usr.sbin.mysqld contains /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;

Add configuration

/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

На моей установке сервер Ubuntu вошел в систему:/var/log/mysql/error.log

Follow up notes:

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

    MySQL might be denied read access to your certificate file if it is not in apparmors configuration. As mentioned in the previous steps^, save all our certificates as .pem files in the /etc/mysql/ directory which is approved by default by apparmor (or modify your apparmor/SELinux to allow access to wherever you stored them.)

  • SSL error: Unable to get private key

    Your MySQL server version may not support the default rsa:2048 format

    Convert generated rsa:2048 to plain rsa with:

    openssl rsa -in server-key.pem -out server-key.pem
    openssl rsa -in client-key.pem -out client-key.pem
    
  • Check if local server supports 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  |
    +---------------+----------------------------+
    
  • Verifying a connection to the database is SSL encrypted:

    Verifying connection

    When logged in to the MySQL instance, you can issue the query:

    show status like 'Ssl_cipher';
    

    If your connection is not encrypted, the result will be blank:

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

    Otherwise, it would show a non-zero length string for the cypher in use:

    mysql> show status like 'Ssl_cipher';
    +---------------+--------------------+
    | Variable_name | Value              |
    +---------------+--------------------+
    | Ssl_cipher    | DHE-RSA-AES256-SHA |
    +---------------+--------------------+
    1 row in set (0.00 sec)
    
  • Require ssl for specific user's connection ('require ssl'):

    • SSL

    Tells the server to permit only SSL-encrypted connections for the account.

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

    To connect, the client must specify the --ssl-ca option to authenticate the server certificate, and may additionally specify the --ssl-key and --ssl-cert options. If neither --ssl-ca option nor --ssl-capath option is specified, the client does not authenticate the server certificate.


Альтернативная ссылка: длинный учебник поБезопасные соединения PHP с MySQL с помощью SSL.

6

У вас правильная общая процедура. Синтаксис команды приведен ниже.

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

Тем не менее, предупреждения отображаются, потому что браузер не смог проверить идентификацию путем проверки сертификата с помощью известного центра сертификации (CA).

Так как это самозаверяющий сертификат, нет CA, и вы можете спокойно проигнорировать предупреждение и продолжить. Если вы хотите получить настоящий сертификат, который будет узнаваем кем-либо в общедоступном Интернете, то процедура ниже.

  1. Generate a private key
  2. Use that private key to create a CSR file
  3. Submit CSR to CA (Verisign or others, etc.)
  4. Install received cert from CA on web server
  5. Add other certs to authentication chain depending on the type cert

У меня есть более подробная информация об этом в посте наЗащита соединения: создание сертификата безопасности с OpenSSL

188

Начиная с 2019 года, следующая команда удовлетворяет все ваши потребности, включая SAN:

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:example.net,IP:10.0.0.1) -subj /CN=example.com

В OpenSSL & # x2265; 1.1.1, это может быть сокращено до:

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:example.net,IP:10.0.0.1

Это создает сертификат, который

  • valid for the domains example.com and example.net (SAN),
  • also valid for the IP address 10.0.0.1 (SAN),
  • relatively strong (as of 2019) and
  • valid for 3650 days (~10 years).

Создает следующие файлы:

  • Private key: example.key
  • Certificate: example.crt

Вся информация предоставляется в командной строке. Там нет раздражающего интерактивного ввода. Там нет возни с конфигурационными файлами. Все необходимые шаги выполняются этим единственным вызовом OpenSSL: от генерации закрытого ключа до самозаверяющего сертификата.

Remark #1: Crypto parameters

Поскольку сертификат самоподписан и должен приниматься пользователями вручную, нет смысла использовать короткий срок действия или слабую криптографию.

В будущем вы можете использовать больше, чем4096 биты для ключа RSA и алгоритм хеширования сильнее, чемsha256, но с 2019 года это нормальные значения. Они достаточно сильны, хотя поддерживаются всеми современными браузерами.

Remark #2: Parameter "-nodes"

Теоретически вы можете оставить-nodes параметр (что означает «без шифрования DES»), в этом случаеexample.key будет зашифрован паролем. Однако это почти никогда не полезно для установки на сервере, поскольку вам нужно будет либо сохранить пароль на сервере, либо вам придется вводить его вручную при каждой перезагрузке.

Remark #3: MinGW

В Windows в MinGW Bash, вы должны префикс команды сMSYS_NO_PATHCONV=1:

MSYS_NO_PATHCONV=1 openssl ...

Или запустите команду на равнинеcmd.exe Командная строка Windows.

Remark #4: See also

Если-newkey rsa:4096 опущен, по умолчанию OpenSSL - 2048-битный RSA, что звучит достаточно. Также я думаю-sha256 по умолчанию для 1.1.1 или выше.
Я не мог понять, что именно было виновато в расширении arg / CN = localhost до C: / Program Files / Git / CN = localhost, поэтому я просто запустил всю команду в обычном cmd.exe, и она работала просто отлично. На всякий случай, если кто-то борется с этим.
@FranklinYu Вы уверены, что rsa: 2048 будет достаточно через 10 лет? Потому что это срок действия. Как объяснено, не имеет смысла использовать короткий срок действия или слабую криптографию. Большинство 2048-битных ключей RSA имеют срок действия не более 1-3 лет. Что касается OpenSSL 1.1.1, я все еще оставляю sha256 там, так что это более явно и очевидно изменить, если вы хотите более сильный хеш.
Я попытался использовать oneliner # 2 (современный) для Windows в mingw64, и я столкнулся с ошибкой с параметром -subj. `$ openssl req -x509 -newkey rsa: 4096 -sha256 -days 3650 -nodes -keyout localhost.key -out localhost.crt -subj & apos; / CN = localhost & apos; -addext subjectAltName = DNS: localhost, IP: 127.0.0.1 Генерация закрытого ключа RSA [...] для записи нового закрытого ключа в «localhost.key». ----- имя должно быть в формате / type0 = value0 / type1 = value1 / type2 = ... где символы могут быть экранированы \. Это имя не в этом формате: «C: / Program Files / Git / CN = localhost»; Проблемы с выполнением запроса сертификата
70

Современные браузеры теперь выдают ошибку безопасности для правильно сформированных самозаверяющих сертификатов, если им не хватает SAN (Subject Alternate Name).OpenSSL does not provide a command-line way to specify thisтак много разработчиков & apos; учебники и закладки внезапно устарели.

Самый быстрый способ возобновить работу - это короткий автономный файл конфигурации:

  1. Create an OpenSSL config file (example: 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. Create the certificate referencing this config file

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

Example config from https://support.citrix.com/article/CTX135602

Теперь вы можете указать SAN в командной строке с помощью-extension 'subjectAltName = DNS:dom.ain, DNS:oth.er' увидетьgithub.com/openssl/openssl/pull/4986
@ Kyopaxa, вы правы - этот параметр избыточен со строкой 3 файла cnf; обновлено.
Да, это очень актуально сейчас, пять лет спустя. Большинство других ответов, как указано, внезапно перестали работать. Минимальный конфиг, приведенный в этом ответе, очень полезен, поскольку потребовалось бы немало времени, чтобы понять его методом проб и ошибок.
Солидный способ. Благодарю. Я предлагаю добавить-sha256.
Это сработало для меня после удаления последнего параметра -extensions & quot; v3_req & apos; который вызывал ошибку. Использование OpenSSL для Windows. Наконец-то мне удалось решить эту проблему! Благодарю.
123

Я не могу комментировать, поэтому я выделю это как отдельный ответ. Я нашел несколько вопросов с принятым однострочным ответом:

  • The one-liner includes a passphrase in the key.
  • The one-liner uses SHA-1 which in many browsers throws warnings in console.

Вот упрощенная версия, которая удаляет ключевую фразу, повышает безопасность для подавления предупреждений и включает предложение в комментариях для передачи в -subj для удаления полного списка вопросов:

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

Заменить "localhost" с любым доменом, который вам требуется. Вам нужно будет выполнить первые две команды одну за другой, поскольку OpenSSL предложит ввести ключевую фразу.

Чтобы объединить их в файл .pem:

cat server.crt server.key > cert.pem
Как насчет файла key.pem?
Чтобы объединить сертификат и ключ в одном файле:cat server.crt server.key >foo-cert.pem, Работает с примером вopenssl-1.0.2d/demos/ssl/
Мне нужен сертификат разработчика дляgithub.com/molnarg/node-http2 и этот ответ просто лучший.
Это все еще просит у меня пароль
@CallumRogers Удалить-des3 из первой строки, чтобы не запрашивать фразу-пароль, понятия не имею, почему OP конкретно заявляет, что не будет запрашивать, а затем добавить-des3 который добавляет симметричное шифрование
1699

Вы можете сделать это одной командой:

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

Вы также можете добавить-nodes (Короче дляno DES) если вы не хотите защищать свой закрытый ключ с помощью ключевой фразы. В противном случае вам будет предложено ввести не менее 4 символов. пароль.

days Параметр (365) можно заменить любым числом, чтобы повлиять на срок годности. После этого вам будет предложено указать «Название страны», но вы можете просто нажатьEnter и принять значения по умолчанию.

добавлять-subj '/CN=localhost' подавить вопросы о содержании сертификата (заменитьlocalhost с желаемым доменом).

Самозаверяющие сертификаты не проверяются третьими лицами, если вы ранее не импортировали их в браузеры. Если вам нужно больше безопасности, вы должны использовать сертификат, подписанныйцентр сертификации (СА).

добавлять-subj '/CN=localhost' подавить вопросы о содержании сертификата (заменитьlocalhost с желаемым доменом).
PS.-nodes не означает «узлы»; а скорее «нет DES»
Как подпись со сторонним поставщиком обеспечивает большую безопасность?
Для всех, кто использует это в автоматизации, вот все общие параметры для предмета:-subj "/C=US/ST=Oregon/L=Portland/O=Company Name/OU=Org/CN=www.example.com"
Не забудьте использовать-sha256 генерировать сертификат на основе SHA-256.
5

Один лайнер FTW. Мне нравится быть простым. Почему бы не использовать одну команду, которая содержит ВСЕ необходимые аргументы? Вот как мне это нравится - это создает сертификат x509 и его ключ PEM:

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

Эта единственная команда содержит все ответы, которые вы обычно предоставляете для деталей сертификата. Таким образом, вы можете установить параметры и запустить команду, получить выходные данные, а затем пойти на кофе.

& GT; & GT; Подробнее здесь & lt; & lt;

Все аргументы, за исключением ответа SAN ... @ vog, также охватывают это (и предшествуют этому) (хотя здесь заполнено более полное поле "Тема" ...) (не большой поклонник за один год истечения тоже нет)
1

Как уже обсуждалось подробно,самозаверяющие сертификаты не доверяют интернету, Вы можетедобавьте свой самозаверяющий сертификат во многие, но не во все браузеры, В качестве альтернативы вы можетестать вашим собственным центром сертификации.

Основной причиной, по которой человек не хочет получать подписанный сертификат в центре сертификации, является стоимость -Symantec взимает от 995 до 1999 долларов в год за сертификаты - только за сертификат, предназначенный для внутренней сети, Symantec взимает 399 долларов в год, Эту стоимость легко оправдать, если вы обрабатываете платежи по кредитным картам или работаете в центре прибыли высокодоходной компании. Это больше, чем многие могут себе позволить для личного проекта, который каждый создает в Интернете, или для некоммерческой организации, работающей с минимальным бюджетом, или если кто-то работает в центре затрат организации - центры затрат всегда пытаются сделать больше менее.

Альтернативой является использованиеcertbot (увидетьо Certbot). Certbot - это простой в использовании автоматический клиент, который получает и развертывает сертификаты SSL / TLS для вашего веб-сервера.

Если вы настроили certbot, вы можете разрешить ему создавать и поддерживать сертификат, выданный вамиПозвольте зашифровать центр сертификации.

Я сделал это на выходных для своей организации. Я установил необходимые пакеты для certbot на своем сервере (Ubuntu 16.04), а затем выполнил команду, необходимую для настройки и включения certbot. Скорее всего, нуженПлагин DNS для certbot - в настоящее время мы используемDigitalOcean хотя, возможно, скоро перейдет на другой сервис.

Обратите внимание, что некоторые инструкции были не совсем верными и заняли время, чтобы разобраться с Google. В первый раз это заняло довольно много времени, но теперь я думаю, что смогу сделать это за считанные минуты.

Что касается DigitalOcean, я столкнулся с трудностями, когда мне предложили ввести путь к INI-файлу учетных данных DigitalOcean. Сценарий имеет в видуПриложения & amp; API страницу и вкладку токенов / ключей на этой странице. Вам необходимо иметь или сгенерировать персональный токен доступа (чтение и запись) для API DigitalOcean - это шестнадцатеричная строка из 65 символов. Затем эту строку необходимо поместить в файл на веб-сервере, с которого вы запускаете certbot. Этот файл может содержать комментарий в качестве первой строки (комментарии начинаются с #). Вторая строка:

dns_digitalocean_token = 0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff

Как только я понял, как настроить токен чтения и записи для API DigitalOcean, было довольно легко использовать certbot для настройкисертификат подстановочного знака, Обратите внимание, что не нужно настраивать подстановочный сертификат, вместо этого можно указать каждый домен и поддомен, к которому требуется применить сертификат. Это был подстановочный сертификат, который требовал INI-файл учетных данных, содержащий личный токен доступа от DigitalOcean.

Обратите внимание, что сертификаты открытых ключей (также известные как сертификаты идентификации или сертификаты SSL) истекают и требуют обновления. Таким образом, вам необходимо будет обновлять свой сертификат на периодической (повторяющейся) основе. Обложки документации Certbotвозобновление сертификатов.

Мой план состоит в том, чтобы написать сценарий для использования команды openssl, чтобы получить дату истечения срока действия моего сертификата и инициировать продление по истечении 30 дней или менее до его истечения. Затем я добавлю этот скрипт в cron и буду запускать его один раз в день.

Вот команда для считывания даты истечения срока действия вашего сертификата:

[email protected]:~# /usr/bin/openssl x509 -enddate -noout -in path-to-certificate-pem-file
notAfter=May 25 19:24:12 2019 GMT
3

Однострочная версия 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"))

Похожие вопросы