How to created a self-signed certificate, became a CA and enable TLS communication via HTTPS

翻到一个以前笔记下的东西,最近也用得到。先贴上来方便在各处查看 😛


命令速查:

  • 创建Private Key并自签名成为CA
    openssl req -x509 -newkey rsa:4096 -nodes -keyout root.pem -days 9999 -out root.crt
  • 创建Private Key和CSR
    openssl req -newkey rsa:4096 -nodes -keyout svr.pem -out svr.csr
  • 创建x509 extention file
    authorityKeyIdentifier=keyid,issuer
    basicConstraints=CA:FALSE
    subjectAltName=IP:127.0.0.1
  • 用CA签名
    openssl x509 -req -in svr.csr -CA root.crt -CAkey root.pem -days 9999 -extfile svr.ext -out svr.crt

Background knowledge:

TLS uses a combination of symmetric and asymmetric cryptography, as this provides a good compromise between performance and security when transmitting data securely.

With symmetric cryptography, data is encrypted and decrypted with a secret key known to both sender and recipient; typically 128 but preferably 256 bits in length (anything less than 80 bits is now considered insecure). Symmetric cryptography is efficient in terms of computation, but having a common secret key means it needs to be shared in a secure manner.

Asymmetric cryptography uses key pairs – a public key, and a private key. The public key is mathematically related to the private key, but given sufficient key length, it is computationally impractical to derive the private key from the public key. This allows the public key of the recipient to be used by the sender to encrypt the data they wish to send to them, but that data can only be decrypted with the private key of the recipient.

The advantage of asymmetric cryptography is that the process of sharing encryption keys does not have to be secure, but the mathematical relationship between public and private keys means that much larger key sizes are required. The recommended minimum key length is 1024 bits, with 2048 bits preferred, but this is up to a thousand times more computationally intensive than symmetric keys of equivalent strength (e.g. a 2048-bit asymmetric key is approximately equivalent to a 112-bit symmetric key) and makes asymmetric encryption too slow for many purposes.

For this reason, TLS uses asymmetric cryptography for securely generating and exchanging a session key. The session key is then used for encrypting the data transmitted by one party, and for decrypting the data received at the other end. Once the session is over, the session key is discarded.

With TLS it is also desirable that a client connecting to a server is able to validate ownership of the server’s public key. This is normally undertaken using an X.509 digital certificate issued by a trusted third party known as a Certificate Authority (CA) which asserts the authenticity of the public key. In some cases, a server may use a self-signed certificate which needs to be explicitly trusted by the client (browsers should display a warning when an untrusted certificate is encountered), but this may be acceptable in private networks and/or where secure certificate distribution is possible. It is highly recommended though, to use certificates issued by publicly trusted CAs.

We need a self-signed certificate to begin with. A self-signed certificate is a certificate that signed with its own private key. General steps:

  • Create a private key
    • This step results in a commonly accepted format of private key (in DEM or PEM format, whether encrypted or not), which contains additional information of private key generating parameters (if using RSA, then p p p, q q q, λ ( n ) \lambda (n) λ(n), etc.). The additional information helps us later on to generate the public key paired with this private key.
  • Create a Certificate Signing Request (CSR)
    • A CSR requires a public key (created from the private key) and a bunch of other information to create (name, country, organization, etc.)
  • Sign the CSR with the private key created, thus the out result is a new Root Certificate Authority
Create files to became CA
  1. generate a private key
openssl genrsa -des3 -out my_root.pem 2048

This will created a private key encrypted by DES algorithm. If you do not wish to have a encryption, you can opt out the -des3 argument. (Since leaking the private key file itself is dangerous enough to lost all protection against “decyphering message”, the encryption of private key is often considered as not necessary. Passwords only asked for creating public key.)

  1. generate a CSR with the private key generated in step 1
openssl req -key my_root.pem -new -out my_root.csr

You’ll be asked to fill lots of information. An important field is Common Name, which should be the exact Fully Qualified Domain Name (FQDN) of our domain.

Optionally: When the openssl req command asks for a “challenge password”, just press return, leaving the password empty.

This password is used by Certificate Authorities to authenticate the certificate owner when they want to revoke their certificate. Since this is a self-signed certificate, there’s no way to revoke it via CRL (Certificate Revocation List).

  1. sign the CSR with the same private key to create the ultimate root CA
openssl x509 -signkey my_root.pem -in my_root.csr -req -days 9999 -out my_root.crt
  1. You may also finish step 1-3 together with just one command:
openssl req -x509 -newkey rsa:4096 -nodes -keyout my_root.pem -days 9999 -out my_root.crt

the argument -nodes stands for no des encryption for private key.

Create key pair to use during TLS communication

In order to establish TLS connection between Client and Server, both sides should have their own copy of key pair, together with certificates signed by one of the CA trusted by both side.

The procedure is similar to ones above, but instead of sign the CSR by the same private key, we have to sign the CSR by the CA we just created just a minute ago:

  1. generate a private key
  2. generate a CSR
  3. use the CA we created to sign the CSR
Server side certificates
  1. generate private key

simple: openssl genrsa -out server.pem 4096

  1. generate a CSR

same as before: openssl req -new -key server.pem -out server.csr

  1. use the CA to sign the CSR

Before we sign it, it is important to know how actually the TLS work with these certificates.

A certificates might have lots of additional fields, aside from the ones we filled during the CSR creation. One of the field that was utilized by TLS but not required during the CSR/Signing process is the subjectAltName field (since the CSR/Signing is only processing some random strings, or bytes to be specific, it does not really care what’s in it. It is the user of certification who looks at the fields. i.e. in the TLS’s use case, the subJectAltName field matters).

As we did not provide the subjectAltName field in the CSR file, we should provided it in a extension file.

Create a server.ext file with content:

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
subjectAltName=IP:127.0.0.1

If you’re going to use the certificate via Internet, then the field should be filled with the real ip address of the server, or the domain name, like:
subjectAltName=IP:123.222.211.198,IP:,DNS:www.goodweb.xyz,DNS:localhost

note that ipv6 address is also supported.

You may noticed that there are two additional fields in the file: authorityKeyIdentifier and basicConstraints. You may search for what they mean online. 😃

Ok, finally we are able to sign the server’s CSR:

openssl x509 -req -CA my_root.crt -CAkey my_root.pem -in server.csr -days 9999 -extfile server.ext -out server.crt

-CAcreateserial is an argument to ask openssl to generate a random serial number for the certificate. Unless you’re going to sign a crazy amount of CSRs, you might want to leave the option as is.

Greate, now we have the certificate (server.crt) and private key (server.pem) files. Server side preparation is done.

Client side certificates

Similar to the server side’s step 1, 2, and 3, we are going to create a private key, get a CSR, then let the CA sign it to obtain a certificate.

However, in step 3, we don’t really care providing valid subjectAltName field. Just thro localhost or 127.0.0.1 should be good enough, since the server will not be validating it.

Let’s do something new, combining the step 1 and 2 together to get private key and CSR in one command:

openssl req -newkey rsa:4096 -nodes -keyout client.pem -out client.csr

As mentioned before, -nodes is for no des encryption.

Create a client.ext file with content:

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
subjectAltName=IP:127.0.0.1

and finish the signing:

openssl x509 -req -CA my_root.crt -CAkey my_root.pem -in client.csr -days 9999 -CAcreateserial -extfile client.ext -out client.crt

Cool.

Wrap up everything

Overall, we went thru three steps:

  1. Create a CA
  2. Use CA to create a certificate for server
  3. Use CA to create a certificate for client

In each step, we have to:

  1. Create a private key (RSA algorithm, tho other algorithm exists, RSA is the most widely accepted)
  2. Create a CSR
  3. Sign the CSR, either use the private key, or the CA

After the tedious procedure, we finally got the files that matter during a TLS communication:

  • my_root.crt (to be added to trusted CA list)
  • server.pem (the server’s private key file)
  • server.crt (the server’s certificate)
  • client.pem (the client’s private key file)
  • client.crt (the client’s certificate)

And an important file not participating the TLS communication, but required to generate new certificates:

  • my_root.pem (used when sign new certificates)

We should now be able to fill the required file sources (the certificate, private key, trusted CA) of any TLS/SSL programming api to establish a successful secured connection.

Sometimes the client side’s private key / certificate is not required, as the browser / programming API will take care of them. But do remember to add the my_root.crt to become the trusted CA in your dev environment.

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值