Extracting decrypt key for AES from openssl on client side - ssl

I have implemented AES 128 encrypt and decrypt functions and tested it with sample data and it checks out perfectly. I used the following reference:
https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.197.pdf
Next I implemented a dummy SSL client and SSL server which uses openssl to send and receive data. It is working without any error and the messages are exchanged seamlessly.
My main goal here is to use openssl for initial handshake sequence. Once the connection is established between server and client, decrypt the incoming message (this time not using the openssl api but rather by using the decrypt AES function implemented earlier) and print and similarly for outgoing message. We will focus on incoming messages.
For this of course I will need the decrypt key and IV. I got the decrypt key(read key) on client side like following: (ssl is the SSL* structure of openssl for the established connection, I am accessing the source code structures of openssl directly)
//following struct copied from crypto/evp/e_aes.c
typedef struct {
union {
double align;
AES_KEY ks;
} ks;
block128_f block;
union {
cbc128_f cbc;
ctr128_f ctr;
} stream;
} EVP_AES_KEY;
[Client Side]
EVP_AES_KEY *cipher_data;
cipher_data = EVP_CIPHER_CTX_get_cipher_data(ssl->enc_read_ctx);
cipher_data->ks.ks.rd_key --> this is the decrypt key
I used this key to decrypt the incoming message with the AES decrypt function but in vain.
Now AES is symmetric encryption so I thought let me check the encrypt(write) key on the server side. The encrypt key on server should be equal to decrypt key on client side. I got the encrypt key on server like following:
[Server Side]
EVP_AES_KEY *cipher_data;
cipher_data = EVP_CIPHER_CTX_get_cipher_data(ssl->enc_write_ctx);
cipher_data->ks.ks.rd_key --> this is the encrypt key
To my surprise they are different. Now if I use the above encrypt key of server to decrypt the message on the client side. The message is decrypted successfully.(as expected, the key used for encrypting the message is used to decrypt the message in AES standard).
So I reach the following inferences:
The decrypt key which is acquired on the client side is encrypted in some way in openssl?
My method for getting the decrypt key on client side is wrong.
How can I get the decrypt key on the client side which I can use in the AES decryption routine?

Related

Non-RSA TLS1.2 Packet decryption

I am trying to decrypt a pcap file. This pcap file contains a capture of an HLS encrypted video stream. The pcap contains TLSv1.2 packets.
Below are some information from the pcap file
Server Hello message Cipher Suite:
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384.
EC Diffie-Hellman server Params: pubkey (1)
The Certificate Status message:
Signature Hash Algorithm Hash: SHA256
Signature Hash Algorithm Signature: ECDSA
Client Key Exchange Message
EC Diffie-Hellman server Params: pubkey (2)
I tried to follow [this Wireshark SSL decryption tutorial][1]. But it seems that it works only for RSA encryptions.
I have been researching for a while and found [this discussion][2]. I am quoting an extract from this discussion:
There is an important parameter to mind: decryption of a passively
recorded session (with a copy of the server private key) works only if
the key exchange was of type RSA or static DH; with "DHE" and "ECDHE"
cipher suites, you won't be able to decrypt such a session, even with
knowledge of the server private key. In that case, you will need
either the negotiated "master secret", or to use the server private
key to actively intercept the connection
It's note worthy that I have the client private key. In my case, the client is FFmpeg video streamer (FFplay). I had a look also on the [TLS v1.2 RFC][3].
My question:
Is it possible to do a decryption in this scenario ? If yes, what do I need to have to do so?
Is the decryption done using the client's private key or using the pre_shared_master (i.e. Diffie-Hellman) ?
[1]: https://wiki.wireshark.org/SSL
[2]: https://security.stackexchange.com/questions/117778/how-to-decrypt-ssl-traffic-with-a-packet-sniffer-when-i-have-the-private-key
[3]: https://www.rfc-editor.org/rfc/rfc5246
First, the clients private or public key are not involved in the key exchange in any way but only used to authenticate the client (if requested by the server). What is used in the key exchange are the servers private and public key, but only if RSA key exchange is used. For DHE/ECDHE they are not used so private/public key are not sufficient. See it is possible to decrypt HTTPS with the (private, public) pair if it uses DHE? for the details why this is the case.
What you would need instead of the private key is actually the exchanged key which is unique for each TLS session even if the private key is the same. Some clients can store this key for later use and if your client can do it see Decrypting TLS Browser Traffic With Wireshark – The Easy Way! how to proceed then to decrypt the traffic.
No, it is not possible to decrypt in this scenario. That would involve breaking EC Diffie-Hellman.
Decryption is not directly performed using the pre_master_secret but it is performed by keys directly derived from the pre-master secret. That is: the client and server decryption keys that are derived from it by first deriving the master_secret and then performing the PRF and dividing the output to the session keys and IV's.

TLS Extended Master Secret- calculate session hash

I'm have tool which manually dissect ssl/http traffic using openssl library. It's work fine in most cases, but failed wheen client/server usese Extended Master Secret extension.
Fail occured on last stage of handshake, where veryfying of test encripted data performed .
As I understand for proper work of this extension I need properly fill handshake buffer with specific TLS fields (client hello, server hello, key exchange) and then master key should be generated baasing on hashing of handshake buffer.
Unfortunatelly it's not work for me.
So my question-which exactly tls packeds should be hashed for generating proper master key ?
Will be gratefull for any comments.
Thanks.
PS: I downloaded experemental version of openssl from github, where this functionality implemented.
openssl s_server/s_client uses corespond extension, Ican see it in Wireshark, and able to decode traffic with server pem file.
You need to do the following to generate the session hash
1) Append all the Handshake messages, other than encrypted handshakes in order of arrival, please don't include the record header to the handshakes. only messages and message headers
2) Hash them based , simple to say,
Hash algorithm varies based on Cipher Suite and Protocal Version
TLS1 and TLS1.1 its mixture of SHA1 and MD5 (16 bit each)
TLS1.2 its mostly SHA256 or SHA384 based on cipher suite.

Thales Payshield HSM RSA Private Key

We are migrating from Thales 8000 to Thales Payshield 9000. We generated an RSA Key Pair in 8000 (with EI - Generate a Public/Private Key Pair command). We stored the public key on the host and loaded the private key to the HSM's tamper-protected memory (with EK - Load a Private Key command).
The problem is we didn't keep the private key and we don't want to create a new key pair because we have to start a new certification process with the vendor if we do this. Is there a solution like storing this key on a smartcard and moving to the new version like LMK.
I read the Thales console - command reference and programmers manual but wasn't able to find a solution.
The private key that is returned from a Thales HSM keypair generation command (this is command EI on the Payshield 9000 that I have access to) is encrypted under LMK keypair 34-35. You will never see this in the clear i.e unencrypted form.
The only way you could extract this from the HSM would be if you knew that LMK keypair; you could then use this to decrypt it. This is often possible in a test environment where a set of known test LMK keypairs are sometimes used.
In a production environment, however, doing this would obviously compromise the security of the entire HSM and any system dependent upon it.
In your situation, you really have little option but to generate a new keypair and then store the encrypted private key bytes.
The problem, however, with only ever having the private key encrypted under this LMK key pair is that you need to use the HSM to sign a CSR, instead of an established tool like openssl.
I did this by using the EI command (generate an RSA keypair) to generate a keypair, storing the raw encrypted private key bytes returned in a file, constructing an unsigned CSR structure, sending that to the HSM with the private key bytes under command EW (Generate a signature), and then appending the signature to my CSR structure.
If you did not save the output (key block) of the EI command, then the chances of getting that key out of there are practically non-existant. Sorry!
Yes, on two conditions only you can Export an RSA Private Key from payshield 9000 HSM to another payshield 9000 HSM:
1st condition: by purchasing certain license which is HSM9-LIC016 and using the host command L8 which is used to export an RSA Private Key under ZMK. Please refer to
"1270A548-037 Card & Mobile Issuance LIC011,016" manual to see detailed steps of host command L8
2nd condition:You should have recorded the Private Key in a secure manner, which you firstly generated it by EI host command, it is generated encrypted under the old LMK, so you can document it securely for future usage like your critical situation you face now.
The Host command L8 function supports the export of an RSA Private Key from encryption under the LMK to encryption under a Zone Master Key.
The following security settings must be configured by console command CS to allow use of this command:
1- 'Enable import / export of RSA Private Keys?' MUST be set to 'YES' (defaults to NO).
2- 'Key export and import in trusted format only?' MUST be set to 'NO' (defaults to YES)
On the other HSM2:
Import an RSA Private Key using the Host command L6
Although, I can send you the steps in deep details if you want.
Refer to manual:
1270A548-037 Card & Mobile Issuance LIC011,016,018,023 v3.4 Release:October 2018

is ssl certificate encoded?

My application capture every packet coming from the server. I can read those packet for HTTP. I want to read the subject field from ssl certificate. But I cant. Is it encoded? If it is, how can I decode & read it?
Assuming that SSL negotiates a protocol that needs certificates, the certificates are generally in ASN.1 based X.509v3 format when they're sent from the server to the client.
From the TLS 1.0 RFC (which is a start if you want to listen to/analyze the protocol);
7.4.2. Server certificate
When this message will be sent:
The server must send a certificate whenever the agreed-upon key
exchange method is not an anonymous one. This message will always
immediately follow the server hello message.
Meaning of this message:
The certificate type must be appropriate for the selected cipher
suite's key exchange algorithm, and is generally an X.509v3
certificate.

Is data sent from the server also encrypted in HTTPS/SSL?

I'm using wireshark and then opening gmail and hotmail to see if I can see the HTML text sent from server to client, but I couldn't find it! Is it encrypted? I knew HTTPS encrypts client packets -- not both!
Please tell me what is wrong with my information.
HTTPS is HTTP over SSL/TLS, where SSL/TLS encrypts the connection in both directions.
During the SSL/TLS handshake, shared keys are negotiated (via the negotiation of a master secret): you get a client write key and a server write key, as described in the TLS specification (Key Calculation).
Yes. In SSL you and the server both have a public and a private key which is used to encrypt/decrypt sent and received data.