I am working on an ethical hacking project to monitor all the encrypted packets through OpenSSL.
I do have both the public and private keys (cert files). My application code snippet for regular packet decryption is as follows:
SSL_library_init();
ctx = InitCTX();
server = OpenConnection(hostname, atoi(portnum));
ssl = SSL_new(ctx); /* create new SSL connection state */
SSL_set_fd(ssl, server); /* attach the socket descriptor */
ShowCerts(ssl); /* get any certs */
SSL_write(ssl,acClientRequest, strlen(acClientRequest)); /* encrypt & send message */
bytes = SSL_read(ssl, buf, sizeof(buf)); /* get reply & decrypt */
SSL_free(ssl); /* release connection state */
SSL_read basically gets the certificate at the time of handshaking and utilizes it for decrypting the data. Is there any way to provide the same certificate offline for decryption of data.
Any help/pointers would be highly appreciable.
Generally TLS is gravitating to ephemeral key exchange, DHE or ECDHE. With ephemeral key exchange the session key (pre-master secret and master secret) are calculated using key agreement with temporary Diffie Hellman keys rather than the RSA or ECDSA key pair that is part of the certificate. So often you cannot do this.
You can however explicitly select one of the older RSA_ ciphersuites. In this case the pre-master secret is encrypted on the client side using the server's public key. The private key of the server can then decrypt this pre-master secret, calculate the session keys using the PRF (HMAC based key derivation) and then verify / decrypt all the packets.
It should be possible to do this using Wireshark, yes.
Note that TLS 1.3 will not support the RSA_ ciphersuites anymore. You would have to capture a public key of the client and private key of the server, the public key of the server and a private key of the client, or indeed the session keys directly to decrypt the traffic. Actually, that was one of the common complaints for TLS 1.3; that decrypting the traffic afterwards is not possible. That's however by design; the NSA cannot do this either.
Related
I wrote a java code. In the code, I used com.microsoft.sqlserver.jdbc.SQLServerDataSource to establish a JDBC connection with my Azure sql database . I found that no matter whether I used " ds.setEncrypt(true);" or not, the JDBC connection was encrypted by TLS ( I use wireshark to catch the TCP packaege , all the package is TLS whether I used " ds.setEncrypt(true);" or not ).
Why ? I checked many official documents, but I couldn't find the answer . It's too difficult...
Azure sql database TLS is always enable ? Are there relevant official documents to prove it ?
The question is : I use ds.setEncrypt(true) or not ,even i set this to "false" , the TCP packages are encrypted by TLS . Why ?
Below is my code to establish the JDBC connection .
public static Connection getConnectionObject() {
SQLServerDataSource ds = new SQLServerDataSource();
ds.setServerName("azuresqldbserver0821.database.windows.net");
ds.setDatabaseName("azuresqldb0821");
ds.setPortNumber(1433);
ds.setUser("root0817");
ds.setPassword("<YourStrong#Passw0rd>");
ds.setEncrypt(false);// I use this method or not ,even i set this to "false" , the TCP packages are encrypted by TLS
ds.setTrustServerCertificate(true);
Connection conn;
try {
conn = ds.getConnection();
} catch (Exception e) {
e.printStackTrace();
return null;
}
return conn;
}
}
When a client first attempts a connection to SQL Azure, it sends an initial connection request. Consider this a "pre-pre-connection" request. At this point the client does not know if TLS/SSL/Encryption is required and waits an answer from SQL Azure to determine if TLS/SSL is indeed required throughout the session (not just the login sequence, the entire connection session). A bit is set on the response indicating so. Then the client library disconnects and reconnects armed with this information.
When you set "Encrypt connection" setting on the connetion string you avoid the "pre-pre-connection", you are preventing any proxy from turning off the encryption bit on the client side of the proxy, this way attacks like man-in-the-middle attack are avoided.
When secure connections are needed, please enable "Encrypt connection" setting.
In-transit encryption to Azure SQL is always enabled.
Transport Layer Security (TLS) was previously known as Secure Sockets Layer (SSL).
I am trying to implement peer certificate validation in node.js with express.
In the production i receive error: EE certificate key too weak.
How can i change it to support the weak key?
I don't want to ignore it in the code level, because if i am doing that it does not check the CA at all.
In the development server, if i remove the matching CA certificate i receive UNABLE_TO_VERIFY_LEAF_SIGNATURE, while in the production server i receive "EE certificate key too weak" - it does not check it at all.
In the development server it is working correctly, but in the production server i receive the error.
I cannot change the certificate on the client devices, so i must support the weak key.
https.createServer({
key: getFile(config.get("ssl_certificate.key")),
cert: getFile(config.get("ssl_certificate.cert")),
ca: [
getCACertFile('ca-crt.pem'), //some certificates
],
requestCert: true,
rejectUnauthorized: false
},app)
In req.socket.authorizationError, i expect to receive null.
In the development server i receive null, but in the production server i receive "EE certificate key too weak"
stderrs:
error: failed to start server: Error: error:140AB18E:SSL routines:SSL_CTX_use_certificate:ca md too weak
at Object.createSecureContext (_tls_common.js:135:17)
at Server (_tls_wrap.js:873:27)
at new Server (https.js:62:14)
at Object.createServer (https.js:85:10)
Node v10.0.0 Release News
Dependencies
V8 has been updated to 6.6. [9daebb48d6]
OpenSSL has been updated to 1.1.0h. [66cb29e646]
If you are using Node.js>=10.0.0, it will raise the exception if certs are encrypted by sha1 or md5.
Generate new certs encrypted by sha256 will fix the question on Server.
But in your case, since the certs has been used for devices to connect to server, you can simply use Node.js<10.0.0 (eg:v8.x) to start the server.
Besides, suggest to use nvm to control versions of Node.js.
nvm use v8.x.x
node server.js
Two aspects of your typical SSL cert immediately jump to one's mind: RSA key length, and the hash algorithm. The recipe to accept the cert might differ based on which one is weak.
Check the cert properties, under Siganture Algorithm. Is it sha1RSA by any chance? If so, search for enabling SHA1 support.
Check the public key. How many bits in it? Is it less than 1024? Then search for minimum RSA key length setting.
I'm trying to configuring data protection and to use the certificate to protect key files. Here is the MS documentation Configuring data protection
Here is what I'm trying to do:
services
.AddDataProtection()
.SetApplicationName("test server")
.PersistKeysToFileSystem("/home/www-data/config")
.ProtectKeysWithCertificate(
new X509Certificate2("/home/www-data/config/"keyprotection.pfx);
When I launch the application I get the following error on startup:
info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[58]
Creating key {71e2c23f-448b-49c9-984f-3c8d7227c904} with
creation date 2017-08-29 18:53:51Z, activation date 2017-08-29 18:53:51Z, and expiration date 2017-11-27 18:53:51Z.
info: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[39]
Writing data to file '/home/www-data/config/key-71e2c23f-448b-49c9-984f-3c8d7227c904.xml'.
fail: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[24]
An exception occurred while processing the key element '<key id="71e2c23f-448b-49c9-984f-3c8d7227c904" version="1" />'.
System.Security.Cryptography.CryptographicException: Unable to retrieve the decryption key.
at System.Security.Cryptography.Xml.EncryptedXml.GetDecryptionKey(EncryptedData encryptedData, String symmetricAlgorithmUri)
at System.Security.Cryptography.Xml.EncryptedXml.DecryptDocument()
at Microsoft.AspNetCore.DataProtection.XmlEncryption.EncryptedXmlDecryptor.Decrypt(XElement encryptedElement)
at Microsoft.AspNetCore.DataProtection.XmlEncryption.XmlEncryptionExtensions.DecryptElement(XElement element, IActivator activator)
at Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager.Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.IInternalXmlKeyManager.DeserializeDescriptorFromKeyElement(XElement keyElement)
warn: Microsoft.AspNetCore.DataProtection.KeyManagement.DefaultKeyResolver[12]
Key {71e2c23f-448b-49c9-984f-3c8d7227c904} is ineligible to be the default key because its CreateEncryptor method failed.
System.Security.Cryptography.CryptographicException: Unable to retrieve the decryption key.
at System.Security.Cryptography.Xml.EncryptedXml.GetDecryptionKey(EncryptedData encryptedData, String symmetricAlgorithmUri)
at System.Security.Cryptography.Xml.EncryptedXml.DecryptDocument()
at Microsoft.AspNetCore.DataProtection.XmlEncryption.EncryptedXmlDecryptor.Decrypt(XElement encryptedElement)
at Microsoft.AspNetCore.DataProtection.XmlEncryption.XmlEncryptionExtensions.DecryptElement(XElement element, IActivator activator)
at Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager.Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.IInternalXmlKeyManager.DeserializeDescriptorFromKeyElement(XElement keyElement)
at Microsoft.AspNetCore.DataProtection.KeyManagement.DeferredKey.<>c__DisplayClass1_0.<GetLazyDescriptorDelegate>b__0()
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
at System.Lazy`1.CreateValue()
at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyBase.get_Descriptor()
at Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.CngGcmAuthenticatedEncryptorFactory.CreateEncryptorInstance(IKey key)
at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyBase.CreateEncryptor()
at Microsoft.AspNetCore.DataProtection.KeyManagement.DefaultKeyResolver.CanCreateAuthenticatedEncryptor(IKey key)
warn: Microsoft.AspNetCore.DataProtection.KeyManagement.DefaultKeyResolver[12]
Key {71e2c23f-448b-49c9-984f-3c8d7227c904} is ineligible to be the default key because its CreateEncryptor method failed.
System.Security.Cryptography.CryptographicException: Unable to retrieve the decryption key.
at System.Security.Cryptography.Xml.EncryptedXml.GetDecryptionKey(EncryptedData encryptedData, String symmetricAlgorithmUri)
at System.Security.Cryptography.Xml.EncryptedXml.DecryptDocument()
at Microsoft.AspNetCore.DataProtection.XmlEncryption.EncryptedXmlDecryptor.Decrypt(XElement encryptedElement)
at Microsoft.AspNetCore.DataProtection.XmlEncryption.XmlEncryptionExtensions.DecryptElement(XElement element, IActivator activator)
at Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager.Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.IInternalXmlKeyManager.DeserializeDescriptorFromKeyElement(XElement keyElement)
at Microsoft.AspNetCore.DataProtection.KeyManagement.DeferredKey.<>c__DisplayClass1_0.<GetLazyDescriptorDelegate>b__0()
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
--- End of stack trace from previous location where exception was thrown ---
So the key is created and well encrypted. But it seems that somehow it doesn't know how to decrypt it as it says in the error:
System.Security.Cryptography.CryptographicException:
Unable to retrieve the decryption key.
If I understand it correctly, it uses the certificate I provided to encrypt the key. But it looks like it doesn't use the same cert for the decryption for some reason (It looks like it tries to retreive it from somewhere else [store?]).
What is going wrong ?
I also tried to put the cert into CA store as described here:
Create a Self-Signed Certificate and trust it on Ubuntu Linux
Then I tried to find them back from the code like this:
var cert = new CertificateResolver().ResolveCertificate(CertThumbprint);
But it didn't work (it cannot find it).
I also tried tried to find them using the following approach:
var store = new X509Store(StoreName.CertificateAuthority,
StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
var collection = store.Certificates.Find(
X509FindType.FindByThumbprint,
CertThumbprint, false);
store.Close();
var x509Cert = collection.Count > 0 ? collection[0] : null;
But it didn't work neither.
So what is the right way ?
For reasons known only to Microsoft, the ProtectKeysWithCertificate overrides that accept actual certificates (PFX files or X509Certificate2 objects) are only able to encrypt DPAPI data. Decryption only works if the same certificate is stored in the machine's certificate store, which makes those overrides relatively pointless.
Why? Who knows. It isn't particularly useful information, but it's vaguely dismissed here as a "limitation of the underlying framework".
In this related discussion (which was just closed without any Microsoft assistance or engagement at all), a user shares custom persistence classes which aren't affected this mysterious "limitation." GitHub repo linked below, I know this is an old question, but maybe it'll help someone else.
https://github.com/tillig/DataProtection
Update: This will be fixed in the upcoming Core 2.1.0 release:
https://github.com/aspnet/Home/issues/2759#issuecomment-367157751
I am implementing SSL server using boost::asio.
The context initialization is shown in below code
boost::asio::ssl::context_base::method SSL_version =
static_cast<boost::asio::ssl::context_base::method>(param_values[ID_PROTOCOL_VERSION].int32_value);
// load certificate files
boost::shared_ptr<boost::asio::ssl::context> context_ = boost::shared_ptr<boost::asio::ssl::context>(
new boost::asio::ssl::context(SSL_version));
p_ctx = boost::static_pointer_cast<void>(context_);
context_->set_options(boost::asio::ssl::context::default_workarounds);
context_->use_certificate_chain_file(cert_chain_file);
context_->use_certificate_file(cert_file, boost::asio::ssl::context::pem);
context_->use_private_key_file(cert_file, boost::asio::ssl::context::pem);
context_->set_verify_mode(boost::asio::ssl::verify_peer | boost::asio::ssl::verify_fail_if_no_peer_cert);
context_->set_verify_callback(boost::bind(&verify_certificate_cb, _1, _2));
if (param_values[ID_CIPHER_LIST].int32_value != 0)
{
std::string cipher_list = "";
generate_cipher_list(param_values[ID_CIPHER_LIST].int32_value, cipher_list);
MA5G_logger::log(PRIORITY_INFO, "Supported cipher list %s", cipher_list.c_str());
SSL_CTX_set_cipher_list((reinterpret_cast<boost::asio::ssl::context*>(p_ctx.get()))->native_handle(),
cipher_list.c_str());
}
in the cipher_list, I am supporting below list
AES128-SHA:AES256-SHA:AES128-SHA256:AES256-SHA256:AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA
With ECDSA certificates if I use cipher_list given above then client can not connect to the server and gives error "No shared cipher". But if I do not give cipher_list then the client can successfully connect to the server. The same cipher list works fine with RSA certificates.
The same ECDSA certificates work fine if I use openssl s_server with -cipher option to provide supported cipher_list
Can anyone help with this issue?
No sorry buddy I found the answer after lot of research.
The problem is with the cipher list and not with the code / certificate.
The same certificate uses ECDHE-ECDSA-AES256-SHA cipher with openssl client-server while used ECDH-ECDSA-AES256-SHA cipher for boost asio SSL client-server.
Anyways thanks #rkyser for your help!
I found this buried in the FAQ of the openssl-1.0.1 source code:
Why can't I make an SSL connection to a server using a DSA certificate?
Typically you'll see a message saying there are no shared ciphers when
the same setup works fine with an RSA certificate. There are two
possible causes. The client may not support connections to DSA servers
most web browsers (including Netscape and MSIE) only support
connections to servers supporting RSA cipher suites. The other cause
is that a set of DH parameters has not been supplied to the server. DH
parameters can be created with the dhparam(1) command and loaded using
the SSL_CTX_set_tmp_dh() for example: check the source to s_server in
apps/s_server.c for an example.
So based on this, make sure you are setting your DH parameters using SSL_CTX_set_tmp_dh().
I have two client pkcs12 keystores. I exported the certs out of both of those and added them to a new jks using keyman. The strange thing is that each keystore seperately works fine, but when i combine them into one keystore, both calls to each client fail with
<pre><code>org.springframework.jms.listener.DefaultMessageListenerContainer#0-1, WRITE: TLSv1 Handshake, length = 32
org.springframework.jms.listener.DefaultMessageListenerContainer#0-1, handling exception: java.net.SocketException: Connection reset
org.springframework.jms.listener.DefaultMessageListenerContainer#0-1, SEND TLSv1 ALERT: fatal, description = unexpected_message
org.springframework.jms.listener.DefaultMessageListenerContainer#0-1, WRITE: TLSv1 Alert, length = 18
org.springframework.jms.listener.DefaultMessageListenerContainer#0-1, Exception sending alert: java.net.SocketException: Broken pipe
org.springframework.jms.listener.DefaultMessageListenerContainer#0-1, called closeSocket()
org.springframework.jms.listener.DefaultMessageListenerContainer#0-1, called close()
org.springframework.jms.listener.DefaultMessageListenerContainer#0-1, called closeInternal(true)
org.springframework.jms.listener.DefaultMessageListenerContainer#0-1, called close()
org.springframework.jms.listener.DefaultMessageListenerContainer#0-1, called closeInternal(true)
org.springframework.jms.listener.DefaultMessageListenerContainer#0-1, called close()
org.springframework.jms.listener.DefaultMessageListenerContainer#0-1, called closeInternal(true)
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:168)
at com.sun.net.ssl.internal.ssl.InputRecord.readFully(InputRecord.java:293)
at com.sun.net.ssl.internal.ssl.InputRecord.read(InputRecord.java:331)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:798)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:632)
at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:59)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123)
at org.apache.commons.httpclient.HttpConnection.flushRequestOutputStream(HttpConnection.java:828)
at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$HttpConnectionAdapter.flushRequestOutputStream(MultiThreadedHttpConnectionManager.java:1565)
at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2116)
at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096)
at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323)
at com.att.socialnetworkingmanager.util.HttpRequestUtil.post_aroundBody4(HttpRequestUtil.java:140)
at com.att.socialnetworkingmanager.util.HttpRequestUtil.post_aroundBody5$advice(HttpRequestUtil.java:65)
at com.att.socialnetworkingmanager.util.HttpRequestUtil.post(HttpRequestUtil.java:1)
at com.att.socialnetworkingmanager.util.HttpRequestUtil.post_aroundBody2(HttpRequestUtil.java:89)
at com.att.socialnetworkingmanager.util.HttpRequestUtil.post_aroundBody3$advice(HttpRequestUtil.java:65)
at com.att.socialnetworkingmanager.util.HttpRequestUtil.post(HttpRequestUtil.java:1)
at com.att.socialnetworkingmanager.sng.impl.SocialNetworkingAuthenticationImpl.getSngAccessToken_aroundBody0(SocialNetworkingAuthenticationImpl.java:87)
at com.att.socialnetworkingmanager.sng.impl.SocialNetworkingAuthenticationImpl.getSngAccessToken_aroundBody1$advice(SocialNetworkingAuthenticationImpl.java:65)
at com.att.socialnetworkingmanager.sng.impl.SocialNetworkingAuthenticationImpl.getSngAccessToken(SocialNetworkingAuthenticationImpl.java:1)
at com.att.socialnetworkingmanager.service.impl.UploadManagerImpl.sendToSng_aroundBody0(UploadManagerImpl.java:61)
at com.att.socialnetworkingmanager.service.impl.UploadManagerImpl.sendToSng_aroundBody1$advice(UploadManagerImpl.java:65)
at com.att.socialnetworkingmanager.service.impl.UploadManagerImpl.sendToSng(UploadManagerImpl.java:1)
at com.att.socialnetworkingmanager.jms.SocialNetworkingManagerQueueListener.onMessage_aroundBody0(SocialNetworkingManagerQueueListener.java:52)
at com.att.socialnetworkingmanager.jms.SocialNetworkingManagerQueueListener.onMessage_aroundBody1$advice(SocialNetworkingManagerQueueListener.java:65)
at com.att.socialnetworkingmanager.jms.SocialNetworkingManagerQueueListener.onMessage(SocialNetworkingManagerQueueListener.java:1)
at org.springframework.jms.listener.adapter.MessageListenerAdapter.onMessage(MessageListenerAdapter.java:343)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:518)
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:479)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:451)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:323)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:261)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:982)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:974)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:876)
at java.lang.Thread.run(Thread.java:662)</code></pre>
I'm not sure what is happening because i have done this before. Any ideas why this fails when combining certs from both clients?
You said you exported the certificates out of both key stores - did you also export the associated keys?
TLS client authentication does need the keys, too. The certificates alone won't get you far.
Additionally, your idea could potentially cause problems when selecting the correct key/certificate for a given connection: you must be sure that you correctly select them, typically a client authentication key/certificate pair is supposed to work only for one dedicated service, so mixing up the keys would result in a rejected connection attempt.
We had a similar problem when using multiple keys in the same keystore.jks file. We had the same behaviour, when we used each key separately, the access worked without any problem. When we put both keys into the same keystore, we got the error "403: Forbidden".
After creating new certificates and more, we found out that the name of the certificates in the keystore has an influence:
one of the keys had the name (anonymized):
test-cert-of_company
and did not work. After changing to cert_of_company it worked.
cert_of_company
We guess that the character "-" in the name did cause the problem and the replacement to "_" solved it. Maybe this can help you.
Use keytool to list the contents of your combined key store.
What is the "type" of each entry?
They should be a private key entries; if not (if they are trusted entries), you failed to export the associated private keys.
Are the two certificates from the same issuer?