As HAL-9000 once said: "This sort of thing has cropped up before, and it has always been due to human error".I am not sure if the programmer "thought long meant 64-bit because he was on a native 64-bit architecture" or "was unaware of the fact that long long is required to declare a 64-bit variable". This is why the IETF changed the type of that variable to uint64_t (unsigned integer 64-bit) which is now the source of much frustration as new programmers learn the c language.
Overview
sequenceDiagram
participant Client
participant Server
Note over Client,Server: TCP Handshake Completed
Client->>Server: 1. ClientHello (Supported Cipher Suites, Random)
Server->>Client: 2. ServerHello (Selected Cipher Suite, Random)
Server->>Client: 3. Certificate (Server Public Key)
Server->>Client: 4. ServerHelloDone
Note over Client: Validates Certificate
Client->>Server: 5. ClientKeyExchange (Encrypted Premaster Secret)
Client->>Server: 6. ChangeCipherSpec (Switch to Encrypted)
Client->>Server: 7. Finished (Finished Message - Encrypted)
Server->>Client: 8. ChangeCipherSpec (Switch to Encrypted)
Server->>Client: 9. Finished (Finished Message - Encrypted)
Note over Client,Server: Secure Tunnel Established
Client<->>Server: Encrypted Application Data
SSL/TLS cryptography is based upon:
Trusted Third Parties
Nerd Stuff
Western conservatives are continually questioning the value of education (and theoretical research) then implementing austerity measures for the purpose of lowering taxes. [[[ BTW, this seems to happen more often in English-speaking countries; I have never seen my taxes ever go down ]]]. Between 2006 and 2015, Canadian conservatives attempted to defund all theoretical research in Canada claiming that Canada should only concentrate upon applied research. The NRC was partially defunded and scientists receiving any government money were muzzled. Pressure on academia is ten times worse under Donald Trump.
Most politicians would never click this next link which I placed here for all nerds: the modern RSA cryptographic system is based upon Fermat's Little Theorem first published in 1640.
Apps and Tools
| |
usual file locations | notes |
|---|---|---|
| program | /usr/bin/openssl /usr/bin/openssl3 |
the older stuff (eg. openssl-1.1.1k-17) the newer stuff (eg. openssl3-3.5.5-5) |
| config | /etc/pki/tls/openssl.cnf | always make a backup copy of this one |
| certificate(s) | /etc/pki/tls/certs | public certificates live here |
| key(s) | /etc/pki/tls/private | private keys live here |
Like most security software, OpenSSL seems deliberately unfriendly so you must read the official CLI docs
or poke around (er, hack).
Here is the command documentation for OpenSSL-3.5 (use the slider to change version-based help)
Legend (for all my examples): <sr> = system response <ur> = user response <enter> = hit the enter key (in my newer examples this is "assumed") <ctrl-c> = hit "control c" <ctrl-z> = hit "control z" <space> = hit the space bar <tab> = hit the tab key
# = start of comment in BASH (Linux/Unix)
\ = line continuation character in BASH (Linux/Unix)
! = start of comment in DCL (OpenVMS)
- = line continuation character in DCL (OpenVMS)
[prompt} = my shell prompt -------------------------------------------------------- <sr> [prompt] <ur> openssl version
<sr> OpenSSL 3.5.8 25 Aug 2026 (Library: OpenSSL 3.5.8 25 Aug 2026) [prompt]
<ur> openssl help <sr> ...verbiage ensues... [prompt]
================================================= NEW: begins with OpenSSL-1.1.0 (August 2016)
<ur> openssl help list #
<sr> ...verbiage ensues...
[prompt]
<ur> openssl list -standard-commands # was: openssl list-standard-commands
<sr> { displays available commands } #
[prompt] #
<ur> openssl list -message-digest-commands # was: openssl list-message-digest-commands
<sr> { displays available digests } #
[prompt] #
<ur> openssl list -cipher-commands # was: openssl list-cipher-commands
<sr> { display available ciphers } #
[prompt] #
================================================= common
<ur> openssl no-rsa # is rsa available?
<sr> rsa # yes, rsa is available
[prompt] #
<ur> openssl help rsa # NEW: display rsa specific help
...verbiage ensues... #
[prompt] #
<ur> openssl no-dsa # is dsa available?
<sr> dsa # yes, dsa is available
[prompt] #
<ur> openssl help dsa # NEW: display dsa specific help
...verbiage ensues... #
[prompt] #
<ur> openssl no-ec # is ec (elliptic key cryptography) available?
<sr> ec # yes, ec is available
[prompt] #
<ur> openssl help ec # NEW: display ec specific help
...verbiage ensues... #
[prompt] #
<ur> openssl no-whatever # is whatever available?
<sr> no-whatever # no, whatever us not available
[prompt] #
<ur> openssl list -cipher-commands # new commands
<sr> aes-128-cbc aes-128-ecb aes-192-cbc aes-192-ecb ...
des-ede3-ofb des3
[prompt]
<ur> openssl help ciphers
<sr> ...verbiage ensues...
[prompt]
<ur> openssl ciphers -tls1_3 #
<su> ...verbiage ensures...
[prompt]
================================================ old commands (museum ware)
<ur> openssl ciphers -? # <sr> usage: ciphers args -v - verbose mode, a textual listing of the SSL/TLS ciphers in OpenSSL -V - even more verbose (OpenVMS users enter -"V" to preserve case) -ssl2 - SSL2 mode -ssl3 - SSL3 mode -tls1 - TLS1 mode [prompt]
<ur> openssl ciphers -ssl2 # display available ssl2 ciphers <sr> ...verbiage ensues... # might be an error message in 2014 [prompt] #
<ur> openssl ciphers -ssl3 # display available ssl3 ciphers <sr> ...verbiage ensues... # might be an error message in 2020 [prompt] #
<ur> openssl ciphers -tls1 # display available tls1 ciphers <sr> ...verbiage ensues... # [prompt] #
================================================= common <ur> openssl ciphers -v # display all available ciphers <sr> ...verbiage ensues... # 100 lines is typical [prompt] #
<ur> openssl ciphers -v | grep -i SSL # display SSL stuff <sr> ...verbiage ensues... # 60 lines is typical [prompt] #
<ur> openssl ciphers -v | grep -i TLS # display TLS-related stuff <sr> ...verbiage ensues... # 60 lines is typical [prompt] #
1) This content of this section is more of an academic/pedagogical nature 2) Click skip this section if you are in a hurry to solve a connectivity problem
3) The following examples manipulate files rather than data streams but you will get the general idea 4) Anything typed into the OpenSSL CLI can also be called from the OpenSSL C-API
exercise-01 "encrypt with base64" =================================
<ur> echo "These are the voyages of the starship Enterprise" > hack1a.txt # use BASH to insert text into a file
<sr> [prompt] #
<ur> cat hack1a.txt # use BASH to test the file
<sr> These are the voyages of the starship Enterprise [prompt] #
<ur> openssl help enc #
<sr> ...verbiage ensues...
<ur> openssl enc -base64 -in hack1a.txt # encrypt using base64 (output to screen) <sr> VGhlc2UgYXJlIHRoZSB2b3lhZ2VzIG9mIHRoZSBzdGFyc2hpcCBFbnRlcnByaXNl Cg== [prompt] #
<ur> openssl enc -base64 -in hack1a.txt -out hack1b.txt # encrypt using base64 (output to file) <sr> [prompt] # no news is good news :-)
<ur> openssl enc -base64 -d -in hack1b.txt # now decrypt the file <sr> These are the voyages of the starship Enterprise # success... [prompt] # Notes: 1) While "base64" is listed as a cipher (in older versions of openssl), it is not a form of secret encryption
since it does not support the use of a secret key. But it does prove that this part of the CLI is working
properly when "base64" is treated as a module. 2) OLDER VERSIONS: type "openssl list-cipher-commands" to see a list of ciphers offered by your installed product. Notice that the listing does include "base64" 3) NEWER VERSIONS: type "openssl ciphers -v" to see a list of ciphers offered by your installed product. However, may find this command more practical "openssl enc -ciphers" Notice that the listing does NOT include "base64" which is why you need the newer command switch "-base64" 4) One of the ciphers is "des3" which we will use in the next exercise 5) Newer versions of OpenSSL also include "base64" as a command to use in place of "enc -base64"
Type "openssl help base64" for details.
exercise-02 "encrypt with des3" =============================== <ur> echo "To boldly go where no man has gone before" > hack2a.txt # use BASH to insert text into a file <sr> [prompt] #
<ur> cat hack2a.txt # use BASH to check the file
<sr> To boldly go where no man has gone before #
[prompt] #
<ur> openssl help enc
<sr> ...verbiage ensues...
[prompt]
<ur> openssl enc -des3 -in hack2a.txt -out hack2b.bin # encrypt file using des3 (output to file) <sr> enter des-ede3-cbc encryption password: # prompting for a mandatory KEY <ur> secret789<enter> # you will be typing this blind (no echo) <sr> Verifying - enter des-ede3-cbc encryption password: # prompting for KEY verification <ur> secret789<enter> # you will be typing this blind (no echo) <sr> [prompt] # no news is good news :-)
<ur> hexdump -C hack2b.bin # more hacking (see note #4 below) <sr> 00000000 53 61 6c 74 65 64 5f 5f 37 50 2d 64 5c bd 8b da |Salted__7P-d\...| 00000010 b7 74 bb bd 75 01 49 f5 b9 10 13 db fa 22 85 15 |.t..u.I......"..| 00000020 1f 1f 25 94 08 23 d1 cb 2f d1 18 d8 7b 36 10 6c |..%..#../...{6.l| 00000030 9a de 91 d3 f6 7f b2 d5 46 3b 5e 7b 49 c1 29 ae |........F;^{I.).| 00000040 [prompt] #
<ur> openssl enc -des3 -d -in hack2b.bin # decrypt message file (out to screen) <sr> enter des-ede3-cbc decryption password: # <ur> secret789<enter> # you will be typing this blind (no echo) <sr> To boldly go where no man has gone before # yay! [prompt]
<ur> openssl enc -des3 -d -in hack2b.bin -k secret789 # decrypt without prompting <sr> To boldly go where no man has gone before [prompt] #
<ur> openssl enc -des3 -d -in hack2b.bin -k "secret789" # double quotes work as well <sr> To boldly go where no man has gone before [prompt] #
<ur> echo "secret789" > hack2c.txt # insert pass-phrase into file <sr> [prompt] #
<ur> openssl enc -des3 -d -in hack2b.bin -pass file:hack2c.txt # decrypt (password from file) <sr> To boldly go where no man has gone before [prompt] #
<ur> openssl enc -des3 -d -in hack2b.bin -pass pass:secret789 # decrypt (inline password) <sr> To boldly go where no man has gone before [prompt] # Notes: 1) the "encryption password" is really a KEY which is used to both encrypt and decrypt 2) be very careful when you enter the pass phrase because some hidden characters (like <tab> and <space>) are processed as-is; for example, the following legal inputs produce different results a) secret789<space><enter> b) secret789<space><space><enter> c) <space>secret789<space><enter> d) <tab>secret789<space><enter>
e) secret789<enter>
f) <enter> 3) if you enter any double-quote characters at the interactive passphrase prompt they will be used to
encrypt but it will be impossible to decrypt using the -k option which first strips quotes before
processing
4) Notice the embedded phrase "Salted__" which is always present. Salt (randomized 64-bit data stored
in the file) is combined with pepper (data not stored in the file (the pass phrase)) to cause every
encryption of the same data to produce different results. This used to stop dictionary hacks. Try it
yourself. Every time you type "openssl enc -des3" you will produce a different result. Now go back
and store just a lower case 'a' as plain text then use a lower case 'a' as the pass phrase. The
result will always contain 24-bytes.
5) Note: SALT is really a combination of the IV (Initialization Vector) and the key which is generated from the passphrase
*** And Now For a Little Theory *** RSA Notes:
0) https://en.wikipedia.org/wiki/RSA_(cryptosystem) 1) RSA encryption/decryption is asymmetric and so requires two keys (one public, one private). 2) RSA keys are based upon upon the product of two carefully chosen prime numbers.
3) the private key is one of the primes.
4) The public key is the product of two primes.
5) during the initial handshake, the public key is passed in full view of the public (obviously).
(usually by reading the server's OpenSSL certificate)
6) the client will use the server's public key to encrypt a message before transmission
7) the server will use the server's private key to decrypt the received encrypted message 8) Optional security: during the handshake, the server may ask the client to send a client public key.
The client will send it's client certificate (usually a user generated certificate) to the server.
The server will use the client's public key to send encrypted responses back to the client.
The client will use the client's private key to decrypt received responses.
This second scheme is known as digital signing.
CAVEAT: just to be clear, using the client's public and private keys to encrypt is done in addition
to using the server's public and private keys. The message is doubly encrypted.
RSA Data: d = private key n = public key e = 65537 (constant with RSA) c = m^e mod n (formula for cipher text)
m = c^d mod n (formula for message text)
exercise-03 "create a new 32-bit private key file" ================================================== Notes:
(1) 32 bits is too small for a certificate but (was) okay for this demo on primes
(2) on newer systems you may not use a key size lower than 512 bits (this limit will eventually increase)
(3) CAVEAT: confusingly, this private key file contains both "a 16-bit private key" AND "a 32-bit public key" <sr> [prompt] # my BASH prompt <ur> openssl genrsa -out hack3a.key 32 # create a 32-bit public key <sr> Generating RSA private key, 32 bit long modulus .+++++++++++++++++++++++++++ .+++++++++++++++++++++++++++ e is 65537 (0x10001) [prompt]
<sr> cat hack3a.key
<ur> -----BEGIN PRIVATE KEY----- MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAtJsdkqviXEtOq997
...verbiage... BKaYCWHXezMAYLmDcJb3Sv47cfjBKQIgcQ8gAMaXvYb6D19m72Lefzyd9Sb7L9XU G5IKhoYJcFk= -----END PRIVATE KEY-----
<ur> openssl rsa -in hack3a.key -text -noout # interpret the key file <sr> Private-Key: (32 bit) # private key file holds a 32-bit public key modulus: 4057358269 (0xf1d65fbd) # this is the 32-bit public key publicExponent: 65537 (0x10001) # same every time privateExponent: 1322158157 (0x4ece884d) prime1: 65123 (0xfe63) # 16-bit prime1 (changes every genrsa) prime2: 62303 (0xf35f) # 16-bit prime2 (changes every genrsa) exponent1: 51313 (0xc871) exponent2: 47415 (0xb937) coefficient: 60666 (0xecfa) [prompt] Notes:
calc: 65123 x 62303 = 4057358269 # public key (product of two primes)
[[[ display only the public key portion ]]]
<ur> openssl pkey -in hack3a.key -outform PEM -pubout # alias: openssl rsa -in hack3a.key -outform PEM -pubout
<sr> -----BEGIN PUBLIC KEY-----
...verbiage... -----END PUBLIC KEY-----
[prompt]
exercise-04 "create a new 512-bit private key file" ===================================================
Notes:
(1) 512 bits is too small for a certificate but is okay for this demo on primes
(2) A certificate publisher will not allow to to use anything smaller that 2048 bits. (this limit will eventually increase)
(3) CAVEAT: confusingly, this private key file contains both "a 256-bit private key" AND "a 512-bit public key"
<sr> [prompt] # my BASH prompt <ur> openssl genrsa -verbose -out hack4a.key 512 # 512 bits just for this demo <sr> Generating RSA private key, 512 bit long modulus ......++++++++++++ .....++++++++++++ e is 65537 (0x10001) [prompt]
<ur> cat hack4a.key # view raw ASCII data <sr> -----BEGIN PRIVATE KEY----- MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAvSPIB+9mim3FQ3T3 Uhlmf19btGEXrDLICER+hQE5ZwpsIBCi8MVKGYJtUqkJjLW6LnjRrlce79Gq3Jy0 qqYAnQIDAQABAkArFQtrQ0zIG1jjlLEBMmf2e3IYFEWgI7EMsQ1gnnbE0Wawaep9 UGnTM4ko2VqaVC0qMdr08oOG/7tNXo+7w+rBAiEA3Wr0YpnrM6jZGjNliN0Fbiqw kEHFxJjmtXxK9qKtjyMCIQDarj2KBkU/z156+EISUiUOTm5xmVXw0CO3ak1m39kN PwIgVSz+xCuH0kCi+7RH2+WCYEXl1CipJp7XKXud7tDXyVcCIQCLplHuXurCQS9Y 4ElxYbwAUt389asISiNE8kHTvIfkCQIgGPZ1NpJz7Me5tw3K/c+jP2uh0PN1Fx3s k7R4rqPqC/0= -----END PRIVATE KEY----- [prompt]
<ur> openssl rsa -in hack4a.key -text -noout # interpret the key file <sr> Private-Key: (512 bit, 2 primes) modulus: # this is our 512-bit public key 00:bd:23:c8:07:ef:66:8a:6d:c5:43:74:f7:52:19: # "00:" is just for padding 66:7f:5f:5b:b4:61:17:ac:32:c8:08:44:7e:85:01: 39:67:0a:6c:20:10:a2:f0:c5:4a:19:82:6d:52:a9: 09:8c:b5:ba:2e:78:d1:ae:57:1e:ef:d1:aa:dc:9c: b4:aa:a6:00:9d # 64 x 8 = 512 bits publicExponent: 65537 (0x10001) privateExponent: 2b:15:0b:6b:43:4c:c8:1b:58:e3:94:b1:01:32:67: f6:7b:72:18:14:45:a0:23:b1:0c:b1:0d:60:9e:76: c4:d1:66:b0:69:ea:7d:50:69:d3:33:89:28:d9:5a: 9a:54:2d:2a:31:da:f4:f2:83:86:ff:bb:4d:5e:8f: bb:c3:ea:c1 prime1: 00:dd:6a:f4:62:99:eb:33:a8:d9:1a:33:65:88:dd: # "00:" is just for padding 05:6e:2a:b0:90:41:c5:c4:98:e6:b5:7c:4a:f6:a2: ad:8f:23 # 32 x 8 = 256 bits prime2: 00:da:ae:3d:8a:06:45:3f:cf:5e:7a:f8:42:12:52: # "00:" is just for padding 25:0e:4e:6e:71:99:55:f0:d0:23:b7:6a:4d:66:df: d9:0d:3f # 32 x 8 = 256 bits exponent1: 55:2c:fe:c4:2b:87:d2:40:a2:fb:b4:47:db:e5:82: 60:45:e5:d4:28:a9:26:9e:d7:29:7b:9d:ee:d0:d7: c9:57 exponent2: 00:8b:a6:51:ee:5e:ea:c2:41:2f:58:e0:49:71:61: bc:00:52:dd:fc:f5:ab:08:4a:23:44:f2:41:d3:bc: 87:e4:09 coefficient: 18:f6:75:36:92:73:ec:c7:b9:b7:0d:ca:fd:cf:a3: 3f:6b:a1:d0:f3:75:17:1d:ec:93:b4:78:ae:a3:ea: 0b:fd
[prompt]
Notes: prime1 x prime2 = modulus [[[ verified with python3 (see code just below) ]]]
[[[ display only the public key portion ]]]
<ur> openssl pkey -in hack4a.key -pubout
<sr> -----BEGIN PUBLIC KEY----- MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAL0jyAfvZoptxUN091IZZn9fW7RhF6wy yAhEfoUBOWcKbCAQovDFShmCbVKpCYy1ui540a5XHu/RqtyctKqmAJ0CAwEAAQ== -----END PUBLIC KEY-----
=====================================================================================
[[[ python code ]]]
#!/usr/bin/python3 # =============================================== # title : hexhack.py # author : Neil Rieck # created: 2026-10-30 # command: ./hexhack.py # purpose: show that 2 primes yield a public key # =============================================== def hexToInt(h): h = h.replace(":", "") i = int(h, 16) return i def main(): hex1 = ("00:dd:6a:f4:62:99:eb:33:a8:d9:1a:33:65:88:dd:" "05:6e:2a:b0:90:41:c5:c4:98:e6:b5:7c:4a:f6:a2:" "ad:8f:23") hex1 int1 = hexToInt(hex1) print(f"1: {int1}") hex2 = ("00:da:ae:3d:8a:06:45:3f:cf:5e:7a:f8:42:12:52:" "25:0e:4e:6e:71:99:55:f0:d0:23:b7:6a:4d:66:df:" "d9:0d:3f") int2 = hexToInt(hex2) print(f"2: {int2}") hex3 = ("00:bd:23:c8:07:ef:66:8a:6d:c5:43:74:f7:52:19:" "66:7f:5f:5b:b4:61:17:ac:32:c8:08:44:7e:85:01:" "39:67:0a:6c:20:10:a2:f0:c5:4a:19:82:6d:52:a9:" "09:8c:b5:ba:2e:78:d1:ae:57:1e:ef:d1:aa:dc:9c:" "b4:aa:a6:00:9d") int3 = hexToInt(hex3) print(f"3: {int3}") int9 = int1 * int2 print(f"T: {int1 * int2}") if int3 == int9: print("-i-public key matches computation") else: print("-e-public key does not match computation") print("adios.") # # catch-all # if __name__ == '__main__': main() #
[[[ test tun ]]]
$ ./hexhack.py 1: 100150112010161307879515856121031132306698659122001444898818934850356408848163 2: 98912057108083667072310118792931755799161095298663828215802679204755615059263 3: 9906053598530051227934063406761483703202138091076134197773187892479644785078437429264959035844067388603060925849342642737264890185245627610728542813683869 T: 9906053598530051227934063406761483703202138091076134197773187892479644785078437429264959035844067388603060925849342642737264890185245627610728542813683869 -i-public key matches computation adios. $
exercise-05 "create a CSR (certificate signing request)" ======================================================== notes: 1) use the 512-bit key file created in exercise-04 2) copy/use of file openssl.cnf is optional
<sr> [prompt] # my BASH prompt <ur> cp /etc/pki/tls/openssl.cnf openssl.cnf # copy template (OPTIONAL) <sr> [prompt]
<ur> openssl req \
-new \
-key hack4a.key \
-out hack5b.csr \
-config openssl.cnf # OPTIONAL <sr> You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [XX]:CA # my responses are in red State or Province Name (full name) []:Ontario # Locality Name (eg, city) [Default City]:Waterloo # Organization Name (eg, company) []:Neil Rieck # I am not a business Organizational Unit Name (eg, section) []:Neil Rieck # Common Name (eg, YOUR name) [server]:neilrieck.net # Email Address []:n.rieck@bell.net Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []:<enter> An optional company name []:<enter> [prompt] <ur> cat hack5b.csr # view raw CSR data <sr> -----BEGIN CERTIFICATE REQUEST----- MIIBdDCCAR4CAQAwgbgxCzAJBgNVBAYTAkNBMRAwDgYDVQQIEwdPbnRhcmlvMREw DwYDVQQHEwhXYXRlcmxvbzElMCMGA1UEChMcVW5pdGVkIEZlZGVyYXRpb24gb2Yg UGxhbmV0czETMBEGA1UECxMKU3RhciBGbGVldDEZMBcGA1UEAxMQSmVhbi1MdWMg UGlja2FyZDEtMCsGCSqGSIb3DQEJARYeamVhbi1sdWMucGljYXJkQHN0YXItZmxl ZXQudWZwMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKIwjuJiJJalNN6uQYW+JAn2 6uipqT8/VvDNIGhqJDxrI2wMj5sNcWn5MmQsZFdl/pxioQvlsdFb8Idk1ZsLc9kC AwEAAaAAMA0GCSqGSIb3DQEBBQUAA0EAILOaqUUSsb0vgTyXqUKsBi12mgSbsLgu rZEEyu0gSsTdVIkkwkVvhavYpxCENbCqiRxH+uHZLkYvbTTfmvUapA== -----END CERTIFICATE REQUEST----- [prompt]
<ur> openssl req -noout -text -in hack5b.csr # view interpreted CSR data <sr> Certificate Request: Data: Version: 0 (0x0) Subject:Subject: C=CA, ST=Ontario, L=Waterloo, O=Neil Rieck, OU=Neil Rieck, CN=neilrieck.net/emailAddress=n.rieck@bell.net Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (512 bit) Modulus (512 bit): # public key 00:a2:30:8e:e2:62:24:96:a5:34:de:ae:41:85:be: # "00:" is just padding 24:09:f6:ea:e8:a9:a9:3f:3f:56:f0:cd:20:68:6a: 24:3c:6b:23:6c:0c:8f:9b:0d:71:69:f9:32:64:2c: 64:57:65:fe:9c:62:a1:0b:e5:b1:d1:5b:f0:87:64: d5:9b:0b:73:d9 # 64 x 8 = 512 bits Exponent: 65537 (0x10001) Attributes: a0:00 Signature Algorithm: sha1WithRSAEncryption 20:b3:9a:a9:45:12:b1:bd:2f:81:3c:97:a9:42:ac:06:2d:76: 9a:04:9b:b0:b8:2e:ad:91:04:ca:ed:20:4a:c4:dd:54:89:24: c2:45:6f:85:ab:d8:a7:10:84:35:b0:aa:89:1c:47:fa:e1:d9: 2e:46:2f:6d:34:df:9a:f5:1a:a4 [prompt]
exercise-06 "create a self-signed certificate" caveat: modern browsers reject these BUT can be used to test the OpenSSL CLI client ===================================================================================
notes: 1) use of file "openssl.cnf" is OPTIONAL
2) x509 indicates "self signed"
<sr> [prompt] <ur> openssl req \ -new \ -x509 \ -days 365 \ -set_serial 20160101 \ -key hack4a.key \ -out hack6b.crt \
-config openssl.cnf <sr> You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:CA # my responses in RED (CA=Canada) State or Province Name (full name) []:Ontario # Canada has provinces Locality Name (eg, city) [Default City]:Waterloo Organization Name (eg, company) []:Neil Rieck # I am not a business Organizational Unit Name (eg, section) []:Neil Rieck Common Name (eg, YOUR name) [server]:neilrieck.net # Email Address []:n.rieck@bell.net # [prompt] <ur> openssl x509 -in hack6b.crt -text -noout # let's see it (processed) <sr> Certificate: Data: Version: 3 (0x2) Serial Number: 20160101 (0x1339e65) Signature Algorithm: sha1WithRSAEncryption Issuer: C=CA, ST=Ontario, L=Waterloo, O=Neil Rieck, OU=Neil Rieck, CN=neilrieck.net/emailAddress=n.rieck@bell.net Validity Not Before: Jan 1 21:06:15 2016 GMT Not After : Dec 31 21:06:15 2016 GMT Subject: C=CA, ST=Ontario, L=Waterloo, O=Neil Rieck, OU=Neil Rieck, CN=neilrieck.net/emailAddress=n.rieck@bell.net Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public Key: (512 bit) Modulus (512 bit): 00:a2:30:8e:e2:62:24:96:a5:34:de:ae:41:85:be: 24:09:f6:ea:e8:a9:a9:3f:3f:56:f0:cd:20:68:6a: 24:3c:6b:23:6c:0c:8f:9b:0d:71:69:f9:32:64:2c: 64:57:65:fe:9c:62:a1:0b:e5:b1:d1:5b:f0:87:64: d5:9b:0b:73:d9 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Subject Key Identifier: 83:79:4A:B8:D5:ED:C4:C5:58:A8:4B:0F:07:E6:8B:FB:A3:22:19:9C X509v3 Authority Key Identifier: keyid:83:79:4A:B8:D5:ED:C4:C5:58:A8:4B:0F:07:E6:8B:FB:A3:22:19:9C DirName:/C=CA/ST=Ontario/L=Waterloo /O=United Federation of Planets /OU=Star Fleet /CN=neilrieck.net/emailAddress=n.rieck@bell.net serial:01:33:9E:65 X509v3 Basic Constraints: CA:TRUE Signature Algorithm: sha1WithRSAEncryption 08:36:67:15:01:c4:8c:e6:2d:10:de:ed:bb:13:4f:cb:9d:4f: 9a:c9:8b:61:ee:84:16:e8:9b:0f:db:a5:05:c7:d5:94:e6:9b: b1:0f:40:d5:bc:be:09:75:5e:7a:33:46:f7:3a:4c:c2:8b:61: c2:85:ad:a0:f2:cf:00:d2:e1:0d [prompt] <ur> cat hack6b.crt # let's see it (raw) <sr> <...hex dump...> #
exercise-7 "certificates: compound operations, private companies AND development platforms" ===========================================================================================
Note: a private CA (certificate authority) is sometimes required for development platdforms operations: 1) create your own CA (certificate authority) key 2) create your own CA (certificate authority) certificate with v3 extensions 3) create your own CSR (certificate signing request) with v3 extensions 4) use your own CA certificate to sign the CSR with v3 extensions ===================================================================== coming soon (it works on my server) -or- follow the steps documented here: https://www.feistyduck.com/library/openssl-cookbook/ Starts on page 39 of the free PDF
exercise-8 "generate an EC key" CAVEAT: as with RSA, this private key file actually contains both private and public keys ======================================== <ur> openssl help ec # show help <sr> ...verbiage ensues... [prompt] <ur> openssl ecparam -list_curves # show available curves <sr> ...verbiage ensues... [prompt] ======================================== generate a new private-public pair (method-1) <ur> openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:prime256v1 -out ec_private.pem <sr> [prompt]
======================================== generate a new private-public pair (method-2)
<ur> openssl ecparam -name prime256v1 -genkey -out ec_private.pem
<sr> [prompt] ======================================== look inside private file <ur> openssl ec -in ec_private.pem -text <sr> read EC key Private-Key: (256 bit) priv: b6:28:6d:69:65:24:fa:45:04:e9:c0:3e:43:90:ed: 9a:a9:71:91:00:67:6b:a4:b6:1a:25:34:a0:fb:1d: ce:d8 pub: 04:fa:71:89:42:dd:ef:b2:1a:f5:40:04:52:ca:0e: 85:ef:4e:93:a5:2e:63:79:80:c7:9a:31:b5:34:0c: 06:16:d2:a0:62:24:88:f5:1e:33:4e:ec:af:ad:a1: ea:07:1a:90:8f:d1:b9:aa:1e:75:62:8c:83:99:42: d4:b7:be:04:55 ASN1 OID: prime256v1 NIST CURVE: P-256 writing EC key -----BEGIN EC PRIVATE KEY----- MHcCAQEEILYobWllJPpFBOnAPkOQ7ZqpcZEAZ2uktholNKD7Hc7YoAoGCCqGSM49 AwEHoUQDQgAE+nGJQt3vshr1QARSyg6F706TpS5jeYDHmjG1NAwGFtKgYiSI9R4z TuyvraHqBxqQj9G5qh51YoyDmULUt74EVQ== -----END EC PRIVATE KEY----- [prompt] ======================================== extract public key <ur> openssl ec -in ec_private.pem -pubout -out ec_public.pem <sr> [prompt] ######################################################################## EC Cheat Sheet: ============== # show available curves openssl ecparam -list_curves # generate a new private key file for a curve
# method-1:
openssl ecparam -name prime256v1 -genkey -out private-key.pem
# method-2:
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:prime256v1 -out private-key.pem # extract the corresponding public key openssl ec -in private-key.pem -pubout -out public-key.pem # optional: create a self-signed certificate openssl req -new -x509 -key private-key.pem -out cert.pem -days 360 # optional: convert pem to pfx openssl pkcs12 -export -inkey private-key.pem -in cert.pem -out cert.pfx ####################################################################### Digging Deeper (for math nerds) ============== <ur> openssl ecparam -out ec_param.pem -name prime256v1 -param_enc explicit <sr> [prompt] <ur> openssl ecparam -in ec_param.pem -text <sr> EC-Parameters: (256 bit) Field Type: prime-field Prime: 00:ff:ff:ff:ff:00:00:00:01:00:00:00:00:00:00: 00:00:00:00:00:00:ff:ff:ff:ff:ff:ff:ff:ff:ff: ff:ff:ff A: 00:ff:ff:ff:ff:00:00:00:01:00:00:00:00:00:00: 00:00:00:00:00:00:ff:ff:ff:ff:ff:ff:ff:ff:ff: ff:ff:fc B: 5a:c6:35:d8:aa:3a:93:e7:b3:eb:bd:55:76:98:86: bc:65:1d:06:b0:cc:53:b0:f6:3b:ce:3c:3e:27:d2: 60:4b Generator (uncompressed): 04:6b:17:d1:f2:e1:2c:42:47:f8:bc:e6:e5:63:a4: 40:f2:77:03:7d:81:2d:eb:33:a0:f4:a1:39:45:d8: 98:c2:96:4f:e3:42:e2:fe:1a:7f:9b:8e:e7:eb:4a: 7c:0f:9e:16:2b:ce:33:57:6b:31:5e:ce:cb:b6:40: 68:37:bf:51:f5 Order: 00:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:ff:ff: ff:ff:bc:e6:fa:ad:a7:17:9e:84:f3:b9:ca:c2:fc: 63:25:51 Cofactor: 1 (0x1) Seed: c4:9d:36:08:86:e7:04:93:6a:66:78:e1:13:9d:26: b7:81:9f:7e:90 -----BEGIN EC PARAMETERS----- MIH3AgEBMCwGByqGSM49AQECIQD/////AAAAAQAAAAAAAAAAAAAAAP////////// /////zBbBCD/////AAAAAQAAAAAAAAAAAAAAAP///////////////AQgWsY12Ko6 k+ez671VdpiGvGUdBrDMU7D2O848PifSYEsDFQDEnTYIhucEk2pmeOETnSa3gZ9+ kARBBGsX0fLhLEJH+Lzm5WOkQPJ3A32BLeszoPShOUXYmMKWT+NC4v4af5uO5+tK fA+eFivOM1drMV7Oy7ZAaDe/UfUCIQD/////AAAAAP//////////vOb6racXnoTz ucrC/GMlUQIBAQ== -----END EC PARAMETERS----- [prompt]
Notes:
========================================================================= NEW: begins with OpenSSL-1.1.0 (August 2016)
<sr> [prompt] #
<ur> openssl help s_client #
...verbiage ensues... #
[prompt] # my BASH prompt
======================================================================== common <ur> openssl s_client -connect www.twitter.com:443 -tls1 -crlf # connect to Twitter
# <sr> ...handshake verbiage... # bla...bla...bla... --- # your s_client prompt <ur> GET / HTTP/1.0<enter> # get default document; use HTTP 1.0
host: www.twitter.com:443<enter> # the host line was optional with HTTP/1.0 but is now required <enter> # signal end of HTTP header <sr> HTTP/1.0 200 OK # response Date: Fri, 22 Jun 2012 23:16:38 GMT # Status: 200 OK # Pragma: no-cache # Content-Type: text/html; charset=UTF-8 #
Connecting to Google USA (non-USA sites may be redirected)
<sr> [prompt] # <ur> openssl s_client -connect www.google.com:443 -tls1 -crlf # connect to Google USA
# <sr> ...handshake verbiage... # bla...bla...bla... --- # your s_client prompt <ur> GET / HTTP/1.0<enter> # get default document; use HTTP 1.0
host: www.google.com:443<enter> # the host line was optional with HTTP/1.0 but is now required <enter> # signal end of HTTP header <sr> HTTP/1.0 302 Found # 302 = moved Location: https://www.google.ca/ # so redirect to Canada Cache-Control: private Content-Type: text/html; charset=UTF-8 Set-Cookie: expires=; expires=Mon, 01-Jan-1990 00:00:00 GMT; path=/; domain=www.google.com
Connecting to Google Canada (non-Canadian sites will be redirected)
<sr> [prompt] # <ur> openssl s_client -connect www.google.ca:443 -tls1 - crlf # connect to Google Canada
# ...handshake verbiage... # bla...bla...bla... --- # your s_client prompt <ur> GET / HTTP/1.1<enter> # okay so let's try HTTP/1.1 host: www.google.ca:443<enter> # a desired host is needed for use with HTTP/1.1 <enter> # signal end of HTTP header <sr> HTTP/1.1 200 OK # Set-Cookie: NID=61=H7WfG9OQ6uHDvVU8OJyt_Z4x8a4cj0DUpLUfH9D9eeKVou1FwaP8ok16 vDlgV3sX1JPzrd3G8tNc3mDgbdPZy8mGnmpKJ3WCKHVT6gbCV8Z56rKIVgXokgJkptJZ-i00; expires=Sat, 22-Dec-2012 22:51:17 GMT; path=/; domain=.google.ca; HttpOnly Date: Fri, 22 Jun 2012 22:51:17 GMT Expires: -1 Cache-Control: private, max-age=0 Content-Type: text/html; charset=windows-1252 Set-Cookie: PREF=ID=3ba285f540771657:FF=0:TM=1340405477:LM=1340405477:S=TpABG903GxV7Ufhg; expires=Sun, 22-Jun-2014 22:51:17 GMT; path=/; domain=.google.ca Set-Cookie: NID=61=H7WfG9OQ6uHDvVU8OJyt_Z4x8a4cj0DUpLUfH9D9eeKVou1FwaP8ok16vDlgV3sX1JPzrd 3G8tNc3mDgbdPZy8mGnmpKJ3WCKHVT6gbCV8Z56rKIVgXokgJkptJZ-i00; expires=Sat, 22-Dec-2012 22:51:17 GMT; path=/; domain=.google.ca; HttpOnly P3P: CP="This is not a P3P policy! See http://www.google.com/support/accounts /bin/answer.py?hl=en&answer=151657 for more info." Server: gws X-XSS-Protection: 1; mode=block X-Frame-Options: SAMEORIGIN Transfer-Encoding: chunked 1000 # byte count of chunked data block [...snip...]
Three connect commands (responses not shown)
<ur> openssl s_client -connect 142.180.221.226:443 -h # get help (only with OpenSSL-3) ------------------------------------------------------------------------
<ur> openssl s_client -connect 142.180.221.226:443 -msg # show the protocol handshake
<ur> openssl s_client -connect 142.180.221.226:443 -showcerts # what far-end certificates are available? <ur> openssl s_client -connect 142.180.221.226:443 -debug # show more info hex and ASCII <ur> openssl s_client -connect 142.180.221.226:443 -state # show ssl state transitions Note: after anyone of the above commands, type the following: <ur> GET / HTTP/1.0<enter> # get default document using HTTP/1.0 <enter> # signal end of HTTP header
# if this fails with "400 Bad Request" then try the connect command with optional switch: -crlf
Four connect commands (responses not shown)
click: quick steps for a series of complete steps near the bottom of this page
for optional client verification (where client=user)
<ur> openssl s_client -connect 142.180.221.226:443 \ -cert client.crt \ -key client.key <enter> <ur> openssl s_client -connect 142.180.221.226:443 \ -cert client.pem <enter> # key + crt (both inside of pem file)
for optional client verification (where client=your system) <ur> openssl s_client -connect 142.180.221.226:443 \ -cert /etc/pki/tls/certs/server.crt \ -key /etc/pki/tls/private/server.key \ -tls1 <enter> # only use TLS1 encryption Note: after anyone of the above commands, type the following: <ur> GET / HTTP/1.0<enter> # get default document using HTTP/1.0 <enter> # signal end of HTTP header
# if this did not work, then restart the whole command with the optional "-crlf" switch
Five connect commands (responses not shown)
<ur> openssl s_client -connect 142.180.39.15:5555 -debug # details while negotiating <ur> openssl s_client -connect 142.180.39.15:5555 -state # watch SSL change states <ur> openssl s_client -connect 142.180.39.15:5555 -tls1 -debug # use the TLS1 protocol <ur> openssl s_client -connect 142.180.39.15:5555 -ssl3 -debug # use the SSL3 protocol <ur> openssl s_client -connect 142.180.39.15:5555 # \ -cert client/client.pem # PEM files require a HASH file \ -CAfile client/client_ca.pem # list of trusted certificates \ -CApath client #
A simple web server (cannot serve up a file)
Server: <ur> openssl s_server -accept 4433 \ -cert /etc/pki/tls/certs/server.crt \ -key /etc/pki/tls/private/server.key \
-CAfile /etc/pki/tls/certs/chain.crt \ -debug \ -www # barely simulate a webserver (lower case) <sr> Using default temp DH parameters Using default temp ECDH parameters ACCEPT Client: <ur> openssl s_client -connect 142.180.39.15:4433 -debug # will connect to server <sr> ...handshake verbiage... # bla...bla...bla... <ur> GET / HTTP/1.0<enter> # request default page containing stats <enter> # signal end of HTTP header
A web server (can serve up a file)
Server: <ur> cd # run these tests from your home directory <sr> [prompt] #
<ur> echo "this is sample text" > neil.txt <enter> # create a small text file <sr> [prompt] #
<ur> openssl s_server -accept 4433 \ -cert /etc/pki/tls/certs/server.crt \ -key /etc/pki/tls/private/server.key \
-CAfile /etc/pki/tls/certs/chain.crt \ -debug \ -WWW <enter> # simulate a better webserver (upper case) <sr> Using default temp DH parameters Using default temp ECDH parameters ACCEPT Client: <ur> openssl s_client -connect 142.180.39.15:4433 \ -cert vms_cert_dir/client.crt \ -key vms_cert_dir/client.key <enter> # will connect to server <sr> ...handshake verbiage... # bla...bla...bla... <ur> GET /neil.txt HTTP/1.0<enter> # request file "neil.txt" <enter> # signal end of HTTP header <sr> HTTP 200 (OK) ...header verbiage... this is sample text # presto
Web server with certificate-based client verification (popular in B2B applications)
Server: <ur> cd # run these tests from your home directory <sr> [prompt]
<ur> cat neil.txt # make sure test file exists <sr> this is sample text [prompt] #
<ur> openssl s_server -accept 4433 \ -cert /etc/pki/tls/certs/server.crt \ -key /etc/pki/tls/private/server.key \ -debug \ -WWW \ -Verify 9 <enter> # force client to require a certificate <sr> verify depth is 9, must return a certificate Using default temp DH parameters Using default temp ECDH parameters ACCEPT Client: <ur> openssl s_client -connect 142.180.39.15:4433 \ -cert vms_cert_dir/client.crt \ -key vms_cert_dir/client.key <enter> # will connect to server <sr> ...handshake verbiage... # bla...bla...bla... <ur> GET /neil.txt HTTP/1.0<enter> # request file "neil.txt" <enter> # signal end of HTTP header <sr> HTTP 200 (OK) ...header verbiage... this is sample text # presto <ur> openssl s_client -connect 142.180.39.15:4433 # reconnect "without any certs" <sr> CONNECTED(00000005) depth=0 /C=CA/ST=ON/L=KITCHENER/O=BELL CANADA/OU=BELL-ATS/CN=www.bellics.com/emailAddress=neil@bellics.com verify error:num=18:self signed certificate # this is not really an error verify return:1 depth=0 /C=CA/ST=ON/L=KITCHENER/O=BELL CANADA/OU=BELL-ATS/CN=www.bellics.com/emailAddress=neil@bellics.com verify return:1 262761:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:S3_PKT:1102:SSL alert number 40 262761:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake failure:S23_LIB:182: Server: <sr> ...verbiage... 261215:error:140890C7:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:peer did not return a certificate:S3_SRVR:2611: ACCEPT # waiting for another transaction
<sr> $ # my BASH prompt <ur> openssl ciphers # see available local ciphers <sr> DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:AES256-SHA:DHE-RSA-CAMELLIA256-SHA: DHE-DSS-CAMELLIA256-SHA:CAMELLIA256-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES- CBC3-SHA:DES-CBC3-SHA:DES-CBC3-MD5:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA: AES128-SHA:DHE-RSA-SEED-SHA:DHE-DSS-SEED-SHA:SEED-SHA:DHE-RSA-CAMELLIA128 -SHA:DHE-DSS-CAMELLIA128-SHA:CAMELLIA128-SHA:RC2-CBC-MD5:DHE-DSS-RC4-SHA: RC4-SHA:RC4-MD5:RC4-MD5:EXP1024-DHE-DSS-DES-CBC-SHA:EXP1024-DES-CBC-SHA:E DH-RSA-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:DES-CBC-SHA:DES-CBC-MD5:EXP1024-DH E-DSS-RC4-SHA:EXP1024-RC4-SHA:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC -SHA:EXP-DES-CBC-SHA:EXP-RC2-CBC-MD5:EXP-RC2-CBC-MD5:EXP-RC4-MD5:EXP-RC4- MD5 $ <ur> openssl s_client -connect www.google.ca:443 -cipher "RC4-SHA" # connect using the RED cipher ...handshake verbiage... # bla...bla...bla... note: the requested cipher might not be available at the far end
notes: 1) I am on my production node "KAWC96" connecting to my development node "KAWC09" 2) We could just ignore the error 18 then continue 3) Or save the remote certificate in a local repository ---------------------------------------------------------------------------------------- <sr> [prompt] # my BASH prompt <ur> cd # start in home location <sr> [prompt] # <ur> openssl s_client -connect kawc09.on.bell.ca:443 -state -showcerts # connect to development platform # (without any local certificate) <sr> CONNECTED(00000005) SSL_connect:before/connect initialization SSL_connect:SSLv2/v3 write client hello A SSL_connect:SSLv3 read server hello A depth=0 /C=ca/ST=Ontario/L=Kitchener/O=Bell Canada/OU=Bell-ATS/CN=kawc09.on.bell.ca/emailAddress=neil@kawc09.on.bell.ca verify error:num=18:self signed certificate <<<--- oops (let's fix this) verify return:1 depth=0 /C=ca/ST=Ontario/L=Kitchener/O=Bell Canada/OU=Bell-ATS/CN=kawc09.on.bell.ca/emailAddress=neil@kawc09.on.bell.ca verify return:1 SSL_connect:SSLv3 read server certificate A SSL_connect:SSLv3 read server key exchange A SSL_connect:SSLv3 read server done A SSL_connect:SSLv3 write client key exchange A SSL_connect:SSLv3 write change cipher spec A SSL_connect:SSLv3 write finished A SSL_connect:SSLv3 flush data SSL_connect:SSLv3 read finished A --- Certificate chain 0 s:/C=ca/ST=Ontario/L=Kitchener/O=Bell Canada/OU=Bell-ATS/CN=kawc09.on.bell.ca/emailAddress=neil@kawc09.on.bell.ca i:/C=ca/ST=Ontario/L=Kitchener/O=Bell Canada/OU=Bell-ATS/CN=kawc09.on.bell.ca/emailAddress=neil@kawc09.on.bell.ca --- Server certificate -----BEGIN CERTIFICATE----- MIICtzCCAiACCQCOJDXcN8BI4TANBgkqhkiG9w0BAQUFADCBnzELMAkGA1UEBhMC [...snip...] S/To2pITuhif+f7Mec4qU/SDUXpj6Se/tJE9TjE2Mc5edTUmgX3amMpYUnQwBHti zQb9M8XXRU0RwBHZgqOYk/amVFeVCVFxw9jn -----END CERTIFICATE----- subject=/C=ca/ST=Ontario/L=Kitchener/O=Bell Canada/OU=Bell-ATS/CN=kawc09.on.bell.ca/emailAddress=neil@kawc09.on.bell.ca issuer=/C=ca/ST=Ontario/L=Kitchener/O=Bell Canada/OU=Bell-ATS/CN=kawc09.on.bell.ca/emailAddress=neil@kawc09.on.bell.ca --- No client certificate CA names sent --- SSL handshake has read 1270 bytes and written 361 bytes --- New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA Server public key is 1024 bit Secure Renegotiation IS supported Compression: NONE Expansion: NONE SSL-Session: Protocol : TLSv1 Cipher : DHE-RSA-AES256-SHA Session-ID: DE5C43E6C8B445FCDA60894A08650E5B19D1E99DAF3F70D2661EE60956001CF1 Session-ID-ctx: Master-Key: CFF329BE8FFF7B8FD7E6201B16F1AC3663EFF5633CDDD6EA52C79ED4A5C1A7A1F796DECCD77FCD21D497DC2021402118 Key-Arg : None Start Time: 1343864769 Timeout : 300 (sec) Verify return code: 18 (self signed certificate) <<<---oops (let's fix this) --- <ur> <ctrl-Y> # we're done so hit <ctrl-Y> <sr> INTERRUPT $
Create a trusted chain (or add to an existing chain)
Note: This is similar to what happens when you import a certificate into your browser
<ur> cre xxx_kawc09.crt # create a file -----BEGIN CERTIFICATE----- # past in the remote certificate from above MIICtzCCAiACCQCOJDXcN8BI4TANBgkqhkiG9w0BAQUFADCBnzELMAkGA1UEBhMC [...snip...] S/To2pITuhif+f7Mec4qU/SDUXpj6Se/tJE9TjE2Mc5edTUmgX3amMpYUnQwBHti zQb9M8XXRU0RwBHZgqOYk/amVFeVCVFxw9jn -----END CERTIFICATE----- <ctrl-z> # hit <ctrl-z> to exit file-creation with SAVE <sr> Exit $ <ur> copy xxx_kawc09.crt vms_cert_dir # optional: copy file to our cert directory <sr> $ <ur> set def vms_cert_dir # now move over there <sr> $ <ur> dir client_ca.pem # any chains like this here? <sr> %DIRECT-W-NOFILES, no files found # nope <ur> copy xxx_kawc09.crt client_ca.pem # copy cert into new PEM or # or copy client_ca.pem, xxx_kawc09.crt client_ca.pem # append cert onto existing PEM <sr> $ <ur> openssl x509 -hash -noout -in client_ca.PEM # compute hash of pem <sr> 1132507a # this is the computed result <ur> copy client_ca.PEM 1132507a.0 # create a hash file with '.0' extension <sr> $ <ur> openssl verify "-CApath" vms_cert_dir -verbose -purpose any client_ca.PEM # test the PEM-hash combo <sr> client_ca.pem: OK # looks good so far <ur> set def sys$login: # back to our home directory <sr> $ <ur> openssl s_client -connect kawc09.on.bell.ca:443 -state - # connect to development platform (again) -cert vms_cert_dir/kawc96.crt - # -key vms_cert_dir/kawc96.key - # -"CAfile" vms_cert_dir/client_ca.PEM # but reference trusted cert chain <sr> CONNECTED(00000005) SSL_connect:before/connect initialization SSL_connect:SSLv2/v3 write client hello A SSL_connect:SSLv3 read server hello A depth=0 /C=ca/ST=Ontario/L=Kitchener/O=Bell Canada/OU=Bell-ATS/CN=kawc09.on.bell.ca/emailAddress=neil@kawc09.on.bell.ca verify return:1 <<<--- cool (fixed) SSL_connect:SSLv3 read server certificate A SSL_connect:SSLv3 read server key exchange A SSL_connect:SSLv3 read server done A SSL_connect:SSLv3 write client key exchange A SSL_connect:SSLv3 write change cipher spec A SSL_connect:SSLv3 write finished A SSL_connect:SSLv3 flush data SSL_connect:SSLv3 read finished A --- Certificate chain 0 s:/C=ca/ST=Ontario/L=Kitchener/O=Bell Canada/OU=Bell-ATS/CN=kawc09.on.bell.ca/emailAddress=neil@kawc09.on.bell.ca i:/C=ca/ST=Ontario/L=Kitchener/O=Bell Canada/OU=Bell-ATS/CN=kawc09.on.bell.ca/emailAddress=neil@kawc09.on.bell.ca --- Server certificate -----BEGIN CERTIFICATE----- MIICtzCCAiACCQCOJDXcN8BI4TANBgkqhkiG9w0BAQUFADCBnzELMAkGA1UEBhMC [...snip...] S/To2pITuhif+f7Mec4qU/SDUXpj6Se/tJE9TjE2Mc5edTUmgX3amMpYUnQwBHti zQb9M8XXRU0RwBHZgqOYk/amVFeVCVFxw9jn -----END CERTIFICATE----- subject=/C=ca/ST=Ontario/L=Kitchener/O=Bell Canada/OU=Bell-ATS/CN=kawc09.on.bell.ca/emailAddress=neil@kawc09.on.bell.ca issuer=/C=ca/ST=Ontario/L=Kitchener/O=Bell Canada/OU=Bell-ATS/CN=kawc09.on.bell.ca/emailAddress=neil@kawc09.on.bell.ca --- No client certificate CA names sent --- SSL handshake has read 1270 bytes and written 361 bytes --- New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA Server public key is 1024 bit Secure Renegotiation IS supported Compression: NONE Expansion: NONE SSL-Session: Protocol : TLSv1 Cipher : DHE-RSA-AES256-SHA Session-ID: 96B7F72BDCCB65C8040BD1DFE714989D87F966D000AB7ED9CDD9AEF5FD4EAE89 Session-ID-ctx: Master-Key: 7737874E462FAFD277E6541BD2608070BEBB15393D6897125F1DF8A10AC3AE24D5FD65BA0F909F9576A04856345BB6EE Key-Arg : None Start Time: 1343865022 Timeout : 300 (sec) Verify return code: 0 (ok) <<<---cool (fixed) --- <ur> <ctrl-z> # we are done <sr> Exit $
Overview:
note: this is a real-world example for server: kawc96.on.bell.ca
(substitute numerical values for ccyymmdd)
commands:
1) openssl genrsa -out kawc96_ccyymmdd.key 2048
2) openssl req -new -key kawc96_ccyymmdd.key -out kawc96_ccyymmdd.csr
3) openssl req -noout -text -in kawc96_ccyymmdd.csr
4) cat (on Unix/Linux) kawc96_ccyymmdd.csr
or
type (on OpenVMS) kawc96_ccyymmdd.csr
steps:
1) copy/paste the contents into the submission window at your certificate vendor's site
2) the vendor will sign your CSR then will hand it back to you as a CRT in base-64 format
(they used to do that by email; but all modern services now require you to fetch it)
3) save it as a file of the form: kawc96_ccyymmdd.crt
4) visit the vendor's site to get a copy the certificate they used to sign your CSR.
(sometimes these are presented as a chain file of intermediate certificates)
I saved mine as: kawc96_ccyymmdd_vendor.crt
5) modify the Apache config file "ssl.conf" (see steps above)
kawc96_ccyymmdd.key (private key which will never been shared with anyone)
kawc96_ccyymmdd.crt (public certificate which contains your public key)
kawc96_ccyymmss_vendor.crt (vendor's public certificate used to sign your cert)
6) restart the server (checking your log files)
OpenSSL CLI commands to display the certificate files just for the fun of it 1) openssl x509 -noout -text -in kawc96_ccyymmdd.crt 2) openssl x509 -noout -text -in kawc96_ccyymmdd_vendor.crt
3) openssl rsa -noout -text -in kawc96_ccyymmdd.key
I have been using multi-host certificates for over two decades, and ordering them was simple until 2025.
Starting in 2025, the procedure above did not produce a multi-host certificate(???).
After contacting the vendor, a non-technical specialist cast the blame on me for not including the additional hosts in the CSR (so why was I still being prompted for a
list of additional hosts?)
Click here to see my hack which worked.
In most instances, the server admin person will test the new certificates by connecting with a modern browser like Chrome or MS-Edge. However, these browsers come with a large collection of CA Root certificates which means that (sometimes) you will only have browser connectivity while connecting by other methods will fail since a leaf-to-root certification path cannot be made. This exact thing happened to me recently when I updated both my CER and KEY files but neglected to update my chain file (of intermediate certificates) from the previous year. Why was this failing now? My host provider changed certificate vendors which meant that my chain was no longer valid). Anyway, here is the python script I used to detect, then fix, this problem: server_certificate_check
step 1: create file "index.html" in your local folder
=====================================================
<html> <head> <title>index.html</title> </head> <body> <p>this is a fake index file used for testing via the openssl cli</p> </body> </html>
step 2: create local certificates
=================================
step 2a: create a key openssl genrsa -des3 -out server.key 2048 # requires a passphrase
-or-
openssl genrsa -out server.key 2048 # no passphrase step 2b: create a CSR openssl req -key server.key -new -out server.csr --------------------------------------------------- dialog start You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [XX]:CA State or Province Name (full name) []:Ontario Locality Name (eg, city) [Default City]:Kitchener Organization Name (eg, company) [Default Company Ltd]:Bell-ATS Organizational Unit Name (eg, section) []:Bell-ATS Common Name (eg, your name or your server's hostname) []:bfdc0d.on.bell.ca Email Address []:neil.rieck@bell.ca Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []: --------------------------------------------------- dialog stop step 2c: self-sign the csr openssl x509 -signkey server.key -in server.csr -req -days 365 -out server.crt
step-3: start the server (self-signed)
======================================
openssl s_server -accept 443 \
-debug -WWW \ -cert ./server.crt \ -key ./server.key
possible reasons for failure
============================ 1) port not opened in your firewall
2) Apache already listening on port 443
Test from the same platform or another
======================================
openssl s_client -connect bfdc0d.on.bell.ca:443
GET /index.html HTTP/1.0<enter><enter> web page verbiage is returned
expert hacks
step-4: create a self-signed Root CA (to sign your own cert) ============================================================ openssl req -x509 -sha256 \ -days 1825 \ -newkey rsa:2048 \ -keyout ccyymmdd_root-CA.key \ -out ccyymmdd_root-CA.crt ----------------------------------------------------------- dialog start Generating a 2048 bit RSA private key ..........................................................+++ ...+++ writing new private key to 'ccyymmdd_root-CA.key' Enter PEM pass phrase:neil Verifying - Enter PEM pass phrase:neil ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [XX]:CA State or Province Name (full name) []:Ontario Locality Name (eg, city) [Default City]:Kitchener Organization Name (eg, company) [Default Company Ltd]:Bell-ATS Organizational Unit Name (eg, section) []:Bell-ATS Common Name (eg, your name or your server's hostname) []:neilrieck Email Address []:neil.rieck@bell.ca ----------------------------------------------------------- dialog stop
step-5: use your root-CA cert to sign your original csr
note: new cert will be named domain2.crt
=======================================================
step-51: create a config file (domain.ext) with the following content:
note: DNS.1 is required; other DNS entries are optional ----------------------------------------------------------- content start authorityKeyIdentifier=keyid,issuer basicConstraints=CA:FALSE subjectAltName = @alt_names [alt_names] DNS.1 = bfdc0d.on.bell.ca DNS.2 = bfdc0e.on.bell.ca ----------------------------------------------------------- content stop
step-52: sign your original csr
openssl x509 -req \ -CA ccyymmdd_root-CA.crt \ -CAkey ccyymmdd_root-CA.key \ -in domain.csr \ -out domain2.crt \ -days 365 \ -CAcreateserial \ -extfile domain.ext ----------------------------------------------------------- dialog start Signature ok subject=/C=CA/ST=Ontario/L=Kitchener/O=Bell-ATS/OU=Bell-ATS
/CN=bfdc0d.on.bell.ca/emailAddress=neil.rieck@bell.ca Getting CA Private Key Enter pass phrase for ccyymmdd_root-CA.key:neil [prompt ~]
step-53: display the cert
=========================
openssl x509 -noout -text -in domain2.crt
step-54: start the server (signed cert)
=======================================
openssl s_server -accept 443 \
-debug -WWW \ -cert ./server.crt \ -key ./server.key \
-CAcert ./ccyymmdd_root-CA.crt
Free OpenSSL books
OpenSSL for OpenVMS
SSL (general)
OpenSSL Tutorials
Back to Home