signed certificate with openssl?
I'm adding https support to an embedded linux device. I have tried to generate a self-signed certificate with these steps:
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
This works, but I get some errors with, for example, google chrome:
This is probably not the site you are looking for!
The site's security certificate is not trusted!
Am I missing something? Is this the correct way to build a self-signed certificate?
You can do that in one command:
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365
You can also add -nodes
if you don't want to protect your private key with a passphrase, otherwise it will prompt you for "at least a 4 character" password. The days parameter (365) you can replace with any number to affect expiration date. It will then prompt you for things like "Country Name" but you can just hit enter and accept defaults.
Self-signed certs are not validated with any third party unless you import them to the browsers previously. If you need more security, you should use a certificate signed by a CA.
Am I missing something? Is this the correct way to build a self-signed certificate?
Its easy to create a self signed certificate. You just use the openssl req
command. It can be tricky to create one that can be consumed by the largest selection of clients, like browsers and command line tools.
Its difficult because the browsers have their own set of requirements, and they are more restrictive than the IETF. The requirements used by browsers are documented at the CA/Browser Forums (see references below). The restrictions arise in two key areas: (1) trust anchors, and (2) DNS names.
Modern browsers (like the warez we're using in 2014/2015) want a certificate that chains back to a trust anchor, and they want DNS names to be presented in particular ways in the certificate. And Browsers are actively moving against self signed server certificates
Some browsers don't exactly make it easy to import a self signed server certificate. In fact, you can't with some browsers, like Android's browser. So the complete solution is to become your own authority.
In the absence of becoming your own authority, you have to get the DNS names right to give the certificate the greatest chance of success. But I would encourage you to become your own authority. Its easy to become your own authority and it will side step all the trust issues (who better to trust than yourself?).
This is probably not the site you are looking for!
The site's security certificate is not trusted!
This is because browsers use a predefined list of trust anchors to validate server certificates. A self signed certificate does not chain back to a trusted anchor.
The best way to avoid this is:
Step 1 - Create your own authority just means to create a self signed certificate with CA: true
and proper key usage. That means the Subject and Issuer are the same entity, CA is set to true in Basic Constraints (it should also be marked as critical), key usage is keyCertSign
and crlSign
(if you are using CRLs), and the Subject Key Identifier (SKI) is the same as the Authority Key Identifier (AKI).
To become your own certificate authority, see How do you sign Certificate Signing Request with your Certification Authority? on Stack Overflow. Then, import your CA into the Trust Store used by the browser.
Steps 2 - 4 are roughly what you do now for a public facing server when you enlist the services of a CA like Startcom or CAcert. Steps 1 and 5 allows you to avoid the third party authority, and act as your own authority (who better to trust than yourself?).
The next best way to avoid the browser warning is to trust the server's certificate. But some browsers, like Android's default browser, do not let you do it. So it will never work on the platform.
The issue of browsers (and other similar user agents) not trusting self signed certificates is going to be a big problem in the Internet of Things (IoT). For example, what is going to happen when you connect to your thermostat or refrigerator to program it? The answer is, nothing good as far as the user experience is concerned.
The W3C's WebAppSec Working Group is starting to look at the issue. See, for example, Proposal: Marking HTTP As Non-Secure.
How to create a self-signed certificate with openssl?
The commands below and the configuration file create a self signed certificate (it also shows you how to create a signing request). They differ from other answers in one respect: the DNS names used for the self signed certificate are in the Subject Alternate Name (SAN), and not the Common Name (CN).
The DNS names are placed in the SAN through the configuration file with the line subjectAltName = @alternate_names
(there's no way to do it through the command line). Then there's an alternate_names
section in the configuration file (you should tune this to suit your taste):
[ 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
Its important to put DNS name in the SAN and not the CN because both the IETF and the CA/Browser Forums specify the practice. They also specify that DNS names in the CN are deprecated (but not prohibited). If you put a DNS name in the CN, then it must be included in the SAN under the CA/B policies. So you can't avoid using the Subject Alternate Name.
If you don't do put DNS names in the SAN, then the certificate will fail to validate under a browser and other user agents which follow the CA/Browser Forum guidelines.
Related: browsers follow the CA/Browser Forum policies; and not the IETF policies. That's one of the reasons a certificate created with OpenSSL (which generally follows the IETF) sometimes does not validate under a Browser (browsers follow the CA/B). They are different standards, they have different issuing policies and different validation requirements.
Create a self signed certificate (notice the addition of -x509
option):
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 (notice the lack of -x509
option):
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 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
You may need to do the following for Chrome. Otherwise Chrome may complain a Common Name is invalid ( ERR_CERT_COMMON_NAME_INVALID
). I'm not sure what the relationship is between an IP address in the SAN and a CN in this instance.
# IPv4 localhost
# IP.1 = 127.0.0.1
# IPv6 localhost
# IP.2 = ::1
There are other rules concerning the handling of DNS names in X.509/PKIX certificates. Refer to these documents for the rules:
RFC 6797 and RFC 7469 are listed because they are more restrictive than the other RFCs and CA/B documents. RFC's 6797 and 7469 do not allow an IP address, either.
Here are the options described in @diegows's answer, described in more detail, from the documentation:
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.
The documentation is actually more detailed than the above, I just summarized it here.
链接地址: http://www.djcxy.com/p/16220.html上一篇: Java中的上下文究竟是什么?
下一篇: 与openssl签署的证书?