 I'm going to demonstrate how to use OpenSSL to perform some public key cryptography operations. The scenario will be there will be two users, A and B. Both users will generate their public key pairs. We'll use RSA as the public key cryptography algorithm. I'll generate their RSE public and private keys. Then user A will take some message, sign that message, create its digital signature of that message, and encrypt the message also using RSA, send to user B. Upon reception user B will decrypt the message and also verify the message, making sure that it came from user A and not someone pretending to be user A. The purpose of the demonstration is to really show some of the basics of OpenSSL. There may be better ways to do this both in OpenSSL as well as in other software. First we're going to generate the public and private key pairs. So with OpenSSL there are many different operations. You can see the main page of OpenSSL to see all those operations. Before we get started though, just to confirm what version of OpenSSL I'm using is 1.00e. The version 1.0 supports some generic operations for public key cryptography. If we man OpenSSL it lists the many different commands and I scroll down. The commands I'm going to use for this demo are the generic forms for public key cryptography like GenP key as opposed to the specific forms like GenRSA and GenDSA. If you're using OpenSSL version before version 1 then they may not support those generic commands and you may need to use GenRSA. Read the man page to see what commands are supported. The first thing we want to do is to generate the public and private key pairs for a user. So we'll use the GenP key command to generate a private key. Specify the algorithm to use, RSA for this demonstration. And select some options for our key generation, some private key options. And the two options I'm going to set is the key length for RSA. The man page for GenP key explains these options. The key length in bits, I'm going to choose 2048 bits. That is the modulus n in RSA will be 2048 bits in length. Another option I'm going to choose the value of the public exponent e. RSA key gen public exponent and I'm going to choose the value 3. By default if you don't give these options then the different, I think the key length is 1024 bits and a different value of the public exponent e is chosen. Again the man page describes those default values. So this will generate a private key for RSA. And I'm going to output that to a file called private key user A. And the format PEM is the default format. There's an alternative format format that can be used for the output of the key as well. It generates the private key and now let's look at the private key. The file has been generated. I'll simply use cat. And so we don't scroll through the screen too fast, pipe into less. And we see the private key. It doesn't make much sense there because this is base 64 encoded. To encode into a format that we can transfer easily over a network the base 64 encoding is used. So this is the private key. Let's look at the values. So instead of looking at the base 64 encoding let's look at the actual values in a simple text encoding. So to view the values we can use OpenSSL and use the pkey command. We can input our private key file and specify the dash text option to show the output rather than in base 64 encoding the actual... Well, it will show the base 64 encoding as well as the actual values. And I'll pipe that into less so we can scroll through. We see the base 64 encoded private key. And then after that it shows the values of the different parameters for the private key all given in hexadecimal. We see the modulus. So the 2048 bit value of n. Then there's the public exponent which we set as an option which is the value 3 in decimal. And then the private exponent. So the public exponent e and the private exponent d gain that in hexadecimal. Also records the two primes which were used to generate n. n the modulus is calculated from multiplying two prime numbers p and q together. p being prime 1 and q being prime 2. So those prime values are recorded as well. And if we keep scrolling down we see that there are three other parameters. Exponent 1, Exponent 2 and a coefficient which are recorded with the private key. What are they? In fact they are values that are used to help with the decryption to speed up the decryption. I'll quit that and let's go and look at the basics of the RSA algorithm to explain them. You should recall that the RSA encryption algorithm is to take some plaintext message e raised to the power of e. Sorry some plaintext message m raised to the power of e the public exponent and then mod by our modulus n. And we get the ciphertext as output. And decryption we take that ciphertext raised to the power of d our private exponent mod by the modulus n and we get the original plaintext m back. So the parameters we have are the modulus n of some length b bits in our example 2048 bits. We have the public exponent e and the private exponent d so we can think that in simple form that the public key is n combined with e and the private key is n combined with d. But in fact n is calculated from multiplying two prime numbers p and q together. So in our private key when we generate it using open SSL to simplify the calculations when we decrypt rather than taking c to the power of d we can use the Chinese remainder theorem to make the decryption faster. And therefore we store the values also of p and q and these three other values exponent one, exponent two and coefficient. Exponent one is simply our private value d mod by p minus one and exponent two is our private value d mod q minus one. And the coefficient is the prime q or the multiplicative inverse of prime q in mod p. Those three values are just there to improve the performance when we do the decryption. So we can think as the private key in fact as being the set of parameters n, e, d, p, q, the two exponents d subscript p, d subscript q and the inverse of q and the public key being n and e. So for the private key all values must be kept private, must be kept secret except n and e because n and e are part of the public key, they can be made publicly available but all those other values must be kept secret and those values are all stored in this file that we created. So this file must be kept secret, we should not make that available to someone. If we're using a multiple user operating system we should set the permission so that no one else can read that file. Now let's create a public key that is give the values of n and e only, put them in a file so that we can make them available to someone else. We use the p key command again, our input is the private key file and we specify the an output file that's called pub key dash a and specify to produce the public key as output minus pub out and that creates our public key file and again we can look at the content of that file again it's base 64 encoded storing the values of e and n the public exponent e and the modulus n and we can look at the contents or the values of those again using this minus text option command p key the input is our public key file specify it's a public key coming in and using the minus text option to show not just the base 64 encoded public key but also the actual values I'll do that again but pipe it into less so that we can see it we see the base 64 encoded data at the top and then the actual values the modulus n which should be the same as in the private key and our exponent e so this file we can make available to other users I'm going to repeat the key generation operation for a second user user B because I'm going to need that later so I'm going to repeat the private key generation step to generate another key but save it in a different file for user B in this case same options and I'm going to repeat the step of creating the public key file for user B that takes the private key file for user B and outputs the public key file for user B in LS we now have two pairs of keys for user A a private key file and a public key file and the same for user B of course these users may be on different systems but for this demo I'm just having both users on the same system and they'll in fact use the same directory in practice those private key files must be kept secret so user B could not see the private key of user A and vice versa now let's do some encryption and also create a digital signature of some text message first let's create a message we've got message.txt open in our nano text editor this is my example message and save that yes so that's the message that I want to send from user A to user B I want the message to be sent confidentially so that no one else could intercept and see the contents of the message and I want user B people want to make sure that the message came from user A and has not been modified so we'll actually create a digital signature of that message before we send it to B how do we create a digital signature the basic form is to take a hash of the message and to encrypt that hash value using the sender's private key to create the hash of a message we can use openSSL and the digest command dgst specify a hash algorithm for this demo I'll use char1 and the file that we want to calculate the hash of message.txt in this example and it gives us the hash value this value 0647 up to ca6 the hash of the file message.txt using the char the secure hash algorithm and then the idea is to encrypt the hash value using A's private key it turns out openSSL has an option to do those steps in one operation that is to calculate the hash and then encrypt it using the private key we use the digest command specify the algorithm and give the option to sign the hash value to sign the message we specify the private key file of user A because we need to sign using the private key of user A and the output is going to go into some file let's call it the signature file it's going to be some binary values so I'll just use a dotbin in the file name and the input is our message so what we're going to do is two steps in this single operation calculate the hash of message.txt and then encrypt that hash value using rsa and using the private key of user A and output that into the file signature.bin that is to create the digital signature of this file we can see the file signature.bin is created ls-l is 256 bytes in length so we will send the signature to user B so the user B can verify that that message came from user A because it's signed by user A's private key to verify we will decrypt using user A's public key if we want confidentiality of our message note that the message is not encrypted if we want confidentiality we need to encrypt that we would normally use a symmetric key cipher like AES or SSS to encrypt but just to demonstrate I will use rsa to encrypt why normally use symmetric key ciphers they're typically faster than public key ciphers especially for larger messages but for this demonstration we can use rsa to encrypt the message to provide confidentiality we use the public key utility operation or command pkeyutl specify to encrypt we want to encrypt the input message.txt file to encrypt we're going to use the public key of user B so specify the public key that's coming in and it will be a public key that's being used as the input to do the encryption and the key file the input key file is the public key of user B and we're going to output to some cipher text and it's going to be some binary output so in this operation we're using using rsa because it's an rsa key to encrypt our message.txt file we're going to encrypt using the public key of user B so that when we send it to user B user B will be able to decrypt using their private key and only B will be able to decrypt because only B has the private key and we see now the cipher text has been created so we would send the cipher text and the signature to user B. I'm not going to send it because in fact I'm going to now behave as user B on this system as if I've received both ciphertext.bin and signature.bin of course user B does not have the message nor does it have the private key of user A but we'll assume that user B has its own private and public key pair which we've generated already so they exist and also we'll assume that user B has the public key of A so the files that B has ciphertext.bin, private key of B public key of A, public key of B and the signature so when B receives the ciphertext and signature it has two things to perform it has to decrypt the ciphertext and then verify the signature to decrypt the ciphertext we'll use similar to how we encrypted the ciphertext using peak key utility operation specify the decrypt option the input file is the ciphertext the input key is the private key of B the message was encrypted using the public key of B therefore we decrypt using the private key of B and the output is going to be the received message let's save it to a file called receivedMessage.txt so we've done the decryption let's look at the contents of that file and it's the same as our original message so we've decrypted this ciphertext our original message it's the same if we compare the two files using diff it produces no output meaning there are no differences between those two files so that's the decryption of the ciphertext at the receiverB the other thing B wants to do is to verify the signature so A signed the message that is they took the hash and encrypted with A's private key sent the signature to B B now needs to verify that signature we use the digest command again with openSSL specify the hash algorithm so B needs to know that the hash algorithm SHA1 was used and select the verify option and we're going to verify using the public key of A if it was signed with the private key of A we need to verify using the public key of A this of course assumes that B has the public key of A and it is indeed the public key of A and it's not someone pretending to be A if that was the case we'd have an error so we're going to verify using the public key of A the signature referring to the file signature.bin and we're going to verify the received message so use SHA1 as the hash algorithm verify the signature containing signature.bin using the public key of A the signature of the received message and it simply gives an output in this case saying verified okay if we use the wrong key instead of trying to verify using the public key of A but mistakenly try to verify using the public key of B it gives us an error message saying verification failed so that's it we've demonstrated how to generate RSA keys using openSSL how to sign a message how to encrypt a message using RSA and also the receiver how to decrypt a message and to verify a message