SHA256 Server Certificate forcing ECDHE ciphers - ssl

I am experiencing a strange issue with assigning a new SHA256 certificate to an IIS web server.
The server has SSL 3.0, TLS 1.0, 1.1 and 1.2 enabled and when using a server certificate on a site signed with RSA (rather than SHA256RSA) the client connects and negotiates TLS_RSA_WITH_AES_256_CBC_SHA for the TLS encryption.
The second the SHA256 certificate is used on the site it then tries to use TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA.
What is odd is that when checking using www.ssllabs.com server test I can see that completely different ciphers are presented from the server when the SHA256 certificate is used or is not.
Ciphers Suites presented when site using SHA1 certificate.
TLS_RSA_WITH_AES_256_CBC_SHA256
TLS_RSA_WITH_AES_256_CBC_SHA
TLS_RSA_WITH_AES_128_CBC_SHA256
TLS_RSA_WITH_AES_128_CBC_SHA
TLS_RSA_WITH_RC4_128_SHA
TLS_RSA_WITH_3DES_EDE_CBC_SHA
TLS_ECHDE_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
TLS_RSA_WTH_RC4_128_MD5
Ciphers Suites presented when site using SHA256 certificate.
TLS_ECHDE_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
I can find no information to show why this happens but I was aware TLS_RSA_WITH_AES ciphers were TLS 1.2 compatible and there seems to be no literature to state if the server certificate is SHA256 that it enforces Elliptical Curve Diffie-Hellman Exchange for the key encryption.
Can anyone explain why this might be happening?
Kind Regards
James Tighe

I have now managed to resolve this issue in case anyone else is getting it.
It seems that it is to do with the Cryptography/Key Store Provider used to request the CSR.
If the CSR is generated on the Windows Server 2008 R2 machine using a Crypto API providers (such as Microsoft Strong Cryptographic Provider) and the KeySpec is not specifically mentioned when generated the CSR it sets the KeySpec = 2 AT_SIGNATURE. The KeySpec determines whether the key can be used for Signatures, Key Exchange (encryption) or both.
When setting the Cryptography provider to a Crypto API provider seems to cause the Windows Server 2008 R2 machine to complete the request but default to KeySpec = 2 In our case it was because we had generated a .INF file to be used with CERTREQ as IIS was not able to enforce the use of SHA256 as the signing algorithm.
If the KeySpec is set in the .INF file to KeySpec = 1 AT_KEYEXCHANGE then this should work although we resolved this issue a different way.
In order to resolve the issue we changed the .INF file to set the ProviderName = "Microsoft Software Key Storage Provider" (a CNG provider). When the certificate was completed it showed the KeySpec = 0 AT_NONE which is when the key store provider is set to CNG.
This issue was raised to Microsoft to help us get a better understanding and it appears that we were right in the KeySpec behaviour and the usage of the Cryptography Provider.
They confirmed that in the .INF file (or the customer template enrolment in Cert MMC) you need to ensure the KeySpec property is set to 1 AT_KEYEXCHANGE or else it will default to 2 AT_SIGNATURE. If you use a CNG provider it will instead default to use 0 AT_NONE and will work correctly.
I hope this can help other people that might be getting this annoying issue as it was quite hard to find a solution.
Kind Regards
James Tighe

Related

Connection is encrypted using an obsolete cipher suite

I am getting this warning on mobile devices, the full warning is:
The connection uses TLS 1.2
The connection is encrypted using AES_256_CBC, with HMAC-SHA1 for message authentication and ECDHE_RSA as the key exchange.
I am using a dedicated VPS for the website and I have used IISCrypto with best practices applied.
You can see the results of the site scanner with the link below.
Qualys Scan Results
The Schannels I am using are below:
Schannel configuration
Chipher Suit Configuration
The Server is Windows 2012 r2 with IIS
Any help would be very grateful.
Paul.
To cite from the Chromium documentation what you need to do to make this warning go away:
... prioritize an ECDHE cipher suite with AES_128_GCM or CHACHA20_POLY1305. Most servers will wish to negotiate TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256.
Looking at what Windows Server 2012 R2 actually supports on ciphers you'll find that it does not support CHACHA20_POLY1305 and that it supports GCM ciphers only with ECC certificates, i.e. it implements ciphers like TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256_P256 but not ciphers like TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256.
But, you are using an RSA certificate and not an ECC certificate which means that none of the GCM ciphers supported by your OS can be used with your certificate. The ciphers you need are only supported with Windows Server 2016.

OpenSSL connection: alert internal error

I have 100 HTTPS services running on a single server using SNI. (Actually, I don't have access to them. It's an assignment. All I know are their domain names N.xxx.yy where N is in range from 00 to 99.) The goal of the assignment is to evaluate security of every single connection to each of these servers. So some of the servers contain expired certificates, certificates with wrong CN, etc.
My problem is that I cannot get past the handshake on some of the servers. I have written my own application in C++ using OpenSSL, but I've also tried it with openssl s_client. This is how I connect to the server:
openssl s_client -host N.xxx.yy -port 443 -verify 1 -servername N.xxx.yy -CAfile assignment-ca.pem
And this is what I get:
139625941858168:error:14094438:SSL routines:ssl3_read_bytes:tlsv1 alert internal error:s3_pkt.c:1493:SSL alert number 80
139625941858168:error:140790E5:SSL routines:ssl23_write:ssl handshake failure:s23_lib.c:177:
In Wireshark, I see that client sent ClientHello, server responded with ServerHello (choosing TLSv1.2 and ECDHE-RSA-AES256-GCM-SHA384) followed by Certificate and then it sent me Alert message containing Internal Error (80).
After trying different thing I have found out that if I run s_client with -tls1 or -tls1_1 I can successfully get past the handshake. -tls1_2 does not work. What is even stranger is that connection through Chrome/Firefox/any other browser succeeds even if TLSv1.2 is negotiated. From what I see, Chrome is sending a different cipher list than me or s_client but even after modifying the cipher list to match the one in Chrome (and making sure that server chooses ECDHE-RSA-AES128-GCM-SHA256), it does not work either. Chrome is sending these TLS extensions, which I don't but most of them seem empty:
Unknown 47802
renegotiation_info
Extended Master Secret
signed_certificate_timestamp
status_request
Application Layer Protocol Negotiation
channel_id
Unknown 6682
Can anybody explain me what is happening here? Unfortunately, I have no way to debug it on the server side so this is all I know.
UPDATE:
After playing around with forged ClientHello messages I managed to track it down to signature_algorithms extension. My app and s_client provide SHA384 + {RSA,DSA,ECDSA} but if I remove these and keep just SHA256 + {RSA,DSA,ECDSA}, as Chrome does, it works and I receive Server Key Exchange message successfully. Could it be that server somehow does not support it, but instead of providing meaningful error message, it just ends unexpectedly and gives me this internal error?
UPDATE 2:
I found answer to why it works with TLS versions prior to 1.2 in RFC5246. Question from the previous UPDATE still holds.
Note: this extension is not meaningful for TLS versions prior to 1.2.
Clients MUST NOT offer it if they are offering prior versions.
However, even if clients do offer it, the rules specified in [TLSEXT]
require servers to ignore extensions they do not understand.
Since you wrote that -tls1_2 does not work I assume either you and/or the server uses an older openssl library. The current version while writing this is 1.1.0e
There were quite some fixes since 0.9.8, which could often be seen on older systems.
For Version 1.0.1 there was this fix, which sounds like your problem:
`Some servers which support TLS 1.0 can choke if we initially indicate
support for TLS 1.2 and later renegotiate using TLS 1.0 in the RSA
encrypted premaster secret. As a workaround use the maximum permitted
client version in client hello, this should keep such servers happy
and still work with previous versions of OpenSSL.`
Maybe also notable:
Don't allow TLS 1.2 SHA-256 ciphersuites in TLS 1.0, 1.1 connections.
So I would suggest to update your openssl-Version and in case of the servers out of your control I would stick to the settings you already found.

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.

Set up Netty-with TLS handsake with ECC and RSA client certificate auth

I am working on a remote server that uses Netty to perform client authentication with a TLS handshake through the Netty SSLHandler library. This S/O question gives a bit: Set up Netty with 2-way SSL Handsake (client and server certificate)
Now, the question I have about this system is that the Server requires a TrustManager to initialize a SSLContext. From what I observe this uses the SunJSSE provider. Now after setting up this implementation, I got it working with RSA client certs. Now, I am having trouble using ECC client certs as SunJSSE cannot recognize them (I think Java SE 7 include SunEC as a provider. But SunEC is a SunJCE implementation and not a SunJSSE one and thus cannot be used as a provider for TrustManager). So, how do I proceed. I heard Bouncy Castle can recognize these certs, but I still cannot instantiate a TrustManager with BC as the provider.
Edit: Also if there is no way to use TrustManagers, should I do the entire handshake only use BouncyCastle's API's and not netty's libraries? That seems off though.
This is my other S/O question that shows the stack trace: Client ECC SSL Certificate contains "unknown named curve"

In which cases can an SSL server omit sending the certificate?

I'm trying to figure out the SSL handshake process. After reading up on TLS in Wikipedia I've seen that
The server sends its Certificate message (depending on the selected cipher suite, this may be omitted by the server)
I've also seen such behavior in real-life sniffs, but only in cases where the user eventually received an "Invalid certificate" warning.
I was wondering in which cases can a server omit the certificate? How can the client verify the server's identity in this case then? Or is it only reserved to cases where the server have no certificate and gives up on sending a fake one, knowing that the user will see a browser warning anyway?
Thanks!
Some cipher suites don't rely on certificates:
The anonymous cipher suites, defined in the main TLS RFC (the names containing DH_anon). Some of them can provide encryption, but without authentication, which is insecure. Section A.5 says the following about them:
The following cipher suites are used for completely anonymous
Diffie-Hellman communications in which neither party is
authenticated. Note that this mode is vulnerable to man-in-the-
middle attacks. Using this mode therefore is of limited use: These
cipher suites MUST NOT be used by TLS 1.2 implementations unless the
application layer has specifically requested to allow anonymous key
exchange. (Anonymous key exchange may sometimes be acceptable, for
example, to support opportunistic encryption when no set-up for
authentication is in place, or when TLS is used as part of more
complex security protocols that have other means to ensure
authentication.)
Kerberos cipher suites, in which case the identification is done via the Kerberos ticket, and the name is verified against the Kerberos principal name (host/MachineName#Realm).
Pre-Shared Keys cipher suites (see section on PSK Identity Encoding).
There is one valid case for anonymous ciphers: the opportunistic encryption of e-mail over SMTP with STARTTLS. As an MITM could easily prevent the use of TLS, there is no use in protecting agains MITM at the TLS level.
If the client knows that he will proceed anyway, even if the certificate was invalid, the can request an anonymous ciphersuite saving the server the generation of a signature and himself the verification the certificate and the signature.