3
votes

I am trying to analyze an SSL 3.0 session via Wireshark. In specific, I want to decrypt the encrypted pre-master key. My understanding is that the pre-master is encrypted with the certificate public key. This is based on the SSL RFC and Specification

Here's what I did. I created a test public/private key pair. The private key is:

-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQDCNh5qKloB7BZ2MgP5hWwc4h/LuH+2VRiriCiV3z/NS8NKK3Gy
edZTa0GL1gm6JoDzcnGg/JXLjnqI/aiIok1AwjaJ5LqErWlkYrkV/1iB6x0oViRT
NsN3hagHHi5Z7n3j1/vP+hfMkSiOeyZ3YwxSWOTDDg2hfmVpJ+5n5ysMwwIDAQAB
AoGAMovlVJpbPL7WhcK0uB+aqNXNkrcdPjZdql9QuNkXAPakCEzQVbRSLPnwYFW/
yFw3GaWCn3S+A/G8QKVMVOtxEWKKBkp3BFKmAsf9t3DeNY7lU8JRdF0f290lhanK
aKdej7OuBDFkY7kYhdXj7fq/EcDsRA7l+TD0sjIp7ikA3NkCQQDpfaYnnkayKl5o
/apDP3FjDeiK3n1xTX3SG9LuS37clzRIlIMh5NTxzRDDxE5jbIAXWE3ikI63Kpo1
zXZOkg3HAkEA1O8WfXg7frsMEaXv671570J+T0yjf8m87o4oZpN4F5ni3uC0sn0u
vc5SeHyAhJlQrDqSVDTGq9Ntc+PqEBR5JQJBAJnTFav0Mk8eaqRwucMkAOdpOlKC
0dHbY5EQk546TpG1a9SFQv8JauECYJEYuyv1R04Z9vXUlrFFd+MKQW7x+fECQQCa
OtbSaHzHbVnvin5+BM7GAyaT75HZZFkJfUQ8EAKDLb5K6v1W7x8k8cWAacV4xcfO
B9qnTVa9bDWyJFoL7ZhVAkEAm1j78aFqXKR8BK0Wk9ulmVJJGX6WZUENlBzln/hZ
LXL0G4fT7BVgvJbFWIElf80y8U1cbhH6S5N2kZ7Pb7rJ8w==
-----END RSA PRIVATE KEY-----

I fired up an OpenSSL server as follows:

openssl s_server -accept 8443 -cert server.crt -key server.key -ssl3 -cipher 'RC4-SHA'

And connected as follows:

openssl s_client -connect localhost:993

Then I captured the SSL Handshake in wireshark and looked at the third packet, labeled "Client Key Exchange, Change Cipher Spec, Encrypted Handshake Message". Under "Client Key Exchange", there is a 128-byte section, which I understand as the encrypted pre-master key. In Hex, it is:

9601aa2a2768b58af647e03f23e3bdaa5d9ab12d648d85755aaaee430ea273946dec5348aaa61dc261138d50d2c80966b7113a659ad5a3998263e2dc0ce4bba5dbd22d2c6bc5c4c75802b8b130d1b0b39558d5516bbe1a1ce2852a6495e52fda5259626480ec1aede49a085b5f6005a1317cfabf72ff740cd038808e01fb3ac2

I am trying to decrypt it in python. Considering I have the private key, it should be quite simple. I do the following:

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP

handshake = "9601aa2a2768b58af647e03f23e3bdaa5d9ab12d648d85755aaaee430ea273946dec5348aaa61dc261138d50d2c80966b7113a659ad5a3998263e2dc0ce4bba5dbd22d2c6bc5c4c75802b8b130d1b0b39558d5516bbe1a1ce2852a6495e52fda5259626480ec1aede49a085b5f6005a1317cfabf72ff740cd038808e01fb3ac2".decode('hex')

privkey = open('server.key', 'r').read()
rsakey = RSA.importKey(privkey)
rsakey = PKCS1_OAEP.new(rsakey)
decrypted = rsakey.decrypt(handshake)

print decrypted

However, I get this error:

Traceback (most recent call last):
  File "handshake.py", line 13, in <module>
    decrypted = rsakey.decrypt(handshake)
  File "/usr/lib/python2.7/dist-packages/Crypto/Cipher/PKCS1_OAEP.py", line 227, in decrypt
    raise ValueError("Incorrect decryption.")
ValueError: Incorrect decryption.

Why can't I decrypt this I have the private key. What do OpenSSL do that I'm not doing? What gives? Any and all help is appreciated!

1
What hash algorithm are you using when doing decryption?user1998698
I didn't specify, the code is as-is. Should I?Farhan Yusufzai
It is a pre-master secret, not a key.user207421

1 Answers

0
votes

It seems that you should use PKCS#1 v1.5 padding instead of OAEP.

This should work:

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5

handshake = "9601aa2a2768b58af647e03f23e3bdaa5d9ab12d648d85755aaaee430ea273946dec5348aaa61dc261138d50d2c80966b7113a659ad5a3998263e2dc0ce4bba5dbd22d2c6bc5c4c75802b8b130d1b0b39558d5516bbe1a1ce2852a6495e52fda5259626480ec1aede49a085b5f6005a1317cfabf72ff740cd038808e01fb3ac2".decode('hex')

privkey = open('server.key', 'r').read()
rsakey = RSA.importKey(privkey)
rsa = PKCS1_v1_5.new(rsakey)
sentinel = 'Failure'
decrypted = rsa.decrypt(handshake, sentinel)

print decrypted.encode('hex')