I am testing SSL, my use case is if the client wants to do a Renegotiation but propose different set of ciphers this time, is there a way this could be tested with openssl s_client. I know R will send a Reneg request, but how do I include Ciphers also?
Related
How can I get a TLS/JA3 fingerprint, which mimics a major browser, in a websocket connection from node? Can I achieve this by modifying node’s TLS configuration, or do I need something more complex?
I've already tried passing shuffled ciphers as one of the options, along with the headers, using node.JS's ws library, however this wasn't enough achieve the desired effect.
Some libraries allow for single HTTP requests, e.g. this one written in the go language, but I need an open websocket connection.
The JA3 fingerprint is based on ciphers and order and various TLS extensions and order. While ciphers and order can be changed, features like the TLS extension order are not accessible from node - I don't think there is even a OpenSSL API for this (OpenSSL is the TLS library underlying node). This means there is no way to emulate a specific JA3 fingerprint from node.
I'd like to use Axios to get a list of TLS versions and ciphers supported by a server.
Are there properties or functions in the request or response object that expose these values?
I'm familiar with request.connection.ssl.getCurrentCipher(), but this only returns the cipher currently being used.
Example:
const axios = require('axios').default;
axios.head('https://example.com').then(r => {
return r.somePropertyOrMethodForTLSVersionsAndCiphers // ??
});
Related article using TLS library, not axios, and for the client not the server: List all TLS Ciphers the Client supports in Nodejs
A TLS client has no visibility in what the server supports. The client just offers a number of ciphers and the server accepts a single one. No information are provided to the client of what others ciphers the server might support.
The client would basically need to actually try all the ciphers by their own to see if a specific cipher is supported or not, i.e. do lots of TLS handshakes to figure out the supported ciphers. Similar for the TLS protocol version the client can only try to connect with a specific protocol and check with which protocol the server responds.
Using Python 3, I'm trying to connect using a SSL context to a remote SMTP host, but I get the following error:
[SSL: DH_KEY_TOO_SMALL] dh key too small (_ssl.c:1056)
Here's the code I use:
from smtplib import SMTP
import ssl, os, certifi
ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH, cafile=certifi.where())
ssl_context.options |= ssl.OP_NO_TLSv1
ssl_context.options |= ssl.OP_NO_TLSv1_1
ssl_context.load_cert_chain(os.path.join(certsdir, 'certificate.pem'), os.path.join(certsdir, 'id_rsa'))
ssl_context.load_dh_params(os.path.join(certsdir, 'dhparams.pem'))
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_NONE
smtp = SMTP(server_name)
smtp.connect((host, 25))
smtp.ehlo()
if smtp.has_extn('starttls'):
smtp.starttls(None, None, ssl_context)
smtp.ehlo()
smtp.mail(fromaddr)
smtp.rcpt(toaddr)
smtp.data(message)
smtp.quit()
Question: Is the issue on my end, or on the destination's server end? Is there something I can do to avoid this issue?
I use certifi for the list of certificates, that is based on Mozilla recommendations and is up-to-date.
Thank you for your help here.
Question: Is the issue on my end, or on the destination's server end?
The server is offering a weak DH key, the client (your script) wants a stronger key. The problem should usually be fixed at the server side. And note that your call of load_dh_params makes no sense since setting the DH key is only relevant for the server side.
Is there something I can do to avoid this issue?
Don't use DH ciphers in the first place. All modern clients support ECDHE ciphers which don't have this problem. DH is very slow anyway.
Usually the client would also choose a ECDHE cipher if offered and this error will not happen. While it might be that the TLS stack at the client is too old and prefers DH, such an old stack would usually not complain about a weak DH. It is thus more likely that the servers SSL stack is too old so that it does not offer the more modern ciphers the clients wants by default.
To make sure that no DH ciphers are offered by the client and thus ECDHE or RSA key exchange is used set the ciphers accordingly:
ssl_context.set_ciphers('DEFAULT:!DH')
Note though that RSA key exchange is considered obsolete too since it does not provide any forward secrecy. You might therefore try if the server can do without DH and without kRSA by using a cipher string of DEFAULT:!DH:!kRSA.
Although I mention ssh-dss for HostKeyAlgorithms in /etc/ssh/ssh_config. ssh-rsa key pair can be used to login!
HostKeyAlgorithms ssh-dss
Some useful info on the above issue
In practice, a RSA key will work everywhere. ECDSA support is newer, so some old client or server may have trouble with ECDSA keys. A DSA key used to work everywhere, as per the SSH standard (RFC 4251 and subsequent), but this changed recently: OpenSSH 7.0 and higher no longer accept DSA keys by default.
In SSL connections. As far as I understand that the the order of the cipher suit that the client offers to the server matters. How can I know what is the order of the client's offered cipher suit in my Firefox or IE browsers?
In FF, I tried to type about:config and then filtered the output to: security.ssl, I got:
Is this is the exact order that the client offers to SSL servers? Does this means, my browser prefers DHE and ECDHE over RSA key exchange because the DHE and ECDHE ciphers came first?
There is nothing in the TLS RFC that says the order matters. Specific servers may choose to honor the order provided by the client as an order of preference, but it isn't required, and neither JSSE not OpenSSL does so to the best of my knowledge.