To create new wiki account, please join us on #znc at Libera.Chat and ask admins to create a wiki account for you. You can say thanks to spambots for this inconvenience.
Certificatetest: Difference between revisions
No edit summary |
|||
(43 intermediate revisions by 2 users not shown) | |||
Line 2: | Line 2: | ||
= ZNC PKI Management = | = ZNC PKI Management = | ||
Make sure that the certificate private | Make sure that the certificate private keys are not encrypted and have not password protection on it. ZNC is unable to properly handle encrypted private key files. | ||
== ZNC Certificates == | |||
ZNC acts as a proxy for the IRC connections; it places itself between our IRC Client(s) and the IRC Server(s) acting as: | |||
* Server for our IRC Clients (Client <-> ZNC) | |||
* Client for IRC Servers (ZNC <-> Server) | |||
As per the time of writing (August 2021), current ZNC version involves certificates in 3 ways: | |||
* ''Client <-> ZNC'' | |||
** '''znc.pem:''' the main and <u>mandatory</u> certificate used by the ZNC to <u>establish</u> all secure connections with IRC and web Client(s). | |||
** '''client.pem:''' the certificates used by the [[certauth|CertAuth module]] for the authentication of IRC & web Client(s) with ZNC. | |||
::- Certificate stored on <u>local machine</u> and Fingerprint saved in the ZNC | |||
* ''ZNC <-> Server'' | |||
** '''user.pem:''' the certificates used by the [[cert|Cert module]] for the authentication of ZNC with the IRC Server(s). | |||
::- Certificate stored on <u>ZNC machine</u> and Fingerprint saved in the IRC Server account | |||
In the commands below we will talk generally of ''private key'' (''priv.pem''), ''public key'' (''pub.pem''), Certificate Signing Request (''csr.pem'') and Certificate (''cert.pem'') without using precise names. Check the page from which you are coming from to understand how to manage the name of generated file. | |||
'''Note:''' Be aware that <code>znc.pem</code> is automatically created during configuration process (if SSL is enabled) and it can be overwritten with the command <code>znc --makepem</code>. | |||
== znc.pem == | |||
=== ZNC 1.7.0+ === | === ZNC 1.7.0+ === | ||
Since 1.7, you can configure ZNC to read different parts of the certificate from different files: | Since 1.7, you can configure ZNC to read different parts of the certificate from different files: | ||
Line 20: | Line 36: | ||
<code>znc.pem</code> '''must''' contain everything in order from the "most private" to the "most public" entries, except for the root certificate. | <code>znc.pem</code> '''must''' contain everything in order from the "most private" to the "most public" entries, except for the root certificate. | ||
It may be something like this: | |||
cat your-certificate-private-key.pem > znc.pem | cat your-certificate-private-key.pem > znc.pem | ||
cat your-certificate.pem >> znc.pem | cat your-certificate.pem >> znc.pem | ||
# If your certificate | |||
cat intermediate-certificate-of- | # If your certificate has been signed by a CA | ||
# | ## add first the Intermediate certificate (if exists - not signed directly by the Root) | ||
cat root-certificate-of- | cat intermediate-certificate-of-CA.pem >> znc.pem | ||
## and after add the Root certificate; even if this is redundant. If client doesn't know this CA, it's not trusted anyway. | |||
cat root-certificate-of-CA.pem >> znc.pem | |||
# DH parameters at the end | # DH parameters at the end | ||
## If they will not be added, ciphers which relay DH can't be used | |||
cat dhparam.pem >> znc.pem | cat dhparam.pem >> znc.pem | ||
To apply changes to certificate file to ZNC, just put (replace) it in ZNC's work folder. | To apply changes to certificate file to ZNC, just put (replace) it in ZNC's work folder. | ||
As of 1.6.2, ZNC will reload <code>znc.pem</code> each time a client connects, but it'll be fixed in future. | '''Note:''' As of 1.6.2, ZNC will reload <code>znc.pem</code> each time a client connects, but it'll be fixed in future. | ||
= Custom OpenSSL Configuration = | |||
In that guide we will adopt a customized version of the openssl configuration file; you can download it from [[OpenSSL.cnf_SelfSigned|HERE]]: copy all the content and store it in a file called <code>selfsigned.cnf</code> | |||
= Algorithms = | = Algorithms = | ||
Line 94: | Line 117: | ||
# Generate the ECC private key with 256-bit key length | # Generate the ECC private key with 256-bit key length | ||
openssl ecparam -genkey -name prime256v1 -outform PEM -out priv.pem | openssl ecparam -genkey -name prime256v1 -outform PEM -out priv.pem | ||
# Generate the ECC public key | # Generate the ECC public key | ||
openssl ec -outform PEM -pubout -in priv.pem -out pub.pem | openssl ec -outform PEM -pubout -in priv.pem -out pub.pem | ||
# Get information on the ECC private key | # Get information on the ECC private key | ||
openssl ecparam -noout -text -in priv.pem | openssl ecparam -noout -text -in priv.pem -out priv.info | ||
# Get sensitive information on the ECC private key | # Get sensitive information on the ECC private key | ||
openssl ecparam -noout -text -in priv.pem -param_enc explicit | openssl ecparam -noout -text -in priv.pem -param_enc explicit >> priv.info | ||
== RSA == | == RSA == | ||
# Generate the RSA private key with 4096-bit key length | # Generate the RSA private key with 4096-bit key length | ||
openssl genrsa -out priv.pem 4096 | openssl genrsa -out priv.pem 4096 | ||
# Generate the RSA public key | # Generate the RSA public key | ||
openssl rsa -outform PEM -pubout -in priv.pem -out pub.pem | openssl rsa -outform PEM -pubout -in priv.pem -out pub.pem | ||
# Get sensitive information on the RSA private key | # Get sensitive information on the RSA private key | ||
openssl rsa -noout -text -in priv.pem | openssl rsa -noout -text -in priv.pem -out priv.info | ||
= Certificate Signing Request = | = Certificate Signing Request = | ||
Line 117: | Line 143: | ||
* 1 csr.pem | * 1 csr.pem | ||
To run the code below you need the [[#Custom_OpenSSL_Configuration|selfsigned.cnf]] file. | |||
# Generate a CSR based on the private key | # Generate a CSR based on the private key | ||
openssl req -new -sha512 -key priv. | openssl req -new -sha512 -key priv.pem -out csr.pem -config selfsigned.cnf | ||
You will be prompted to fill the fields below: | You will be prompted to fill the fields below: | ||
{| class="wikitable" | {| class="wikitable" | ||
Line 153: | Line 180: | ||
-subj "/CN=YourZncNickname" | -subj "/CN=YourZncNickname" | ||
or | or | ||
-subj "/CN=FQDN:Port" | -subj "/CN=FQDN:Port" | ||
'''''Note:''' Some user could encounter some issue to login via certificate due to random settings/old caching/etc; try to use your ZNC's FQDN:Port instead of YourZncNickname. Thanks to <CryptoSiD> on Freenode for the tip '' | '''''Note:''' Some user could encounter some issue to login via certificate due to random settings/old caching/etc; try to use your ZNC's FQDN:Port instead of YourZncNickname. Thanks to <CryptoSiD> on Freenode for the tip '' | ||
Line 159: | Line 186: | ||
The last step is to generate the X.509 certificate using the CSR previously generated. | The last step is to generate the X.509 certificate using the CSR previously generated. | ||
Now you can: | Now you can: | ||
* submit the CSR to a [[ | * submit the CSR to a [[#Signed by Public CA|Public CA]] | ||
* self signing it | * [[#Self Signed|self signing it]] | ||
''' | '''Hint:''' If you are generating the certificate for: | ||
* | * ''Client <-> ZNC'' | ||
* [[Certauth|CertAuth module]] | ** '''<code>znc.pem</code>:''' you have to decide based on your scenario | ||
* ZNC | ** '''[[Certauth|CertAuth module]]:''' you can opt for a Self Signed Certificate, but it could be recognized as untrusted | ||
* ''ZNC <-> Server'' | |||
** '''[[Cert|Cert module]]:''' you can go directly with a simpler/faster/costless Self Signed Certificate | |||
At the end of the process you will have: | At the end of the process you will have: | ||
Line 173: | Line 201: | ||
* 1 bundle.pem (''optional - depending on the Public CA'') | * 1 bundle.pem (''optional - depending on the Public CA'') | ||
== Public CA == | == Signed vs Self Signed == | ||
The only difference between the 2 classes of certificates is the Issuer, the entity that sign the certificate. | |||
=== Security explanation === | |||
By the security point of view, there are no immediate differences between a Signed and a Self Signed (well configured) certificate. They both encrypts the traffic and prevent Man-In-The-Middle attacks. | |||
All modern browsers nowadays give red warning if you visit HTTPS site using a Self Signed Certificate, cause it could have been created a second before the connection by an attacker and the browser warns you about "at who you are connecting to", a "not trusted" site. Once you store the certificate and ''flag'' it as trusted, the browser will trust that Fingerprint and will consider it as trusted (during its validity period). Once expired, the browser will start to warn you again cause it is an expired Certificate. Once expired the certificate is still cryptographically security valid, but it is considered as security risk. In the past a certificate was valid for periods like 3-5 years. Nowadays a certificate (thanks to the advance of technology) could be renewed even every 30 days. So in the case you set the expiration of a certificate to 1 day, at 2nd day it will still perform its security job, but browser will warn you ''"Ehy! The certificate is expired! Probably a new one has been released, move to updated it"''. | |||
If you save the Fingerprint of your Self Signed Certificate and will check it when you get the warn (to prevent false positive or strict security settings), is cryptographically the same of a Signed one. | |||
All of this is true if the certificate is '''secure'''; if it uses unsecure features, both Signed and Self Signed would be unsecure. Example: Certificate signed with SHA-1 hash algorithm; all modern browser warns you about that certificates, even if they are Signed by a Public trusted CA or a self signed one. | |||
Don't worry, the commands on this guide use SHA-512 as hash signing algorithm; the current standards use SHA-256, the hash signing algorithm before the SHA-512. | |||
=== Practical explanation === | |||
To sign a certificate a private key is required; the private key is "personal", so it belongs to an "entity". When you create a private key, you are assuring ''"Im the owner of this key"''. To share the information on your ownership, you create a Certificate derived from that private key. Now, it is required an third party that signs with his private key your certificate (signing request) saying to the world "This certificate belongs to that person" (that's the basic job of a CA). When you let sign your Certificate by a third global known (trusted) party, a Public CA, you get a so named "Signed Certificate". Thanks to the cryptography world, the world will recognize the Certificate as your own and valid, cause it is signed by a (trusted) Public CA that they recognize. Instead, if you decide to sign by your self, with yourself key, it will become a so called Self signed certificate cause it has been signed by yourself (by itself private key). And Yes and No: Yes, all Public CA are based on a first Self Signed Certificate, but it has been spread globally and trusted so all people recognize it as valide; No, even if you sign the certificate with another private key created by yourself something will change; that because no one knows about your "signing key" and no one will trust it. You are <u>theoretically</u> creating a Private CA (no, you are practically not creating a CA cause it is a bit harder than this) and you are signing it with another key, but the key used to sign is not '''trusted''' by the world. That's the main point of a CA, being recognized valid cause signed by a trusted party. | |||
You could develop your own private CA, trust it on your machines, and those machines will then recognize its certificates as valid, but this is mainly done on internal networks for personal application services. If you are going to share the ZNC instance, you should share also the entire CA infrastructure with all people... It is so much work when if you need to share the ZNC instance with other people, a simple certificate has totally affordable cost; moreover there are free services like Let's Encrypt that provide SSL Certificate for free. Remember that for the web navigation, the main purpouse of a certificate is to encrypt the traffic; for the "recognized ownership" there are further (paid) levels of certificates. | |||
== Signed by Public CA == | |||
Signed SSL certificates are recommended when more than one person share the same ZNC instance. | Signed SSL certificates are recommended when more than one person share the same ZNC instance. | ||
Line 184: | Line 226: | ||
In cryptography and computer security, a self-signed certificate is a security certificate that is not signed by a certificate authority (CA) | In cryptography and computer security, a self-signed certificate is a security certificate that is not signed by a certificate authority (CA) | ||
- [Source: [https://en.wikipedia.org/wiki/Self-signed_certificate Wikipedia]] | - [Source: [https://en.wikipedia.org/wiki/Self-signed_certificate Wikipedia]] | ||
Extending the mindset, the CA is considered ''Public'', so | Extending the mindset, the CA is considered ''Public'', so widely distribuited. In that case even a Private CA Signed certificate can be considered as a Self Signed (signed by our own CA - not Public). | ||
To do not go out of the scope of this page, we will not consider the scenario of signing the CSR with a Private CA; moreover, if you have a Private CA, you should be able to sign a CSR by your self. | To do not go out of the scope of this page, we will not consider the scenario of signing the CSR with a Private CA; moreover, if you have a Private CA, you should be able to sign a CSR by your self. | ||
Regardless you opted out for an ''ECC'' or a ''RSA'' algorithms, the commands are the same. | To run the code below you need the [[#Custom_OpenSSL_Configuration|selfsigned.cnf]] file. | ||
Regardless you opted out for an ''ECC'' or a ''RSA'' algorithms, the commands are the same. In the code below use: | |||
* <code>server_cert</code> if you are generating the certificate for the ZNC (<code>znc.pem</code>) | |||
* <code>usr_cert</code> if you are generating the certificate for modules/SASL/authentications | |||
# Generate the Certificate, selfsigning the CSR | # Generate the Certificate, selfsigning the CSR | ||
openssl req -x509 -sha512 -days | openssl req -new -x509 -sha512 -days 365 -key priv.pem -in csr.pem -out cert.pem -config selfsigned.cnf -extensions usr_cert/server_cert | ||
# Store information of the certificate | # Store information of the certificate | ||
openssl x509 -fingerprint -sha512 -serial -hash -text -noout -in cert.pem -out cert.info | openssl x509 -fingerprint -sha512 -serial -hash -text -noout -in cert.pem -out cert.info | ||
= DHparam= | = DHparam= | ||
An additional step is to generate the Diffie-Hellman key exchange parameters. If they will not be generated, ciphers which relay DH can't be used | |||
The dhparam file | The Diffie-Hellman key exchange ([https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange Wikipedia] - [https://wiki.openssl.org/index.php/Diffie_Hellman OpenSSL]) is a method of securely exchanging cryptographic keys. | ||
It has to be append at the end of the <code>znc.pem</code>. | |||
The dhparam file does not need to be kept secret and can be used multiple times. | |||
== Local generation == | |||
In the command below, feel free to increase 2048 as you like but be aware that this will take '''''a long time'''''. | |||
# Generate DH parameters | |||
openssl dhparam -out dhparam.pem 2048 | openssl dhparam -out dhparam.pem 2048 | ||
# Check DH parameters created | |||
openssl dhparam -noout -text -check -in dhparam.pem | |||
== Online generation == | |||
If you want to speed up the generation process you can use the services of [[https://2ton.com.au/dhtool/#service 2ton]]; they offer freshly generated DHparam files. | If you want to speed up the generation process you can use the services of [[https://2ton.com.au/dhtool/#service 2ton]]; they offer freshly generated DHparam files. | ||
Line 211: | Line 268: | ||
For example you need this kind of format when you have to interact with browser (Ex. [[Certauth| CertAuth module]]) | For example you need this kind of format when you have to interact with browser (Ex. [[Certauth| CertAuth module]]) | ||
openssl pkcs12 -export -in cert.pem -out znc_user. | openssl pkcs12 -export -nodes -inkey priv.pem -in cert.pem -out znc_user.p12 -password pass: | ||
== Fingerprint == | == Fingerprint == | ||
Each certificate has its own fingerprint and can be recognized by it. Fingerprints are calculated using | Each certificate has its own fingerprint and can be recognized by it. Fingerprints are calculated using [https://en.wikipedia.org/wiki/Cryptographic_hash_function HASHes]. Allowed hashes are: <code>MD5</code>,<code>SHA1</code>,<code>SHA256</code>,<code>SHA512</code>. | ||
openssl x509 -md5 -noout -fingerprint -in | There are many reasons for which we would like to verify the fingerprint of a certificate: | ||
openssl x509 -sha1 -noout -fingerprint -in | * to set up the [[Cert | Cert module]] | ||
openssl x509 -sha256 -noout -fingerprint -in | * to check if a MITM attack is in progress | ||
openssl x509 -sha512 -noout -fingerprint -in | * etc | ||
We could retrieve the fingerprint as from a local certificate as from an online one. | |||
=== Local certificate === | |||
# MD5 | |||
openssl x509 -md5 -noout -fingerprint -in cert.pem > cert.md5 | |||
openssl x509 -md5 -noout -fingerprint -in cert.pem | sed -e 's/^.*=//;s/://g;y/ABCDEF/abcdef/' >> cert.md5 | |||
# SHA-1 | |||
openssl x509 -sha1 -noout -fingerprint -in cert.pem > cert.sha1 | |||
openssl x509 -sha1 -noout -fingerprint -in cert.pem | sed -e 's/^.*=//;s/://g;y/ABCDEF/abcdef/' >> cert.sha1 | |||
# sha-256 | |||
openssl x509 -sha256 -noout -fingerprint -in cert.pem > cert.sha256 | |||
openssl x509 -sha256 -noout -fingerprint -in cert.pem | sed -e 's/^.*=//;s/://g;y/ABCDEF/abcdef/' >> cert.sha256 | |||
# SHA-512 | |||
openssl x509 -sha512 -noout -fingerprint -in cert.pem > cert.sha512 | |||
openssl x509 -sha512 -noout -fingerprint -in cert.pem | sed -e 's/^.*=//;s/://g;y/ABCDEF/abcdef/' >> cert.sha512 | |||
If you need the fingerprint just as terminal output remove the redirect <code>> cert.***</code>. | |||
If you need the fingerprint in the default format, use the commands without <code>| sed -e 's/^.*=//;s/://g;y/ABCDEF/abcdef/'</code> | |||
'''Note:''' If you are here from the [[Cert| Cert module]], be aware that different IRC networks use different fingerprints; for example Libera.chat uses SHA-512. Consult the network you're connecting to for this information. | '''Note:''' If you are here from the [[Cert| Cert module]], be aware that different IRC networks use different fingerprints; for example Libera.chat uses SHA-512. Consult the network you're connecting to for this information. | ||
=== Online certificate === | |||
# Replace with the hostname/FQDN of your ZNC Server | |||
sslhost=znc.example.com | |||
# Replace with the SSL port of your ZNC Server | |||
sslport=6697 | |||
sslcert=$(openssl s_client -showcerts -connect "$sslhost":"$sslport" < /dev/null) | |||
echo "$sslcert" | openssl x509 -noout -fingerprint -md5 | |||
echo "$sslcert" | openssl x509 -noout -fingerprint -sha1 | |||
echo "$sslcert" | openssl x509 -noout -fingerprint -sha256 | |||
echo "$sslcert" | openssl x509 -noout -fingerprint -sha512 | |||
= Glossary = | = Glossary = | ||
Line 228: | Line 316: | ||
* '''CSR:''' Certificate Signing Request | * '''CSR:''' Certificate Signing Request | ||
* '''DER:''' Distinguished Encoding Rules is a binary encoding for X.509 certificates and private keys | * '''DER:''' Distinguished Encoding Rules is a binary encoding for X.509 certificates and private keys | ||
* '''DES:''' Data Encryption Standard is a symmetric-key algorithm for the encryption of digital data. Too insecure for encryption nowadays. | |||
* '''DSA:''' Digital Signature Algorithm | * '''DSA:''' Digital Signature Algorithm | ||
* '''ECC:''' Elliptic Curve Cryptography algorithms | * '''ECC:''' Elliptic Curve Cryptography algorithms | ||
* '''FQDN:''' Fully Qualified Domain Name or Hostname | * '''FQDN:''' Fully Qualified Domain Name or Hostname | ||
* '''MITM:''' Man-In-The-Middle attack; an attacker acts as proxy sniffing and/or altering the traffic data | |||
* '''P12:''' Common file extension for '''PKCS#12''' format | * '''P12:''' Common file extension for '''PKCS#12''' format | ||
* '''PEM:''' Privacy Enhanced Mail is a Base64 encoded ASCII file format | * '''PEM:''' Privacy Enhanced Mail is a Base64 encoded ASCII file format | ||
Line 240: | Line 330: | ||
* '''Public Key:''' One of the key pair. It is the one that can be freely shared | * '''Public Key:''' One of the key pair. It is the one that can be freely shared | ||
* '''RSA:''' Rivest-Shamir-Adleman algorithms | * '''RSA:''' Rivest-Shamir-Adleman algorithms | ||
* '''SSL:''' Secure Sockets Layer is a cryptographic protocol designed to provide communications security over a computer network |
Latest revision as of 18:26, 23 August 2021
The scope of this page is to be the guide to manage ZNC's certificates. To increase the security check the Hardening page.
ZNC PKI Management
Make sure that the certificate private keys are not encrypted and have not password protection on it. ZNC is unable to properly handle encrypted private key files.
ZNC Certificates
ZNC acts as a proxy for the IRC connections; it places itself between our IRC Client(s) and the IRC Server(s) acting as:
- Server for our IRC Clients (Client <-> ZNC)
- Client for IRC Servers (ZNC <-> Server)
As per the time of writing (August 2021), current ZNC version involves certificates in 3 ways:
- Client <-> ZNC
- znc.pem: the main and mandatory certificate used by the ZNC to establish all secure connections with IRC and web Client(s).
- client.pem: the certificates used by the CertAuth module for the authentication of IRC & web Client(s) with ZNC.
- - Certificate stored on local machine and Fingerprint saved in the ZNC
- ZNC <-> Server
- user.pem: the certificates used by the Cert module for the authentication of ZNC with the IRC Server(s).
- - Certificate stored on ZNC machine and Fingerprint saved in the IRC Server account
In the commands below we will talk generally of private key (priv.pem), public key (pub.pem), Certificate Signing Request (csr.pem) and Certificate (cert.pem) without using precise names. Check the page from which you are coming from to understand how to manage the name of generated file.
Note: Be aware that znc.pem
is automatically created during configuration process (if SSL is enabled) and it can be overwritten with the command znc --makepem
.
znc.pem
ZNC 1.7.0+
Since 1.7, you can configure ZNC to read different parts of the certificate from different files:
SSLCertFile = /path/to/combined/cert.pem SSLKeyFile = /path/to/private/priv.pem SSLDHParamFile = /path/to/DH/dhparam.pem
Read Configuration about how to edit config.
The old way (described below) still works.
Before ZNC 1.7
znc.pem
must contain everything in order from the "most private" to the "most public" entries, except for the root certificate.
It may be something like this:
cat your-certificate-private-key.pem > znc.pem cat your-certificate.pem >> znc.pem # If your certificate has been signed by a CA ## add first the Intermediate certificate (if exists - not signed directly by the Root) cat intermediate-certificate-of-CA.pem >> znc.pem ## and after add the Root certificate; even if this is redundant. If client doesn't know this CA, it's not trusted anyway. cat root-certificate-of-CA.pem >> znc.pem # DH parameters at the end ## If they will not be added, ciphers which relay DH can't be used cat dhparam.pem >> znc.pem
To apply changes to certificate file to ZNC, just put (replace) it in ZNC's work folder.
Note: As of 1.6.2, ZNC will reload znc.pem
each time a client connects, but it'll be fixed in future.
Custom OpenSSL Configuration
In that guide we will adopt a customized version of the openssl configuration file; you can download it from HERE: copy all the content and store it in a file called selfsigned.cnf
Algorithms
The Public Key Infrastructures (PKI) are based on asymmetric cryptography principles: public & private key.
There are 3 primary algorithms used for PKI key generation:
- (ECC) Elliptic Curve Cryptography
It is the most recently-developed encryption method of the three, but it is going to be more supported. With shorter key lengths, it provides equivalent levels of cryptographic strength as RSA and DSA.
- (RSA) Rivest-Shamir-Adleman
The RSA algorithm was developed in 1977 by Ron Rivest, Adi Shamir, and Leonard Adleman. It is currently the most used and supported key algorithm. Nowadays the key length standard is 2048-4096 bits.
- (DSA) Digital Signature Algorithm
It uses a different algorithm than RSA to create public/private keys but both are considered to be equivalent at same key length. The main differences come down to performance, speed and adoption by the market. Moreover some software are limited to manage DSA up to 1024 bits.
Algorithms Key Size Comparison (bits) | |||||
---|---|---|---|---|---|
Symmetric | RSA/DSA | ECC | |||
80 | 1024 | 160-223 | |||
112 | 2048 | 224-255 | |||
128 | 3072 | 256-383 | |||
192 | 7680 | 384-511 | |||
256 | 15360 | 512+ |
Considering the current security standards, we will continue using ECC and RSA.
Key generation
The first step is to create a key pair. As described before, we will provide commands to create ECC or RSA keys.
WARNING: The folllowing commands will not encrypt/password protect the private key cause ZNC is unable to properly handle encrypted private key files. For this reason keep it secret.
Before to proceed, if you want to adopt the ECC, check 2 constraints: * Your IRC Client/Server supports ECC * In the case you want certificates signed by a Public CA, be sure it supports ECC If any of these 2 points will be a NO, then use the RSA.
Regardless of the algorithm you choose, at the end of the process you will have:
- 1 priv.pem
- 1 pub.pem
- 1 priv.info (optional)
ECC
# Generate the ECC private key with 256-bit key length openssl ecparam -genkey -name prime256v1 -outform PEM -out priv.pem # Generate the ECC public key openssl ec -outform PEM -pubout -in priv.pem -out pub.pem # Get information on the ECC private key openssl ecparam -noout -text -in priv.pem -out priv.info # Get sensitive information on the ECC private key openssl ecparam -noout -text -in priv.pem -param_enc explicit >> priv.info
RSA
# Generate the RSA private key with 4096-bit key length openssl genrsa -out priv.pem 4096 # Generate the RSA public key openssl rsa -outform PEM -pubout -in priv.pem -out pub.pem # Get sensitive information on the RSA private key openssl rsa -noout -text -in priv.pem -out priv.info
Certificate Signing Request
The second step is to create a Certificate Signing Request (CSR); to proceed a priv.pem is required (ECC or RSA doesn't matter).
At the end of the process you will have:
- 1 csr.pem
To run the code below you need the selfsigned.cnf file.
# Generate a CSR based on the private key openssl req -new -sha512 -key priv.pem -out csr.pem -config selfsigned.cnf
You will be prompted to fill the fields below:
Country Name (2 letter code) | The two-letter country code where your company is legally located. |
---|---|
State or Province Name (full name) | The state/province where your company is legally located. |
Locality Name (e.g., city) | The city where your company is legally located. |
Organization Name (e.g., company) | Your company's legally registered name (e.g., YourCompany, Inc.). |
Organizational Unit Name (e.g., section) | The name of your department within the organization. (You can leave this option blank; simply press Enter.) |
Common Name (e.g., server FQDN) | The fully-qualified domain name (FQDN) (e.g., www.example.com). |
Email Address | Your email address. (You can leave this option blank; simply press Enter.) |
A challenge password | Leave this option blank (simply press Enter). |
An optional company name | Leave this option blank (simply press Enter). |
If you want automate the process, you can feed the command providing information with this additional parameter:
-subj "/C=XX/ST=XXXX/L=YYYY/O=ZZZZ/OU=XYZ/CN=FQDN/emailAddress=user [at] domain [dot] com"
If you need the certificate only for the modules Cert or CertAuth you can simply use:
-subj "/CN=YourZncNickname"
or
-subj "/CN=FQDN:Port"
Note: Some user could encounter some issue to login via certificate due to random settings/old caching/etc; try to use your ZNC's FQDN:Port instead of YourZncNickname. Thanks to <CryptoSiD> on Freenode for the tip
Certificate generation
The last step is to generate the X.509 certificate using the CSR previously generated. Now you can:
- submit the CSR to a Public CA
- self signing it
Hint: If you are generating the certificate for:
- Client <-> ZNC
znc.pem
: you have to decide based on your scenario- CertAuth module: you can opt for a Self Signed Certificate, but it could be recognized as untrusted
- ZNC <-> Server
- Cert module: you can go directly with a simpler/faster/costless Self Signed Certificate
At the end of the process you will have:
- 1 cert.pem
- 1 cert.info (optional)
- 1 bundle.pem (optional - depending on the Public CA)
Signed vs Self Signed
The only difference between the 2 classes of certificates is the Issuer, the entity that sign the certificate.
Security explanation
By the security point of view, there are no immediate differences between a Signed and a Self Signed (well configured) certificate. They both encrypts the traffic and prevent Man-In-The-Middle attacks. All modern browsers nowadays give red warning if you visit HTTPS site using a Self Signed Certificate, cause it could have been created a second before the connection by an attacker and the browser warns you about "at who you are connecting to", a "not trusted" site. Once you store the certificate and flag it as trusted, the browser will trust that Fingerprint and will consider it as trusted (during its validity period). Once expired, the browser will start to warn you again cause it is an expired Certificate. Once expired the certificate is still cryptographically security valid, but it is considered as security risk. In the past a certificate was valid for periods like 3-5 years. Nowadays a certificate (thanks to the advance of technology) could be renewed even every 30 days. So in the case you set the expiration of a certificate to 1 day, at 2nd day it will still perform its security job, but browser will warn you "Ehy! The certificate is expired! Probably a new one has been released, move to updated it". If you save the Fingerprint of your Self Signed Certificate and will check it when you get the warn (to prevent false positive or strict security settings), is cryptographically the same of a Signed one. All of this is true if the certificate is secure; if it uses unsecure features, both Signed and Self Signed would be unsecure. Example: Certificate signed with SHA-1 hash algorithm; all modern browser warns you about that certificates, even if they are Signed by a Public trusted CA or a self signed one. Don't worry, the commands on this guide use SHA-512 as hash signing algorithm; the current standards use SHA-256, the hash signing algorithm before the SHA-512.
Practical explanation
To sign a certificate a private key is required; the private key is "personal", so it belongs to an "entity". When you create a private key, you are assuring "Im the owner of this key". To share the information on your ownership, you create a Certificate derived from that private key. Now, it is required an third party that signs with his private key your certificate (signing request) saying to the world "This certificate belongs to that person" (that's the basic job of a CA). When you let sign your Certificate by a third global known (trusted) party, a Public CA, you get a so named "Signed Certificate". Thanks to the cryptography world, the world will recognize the Certificate as your own and valid, cause it is signed by a (trusted) Public CA that they recognize. Instead, if you decide to sign by your self, with yourself key, it will become a so called Self signed certificate cause it has been signed by yourself (by itself private key). And Yes and No: Yes, all Public CA are based on a first Self Signed Certificate, but it has been spread globally and trusted so all people recognize it as valide; No, even if you sign the certificate with another private key created by yourself something will change; that because no one knows about your "signing key" and no one will trust it. You are theoretically creating a Private CA (no, you are practically not creating a CA cause it is a bit harder than this) and you are signing it with another key, but the key used to sign is not trusted by the world. That's the main point of a CA, being recognized valid cause signed by a trusted party. You could develop your own private CA, trust it on your machines, and those machines will then recognize its certificates as valid, but this is mainly done on internal networks for personal application services. If you are going to share the ZNC instance, you should share also the entire CA infrastructure with all people... It is so much work when if you need to share the ZNC instance with other people, a simple certificate has totally affordable cost; moreover there are free services like Let's Encrypt that provide SSL Certificate for free. Remember that for the web navigation, the main purpouse of a certificate is to encrypt the traffic; for the "recognized ownership" there are further (paid) levels of certificates.
Signed by Public CA
Signed SSL certificates are recommended when more than one person share the same ZNC instance.
Most of the time they are generated by third-party companies; for this reason you can check the dedicated page Signed_SSL_certificate on the topic.
Note: remember to retrieve the Root and Intermediate certificate of the Public CA you will choose. They could be provided in a single bundle file too.
Self Signed
The strict definition of Self Signed Certificate is:
In cryptography and computer security, a self-signed certificate is a security certificate that is not signed by a certificate authority (CA) - [Source: Wikipedia]
Extending the mindset, the CA is considered Public, so widely distribuited. In that case even a Private CA Signed certificate can be considered as a Self Signed (signed by our own CA - not Public). To do not go out of the scope of this page, we will not consider the scenario of signing the CSR with a Private CA; moreover, if you have a Private CA, you should be able to sign a CSR by your self.
To run the code below you need the selfsigned.cnf file.
Regardless you opted out for an ECC or a RSA algorithms, the commands are the same. In the code below use:
server_cert
if you are generating the certificate for the ZNC (znc.pem
)usr_cert
if you are generating the certificate for modules/SASL/authentications
# Generate the Certificate, selfsigning the CSR openssl req -new -x509 -sha512 -days 365 -key priv.pem -in csr.pem -out cert.pem -config selfsigned.cnf -extensions usr_cert/server_cert # Store information of the certificate openssl x509 -fingerprint -sha512 -serial -hash -text -noout -in cert.pem -out cert.info
DHparam
An additional step is to generate the Diffie-Hellman key exchange parameters. If they will not be generated, ciphers which relay DH can't be used
The Diffie-Hellman key exchange (Wikipedia - OpenSSL) is a method of securely exchanging cryptographic keys.
It has to be append at the end of the znc.pem
.
The dhparam file does not need to be kept secret and can be used multiple times.
Local generation
In the command below, feel free to increase 2048 as you like but be aware that this will take a long time.
# Generate DH parameters openssl dhparam -out dhparam.pem 2048 # Check DH parameters created openssl dhparam -noout -text -check -in dhparam.pem
Online generation
If you want to speed up the generation process you can use the services of [2ton]; they offer freshly generated DHparam files.
You can simply download them (wget or curl) choosing the size you want (2048, 3072,4096,8192):
wget https://2ton.com.au/dhparam/2048 -O dhparam.pem curl https://2ton.com.au/dhparam/2048 -o dhparam.pem
Additional useful commands
PKCS#12
The command below will change the format of the certificate from PEM to PKCS#12.
For example you need this kind of format when you have to interact with browser (Ex. CertAuth module)
openssl pkcs12 -export -nodes -inkey priv.pem -in cert.pem -out znc_user.p12 -password pass:
Fingerprint
Each certificate has its own fingerprint and can be recognized by it. Fingerprints are calculated using HASHes. Allowed hashes are: MD5
,SHA1
,SHA256
,SHA512
.
There are many reasons for which we would like to verify the fingerprint of a certificate:
- to set up the Cert module
- to check if a MITM attack is in progress
- etc
We could retrieve the fingerprint as from a local certificate as from an online one.
Local certificate
# MD5 openssl x509 -md5 -noout -fingerprint -in cert.pem > cert.md5 openssl x509 -md5 -noout -fingerprint -in cert.pem | sed -e 's/^.*=//;s/://g;y/ABCDEF/abcdef/' >> cert.md5 # SHA-1 openssl x509 -sha1 -noout -fingerprint -in cert.pem > cert.sha1 openssl x509 -sha1 -noout -fingerprint -in cert.pem | sed -e 's/^.*=//;s/://g;y/ABCDEF/abcdef/' >> cert.sha1 # sha-256 openssl x509 -sha256 -noout -fingerprint -in cert.pem > cert.sha256 openssl x509 -sha256 -noout -fingerprint -in cert.pem | sed -e 's/^.*=//;s/://g;y/ABCDEF/abcdef/' >> cert.sha256 # SHA-512 openssl x509 -sha512 -noout -fingerprint -in cert.pem > cert.sha512 openssl x509 -sha512 -noout -fingerprint -in cert.pem | sed -e 's/^.*=//;s/://g;y/ABCDEF/abcdef/' >> cert.sha512
If you need the fingerprint just as terminal output remove the redirect > cert.***
.
If you need the fingerprint in the default format, use the commands without | sed -e 's/^.*=//;s/://g;y/ABCDEF/abcdef/'
Note: If you are here from the Cert module, be aware that different IRC networks use different fingerprints; for example Libera.chat uses SHA-512. Consult the network you're connecting to for this information.
Online certificate
# Replace with the hostname/FQDN of your ZNC Server sslhost=znc.example.com # Replace with the SSL port of your ZNC Server sslport=6697 sslcert=$(openssl s_client -showcerts -connect "$sslhost":"$sslport" < /dev/null) echo "$sslcert" | openssl x509 -noout -fingerprint -md5 echo "$sslcert" | openssl x509 -noout -fingerprint -sha1 echo "$sslcert" | openssl x509 -noout -fingerprint -sha256 echo "$sslcert" | openssl x509 -noout -fingerprint -sha512
Glossary
- CA: Certificate Authority or Certification Authority is the entity that issues digital (X.509) certificates
- Certificate: Also known as X.509 certificate, it is used to encrypt and decrypt data relaying on a related public and private key pair.
- CSR: Certificate Signing Request
- DER: Distinguished Encoding Rules is a binary encoding for X.509 certificates and private keys
- DES: Data Encryption Standard is a symmetric-key algorithm for the encryption of digital data. Too insecure for encryption nowadays.
- DSA: Digital Signature Algorithm
- ECC: Elliptic Curve Cryptography algorithms
- FQDN: Fully Qualified Domain Name or Hostname
- MITM: Man-In-The-Middle attack; an attacker acts as proxy sniffing and/or altering the traffic data
- P12: Common file extension for PKCS#12 format
- PEM: Privacy Enhanced Mail is a Base64 encoded ASCII file format
- PFX: Common file extension for PKCS#12 format
- PKCS12: Common file extension for PKCS#12 format
- PKCS#12: Binary format for storing certificate chain and private key in a single: encryptable file
- PKI: Public Key Infrastructures
- Private Key: One of the key pair. It is the one that must be kept secret
- Public Key: One of the key pair. It is the one that can be freely shared
- RSA: Rivest-Shamir-Adleman algorithms
- SSL: Secure Sockets Layer is a cryptographic protocol designed to provide communications security over a computer network