Does JWKS endpoint need https / TLS? - https

Currently, we embed the public key in the application for JWT validation. And we found the manual key rotation is quite hard. For example, the mobile app cannot switch the key on the same day when we replace the key from the server.
So, we are working on a automatic key rotation approach. The idea is the get the clients to switch to JWKS endpoint so that they can switch the new key without manual update.
I would like to ask do we need https to protect the JKWS endpoint? Because if we use https using internal CA or self-signed cert, we may have to manually replace the cert in every clients when it expires. This defeats the purpose of automatic key rotation.

You want TLS at JWKS endpoint. Without TLS you will have no guarantee that the keys are coming from your server (someone will be able to spoof the response). So TLS at the JWKS endpoint is a must.
You don't need mutual TLS, unless there are some high security requirements for that.
As you pointed out it's best to use certs signed by a trusted CA for that purpose.

I think to be more precise: you want to have the confidence in the response from the jwks endpoint, in both authenticity and integrity (i.e. you want to know the response came from the jwks endpoint, and it wasn't messed with).
TLS is one way to support that. Take note that there are such things as ssl termination which may mean that part of your connection is not covered.
HTTP signatures are another way to support this (although not fully specced out yet)

Related

Can certificates verify dumped https traffic?

Let's suppose, for example, I made a HTTP request to https://example.com and dumped following data
all certificates up to root CA that used to verify the server when the connection was made
all raw TCP traffic in both direction
all unencerypted/decrypted HTTP traffic in both direction
(optional) additional data generated by client
Then I want to prove that I did make such connection to https://example.com trusted by those CAs and the traffic is not fake or modified on client side, with assumption that the website is "trusted", e.g. it's securely configured and not hacked.
Is this possible?
If possible, what additional data is required to be dumped by the client and how to perform the verification?
With enough "additional data generated by client", yes, but the practical answer is "no".
The ciphersuites in use in modern TLS all use a feature known as "Perfect Forward Secrecy". The gist is that in addition to the stable asymmetric keypair used for server (and, optionally, client) identity, both the client and the server generate a random Elliptic Curve Diffie-Hellman (or classic Diffie-Hellman) keypair, do the (EC)DH key negotiation for the session master key, and then both sides promptly forget the temporary private key from that negotiation. Without either of those (EC)DH private keys you can't re-derive the integrity keys, so you can't prove the session.
Of course, if you could re-derive the integrity keys, then you could just forge the session afterwards. So I guess that, ultimately, either way the answer is "no".

[golang]Is it possible to write TLS server without certificate?

From client I already have tls config which sets InsecureSkipVerify to true. How to write server for this client which take any cert.
Can tls.config help in server too? like setting InsecureSkipVerify to true?
No, as #JimB told you, TLS can't work without certificates.
The reasoning is simple: TLS is all about security, and certificates
are cryptographic keys which provide that security (TLS uses a so-called
"asymmetric cryptography" where each party has a key pair consisting of
a private and public parts; the public part is what get sent to another party
when doing a TLS handshake).
But on the other hand the security TLS provides is two-fold:
It provides mutual authentication of the parties participating in the
exchange.
It provides encryption of the transmission channel¹.
Certificates are used for both aspects: the fact they contain cryptographic keys is used for (2), and the fact they have owner's identity encoded
in them (and verified by whoever was issued a particular cercificate)
is used for (1).
Let me not digress into discussing how (1) works in detail
(though I truly urge you to read some theory on it) but (1) is what
you actually want to sidestep.
The good (for you) thing is that it's cheaply doable:
The TLS clients can be told to not verify the server's identity.
The TLS servers can be told to do the same (and often it's the default
mode they operate in—which is typical for regular websites
for instance).
You can create a so-called self-signed certificate for your TLS
server.
The latter requires nothing but something which is able to generate
X.509 certificates; OpenSSL is typically used for this;
just google for it.
If you're on Debian or Debian derivative (like Ubuntu, Mint etc)
consider installing the ssl-cert package and using
the make-ssl-cert program it provides.
¹ To be precise, they only protect the very initial phase of the exchange during which the parties generate and send to each other keys used for symmetric encryption, which are then used to encrypt the communication channel, and are regenerated (and re-exchanged) periodically. This is done because symmetric algoritms are way faster.

Server to Client SSL Encryption w/o SSL Authentication - Tomcat & Spring

Scenario: Sensitive information is exchanged (1) from client to server AND (2) from server to client.
Problem: Data exchanged is not encrypted, so sniffing is easy (it's always theoretically possible, right?)
Solution: Encrypt all data transmitted in either direction (server-to-client and client-to-server).
Implementation:
(1) Client to server - Generate certificate, install private key on server and configure Tomcat to work on HTTPS (Many tutorials for this online).
(2) Server to client - Private key goes to (or generated by) clients, however it seems that some tutorials strongly emphasize that that every client should have their own certificate for the sake of authentication.
Question: If I am already authenticating my users through a database username/password (hashed with salt) combo, but I still need to encrypt server-to-client data transmissions to reduce chance of sniffing, can I just generate one private key for all clients? Are there other ways of achieving what I need with Tomcat/Spring?
It seems you're mixing something up:
Regular https includes encryption in both directions, and only a private key + certificate on the server side. Once a client requests resources through https, they get the answer encrypted. So you'll just need to enforce the https connection (e.g. by redirecting certain requests to https with no delivery of data through http)
If you want client certificates, these are purely used for client authentication, so sharing a common client key/certificate with all possible clients will defeat this purpose. Having client keys/certs does not add any more encryption to your data transfer.
Answering to your follow-up question in the comment:
For https, the server keeps its private key, the public key is what is shared with the client. On typical https, the client can be reasonably sure who the server is (authentication, done through the trustworthy signature on the server's public key. This is what you pay trustcenters for) However, the server has no clue who the client is (here client certificates would come into play, but purely for authentication, not for encryption)
Server and client negotiate a common session key. For this purpose there are many different implementations of the key-exchange protocol. This forum is probably not the right place to describe session negotiation and the ssl handshake again, but you can be sure that you only need a server side key for the purpose you describe above: Take any website as an example: If you go to google mail, their https encryption works through them having a private key and a certified (signed) public key: You have no client side certification, but provide your username and password through the encrypted connection to them. Otherwise you'd have to install a client side key/certificate for a lot of services - and that would be too much of a burden for the average internet user.
Hope that helps.

Is a HTTPS connection secure without a valid SSL certificate?

I use a HTTPS connection without a valid SSL certificate. Is the connection safe? Is the information encrypted?
The connection is encrypted even if the SSL certificate isn't valid (expired, snake-oil, untrusted CA, etc.). The SSL certificate validation just makes sure you're connecting to the folks you think you're connecting to. Encryption doesn't do you any good if the folks decrypting your data are crackers instead of PayPal.
Actually it is possible to establish an encrypted connection between complete strangers without a certificate, using Diffie-Hellman or similar key exchange algorithms.
Alice and Bob agree on a random number x. Alice calculates
xa, where a is a large prime number known only to Alice, and sends that to Bob. Bob calculates xb and sends it to Alice. Alice calculates (xb)a, and Bob calculates (xa)b. Since (xa)b = (xb)a = xab, Alice and Bob now both know the number xab and can use it as an encryption key. The beauty of this is that Bob doesn't know a, Alice doesn't know b, and any eavesdroppers don't know either number (because calculating a from xa, in the case of large numbers, would take years).
As supercat points out, this by itself is still susceptible to a man-in-the-middle attack, and that's why at least one end of the transaction needs to authenticate using a certificate. To be accurate, though, it is not the server that checks this, it's the browser, and most browsers will let the user continue if the certificate is invalid (or possibly even garbage). In that event, the connection will still be considerably more secure than a regular connection. To listen in, you'd need to be able to manipulate IP routing or DNS lookups, and you'd have to set it up before the connection was first made, which is not easy to do.
BTW the keypairs in certificates are not what's used to encrypt actual traffic; they are used to establish a new single-use key for a much faster symmetric cipher (such as DES) which then does the rest of the work.
If there were no verification of SSL certificates, then someone who intercepted a communications channel could capture a request to connect to https://www.acmebank.com, send its own request to www.acmebank.com, and negotiate keys with both acmebank.com and the user. After that, it could receive each morsel of data from the user, decrypt with the user's key, and encrypt with acmebank's key, and do likewise with data from acmebank.com. The net effect would be that neither the user nor acmebank would see anything wrong, but the interceptor would be able to decrypt all of the data between the user and acmebank. The user and the bank will be using different keys to handle their communication, but neither entity will know this. Adding any standard aspect to the protocol to inquire what key is in use wouldn't help, since the interceptor could detect such queries and change the responses appropriately.
SSL prevents a man-in-the-middle attack by requiring the host to send the recipient a copy of the key the host is using, encrypted in a form that an intruder won't be able to fake (unless the intruder can fake CA credentials, at least). If one does not use a CA-issued certificate, there will be little protection against a man-in-the-middle attack, though the encrypted layer would prevent passive or retrospective decryption of session contents (BTW, I wish there were standards for something between unencrypted communication and SSL, for situations where passive or retrospective decryption are the primary threat, but I don't know of any).
Don't bother yourself anymore with invalid ssl certificate. You can now generate free browser valid certificate for your server as easily as you would generate a snakeoil (self-signed, browser invalid) certificate. Go see https://letsencrypt.org/ it's free and open to contributions.
Nope. What you're doing when using HTTPS is telling the browser to connect via a different port (443) whereas normally you connect via (80). Without a certificate, the server would refuse the connection. HTTPS is simply not possible without a certificate. Look here and you'll see a certificate is needed for it to work.
It's possible to establish an encrypted connection, yes, but it would still be possible that you're communicating with a cracked cpmputer instead of the real server. Like that, the cracked computer tells the server that he would be the client, decrypt all the data, store it and send the encrypted data to the client (and tell him he would be the server). So it's just a safe connection if there's no vulnerable point between the server and the client, which no one can guarantee.

SSL Client Cert Verification optimisation

We currently have a group of web-services exposing interfaces to a variety of different client types and roles.
Background:
Authentication is handled through SSL Client Certificate Verification. This is currently being done in web-service code (not by the HTTP server). We don't want to use any scheme less secure than this. This post is not talking about Authorisation, only Authentication.
The web-services talk both SOAP and REST(JSON) and I'm definitely not interested in starting a discussion about the merits of either approach.
All operations exposed via the web-services are stateless.
My problem is that verifying the client certificate on each requests is very heavyweight, and easily dominates CPU time on the application server. I've already tried seperating the Authentication & Application portions onto different physical servers to reduce load, but that doesn't improve dispatch speed overall - the request still takes a constant time to authenticate, no matter where that is done.
I'd like to try limiting the number of authentications by generating an HTTP cookie (with an associated server-side session) after successful client certificate verification, which when supplied by the client will cause client certificate verification to be skipped (though still talking over SSL). I'd also like to time-limit the sessions, and make the processes as transparent as possible from a client perspective.
My questions:
Is this still as secure? (and how can we optimise for security and pragmatism?)
Are there free implementations of this scheme? (I'm aware of the SiteMinder product by CA)
Given the above, should we continue to do Authentication in-application, or move to in-server ?
generating an HTTP cookie (with an
associated server-side session) after
successful client certificate
verification, which when supplied by
the client will cause client
certificate verification to be skipped
Is this still as secure? (and how can
we optimise for security and
pragmatism?)
It's not quite as secure in theory, because the server can no longer prove to himself that there's not a man-in-the-middle.
When the client was presents a client-side certificate, the server can trust it cryptographically. The client and server should be encrypting and data (well, the session key) based on the client's key. Without a client-side cert, the server can only hope that the client has done a good job of validating the server's certificate (as perceived by the client) and by doing so eliminated the possibility of Mr. MitM.
An out-of-the-box Windows client trusts over 200 root CA certificates. In the absence of a client-side cert, the server ends up trusting by extension.
Here's a nice writeup of what to look for in a packet capture to verify that a client cert is providing defense against MitM:
http://www.carbonwind.net/ISA/ACaseofMITM/ACaseofMITMpart3.htm
Explanation of this type of MitM.
http://www.networkworld.com/community/node/31124
This technique is actually used by some firewall appliances boxes to perform deep inspection into the SSL.
MitM used to seem like a big Mission Impossible-style production that took a lot to pull off. Really though it doesn't take any more than a compromised DNS resolver or router anywhere along the way. There are a lot of little Linksys and Netgear boxes out there in the world and probably two or three of them don't have the latest security updates.
In practice, this seems to be good enough for major financial institutions' sites, although recent evidence suggests that their risk assessment strategies are somewhat less than ideal.
Are there free implementations of this scheme? (I'm aware of the SiteMinder product by CA)
Just a client-side cookie, right? That seems to be a pretty standard part of every web app framework.
Given the above, should we continue to do Authentication in-application, or move to in-server ?
Hardware crypto accelerators (either a SSL proxy front end or an accelerator card) can speed this stuff up dramatically.
Moving the cert validation into the HTTP server might help. You may be doing some duplication in the crypto math anyway.
See if you would benefit from a cheaper algorithm or smaller key size on the client certs.
Once you validate a client cert, you could try caching a hash digest of it (or even the whole thing) for short time. That might save you from having to repeat the signature validations all the way up the chain of trust on every hit.
How often to your clients transact? If the ones making up the bulk of your transactions are hitting you frequently, you may be able to convince them to combine multiple transactions in a single SSL negotiation/authentication. Look into setting the HTTP Keep-Alive header. They may be doing that already to some extent. Perhaps your app is doing client cert validation on every HTTP request/response, or just once at the beginning of each session?
Anyway, those are some ideas, best of luck!

Resources