Retrieve up-to-date TLS cipher suite with python - python

I already tried to utilize openssl ciphers, but the format is different and I have to match them with a given set of ciphers. I also tried to translate the OpenSSL cipher suite format into the one I need, but that's a mess.
Hence, I'm searching for a way to retreive an up-to-date TLS cipher suite list with python in the appropriate format. Maybe there's even some Web-Interface?
Here are some examples:
The Format I need OpenSSL Format
--------------------------------- ---------------------
SSL_RSA_WITH_IDEA_CBC_SHA IDEA-CBC-SHA
TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA DHE-RSA-DES-CBC3-SHA
TLS_RSA_WITH_AES_256_CBC_SHA AES256-SHA

Related

Match a domain name to a SSL certificate in a local file

I've got a bunch of SSL certificates in files on the local disk of a server, and want to find the right certificate for a given domain name. Recent versions of Python provide the ssl.match_hostname() function which in principle is all that's needed. However, it expects the certificate in a decoded Python dictionary format as returned by ssl.SSLSocket.getpeercert(), and I can't find a way to parse a certificate from a local file into that format. The underlying C function that performs the parsing does not seem to be exposed directly.
So how can I find the matching SSL certificate for a given hostname? This does not seem like a completely exotic thing to do.
What I would like to avoid is to parse the subject field and the subjectAltName extension of the x509 certificate and implement the hostname matching code myself, since there is a certain complexity involved. (The relevant code in the Python standard library for the domain name matching part alone goes on for more than hundred lines.)

Signing parts of a URL with a RSAKey using Python instead of C#

I do have a private RSAKey (in XML format) that was generated by a .NET class. Those keys, are regularly used to sign parts of a URL. I am trying to sign these URLs with the existing keys via Python, because I am working now in a Linux based environment. The structure of the RSAKey looks like so:
RSAKeyValue,Modulus,Exponent,P,Q,DP,InverseQ,D represented in XML format.
Using C#, I simply instantiate a RSACryptoServiceProvider object and call SignData(bytes, new SHA1CryptoServiceProvider()), and I am done.
I have tried for several days now to replicate this process using Python in a Linux environment without any luck. I extracted modulus, and exponent, base64 decoded, and created byte arrays from them. I also changed the byte order. I was under the assumption that I could use M2Crypto and call RSA.new_pub_key((e,n)) and use that key to sign but no matter what I do I either can't create a proper key, or the signing process doesn't work.
My questions are:
-Is it possible to use an RSAKey in XML format that was generated via .NET, and sign data via Python (M2Crypto or any other lib will do) with the exact same result as in .NET ?
If so, what are the exact steps to do so?
My apologies for the long question. Thanks for any help.

Extract signing certs from a PKCS7 SignedData structure with m2crypto

I am trying to use M2Crypto to extract the signing certificates from a Windows PE file. According to the MS specification the data is stored in a PKCS#7 SignedData structure (stored in ASN.1 format, not the base64). I can't seem to get the binary format to load since it is not in PEM.
Pardon my ignorance with the crypto suites involved here, but if someone can show me the basics of how to get the signing certs out of a SignedData block I'd be most thankful!
If it helps, i found another solution for my problem but it is in C... how to Read the certificates file from the PKCS7.p7b certificate file usind openssl? If i could convert that to m2crpyto i'd be set.
I think there's more to this than just reading the certificate in PKCS7, unless you know absolutely what the offset & struct are.
You might want to take a look at either:
http://msdn.microsoft.com/en-us/library/aa380395(v=VS.85).aspx for the extraction process
Or possibly
http://msdn.microsoft.com/en-us/library/system.reflection.assemblyname.getpublickey%28VS.80%29.aspx
Additionally, it looks like Microsoft signs with a 'PFX' formatted file (I'd never heard of it before..)
But, I was able to find instructions on converting PFX back to a PEM, which should be a cakewalk to extract.
http://support.citrix.com/article/CTX106028

How to encode an RSA key using PKCS12 in Python?

I'm using Python (under Google App Engine), and I have some RSA private keys that I need to export in PKCS#12 format. Is there anything out there that will assist me with this? I'm using PyCrypto/KeyCzar, and I've figured out how to import/export RSA keys in PKCS8 format, but I really need it in PKCS12.
Can anybody point me in the right direction? If it helps, the reason I need them in PKCS12 format is so that I can import them on the iPhone, which seems to only allow key-import in that format.
If you can handle some ASN.1 generation, you can relatively easily convert a PKCS#8-file into a PKCS#12-file. A PKCS#12-file is basically a wrapper around a PKCS#8 and a certificate, so to make a PKCS#12-file, you just have to add some additional data around your PKCS#8-file and your certificate.
Usually a PKCS#12-file will contain the certificate(s) in an encrypted structure, but all compliant parsers should be able to read it from an unencrypted structure. Also, PKCS#12-files will usually contain a MacData-structure for integrity-check, but this is optional and a compliant parser should work fine without it.
The standard tool for the job is typically OpenSSL.
See the openssl pkcs12 command.
This mailing list posting tends to suggest that PKCS12 is not planned for a future feature of that package, and is not currently implemented.
http://lists.dlitz.net/pipermail/pycrypto/2009q2/000104.html

Which AES library to use in Ruby/Python?

I need to be able to send encrypted data between a Ruby client and a Python server (and vice versa) and have been having trouble with the ruby-aes gem/library. The library is very easy to use but we've been having trouble passing data between it and the pyCrypto AES library for Python. These libraries seem to be fine when they're the only one being used, but they don't seem to play well across language boundaries. Any ideas?
Edit: We're doing the communication over SOAP and have also tried converting the binary data to base64 to no avail. Also, it's more that the encryption/decryption is almost but not exactly the same between the two (e.g., the lengths differ by one or there is extra garbage characters on the end of the decrypted string)
(e.g., the lengths differ by one or there is extra garbage characters on the end of the decrypted string)
I missed that bit. There's nothing wrong with your encryption/decryption. It sounds like a padding problem. AES always encodes data in blocks of 128 bits. If the length of your data isn't a multiple of 128 bits the data should be padded before encryption and the padding needs to be removed/ignored after encryption.
Turns out what happened was that ruby-aes automatically pads data to fill up 16 chars and sticks a null character on the end of the final string as a delimiter. PyCrypto requires you to do multiples of 16 chars so that was how we figured out what ruby-aes was doing.
It's hard to even guess at what's happening without more information ...
If I were you, I'd check that in your Python and Ruby programs:
The keys are the same (obviously). Dump them as hex and compare each byte.
The initialization vectors are the same. This is the parameter IV in AES.new() in pyCrypto. Dump them as hex too.
The modes are the same. The parameter mode in AES.new() in pyCrypto.
There are defaults for IV and mode in pyCrypto, but don't trust that they are the same as in the Ruby implementation. Use one of the simpler modes, like CBC. I've found that different libraries have different interpretations of how the mode complex modes, such as PTR, work.
Wikipedia has a great article about how block cipher modes.
Kind of depends on how you are transferring the encrypted data. It is possible that you are writing a file in one language and then trying to read it in from the other. Python (especially on Windows) requires that you specify binary mode for binary files. So in Python, assuming you want to decrypt there, you should open the file like this:
f = open('/path/to/file', 'rb')
The "b" indicates binary. And if you are writing the encrypted data to file from Python:
f = open('/path/to/file', 'wb')
f.write(encrypted_data)
Basically what Hugh said above: check the IV's, key sizes and the chaining modes to make sure everything is identical.
Test both sides independantly, encode some information and check that Ruby and Python endoded it identically. You're assuming that the problem has to do with encryption, but it may just be something as simple as sending the encrypted data with puts which throws random newlines into the data. Once you're sure they encrypt the data correctly, check that you receive exactly what you think you sent. Keep going step by step until you find the stage that corrupts the data.
Also, I'd suggest using the openssl library that's included in ruby's standard library instead of using an external gem.

Categories