We are currently working on a data-backup kinda project. We ship our own hardware to industrial customers. This hardware will then read out all related data the customer wants to backup and sends them to a cloud server using MQTT (Node.js Client and Mosca MQTT Broker).
Now my questions are:
Is there a free TLS certificate that i can use for my MQTT connection? The only ones that i found require a domain name.
To incease security, we are using JWT. We don't have any database though. The Token will be passed as an MQTT-Password argument. Is there a better alternative?
Is a self-signed TLS certificate bad practice even if the private cert
is not publicly available? It will only be shipped embedded into our
hardware and to our verified customers.
Of course it is bad practice (very bad practice). Get a certificate from a proper CA authority. Unless you want your company to be sued into the stone-age for a security breach.
Is there a free TLS certificate that i can use for my MQTT connection? The only ones that i found require a domain name.
The certificate "certifies" that the information is provided by a specific entity, where the entity is defined as "a domain name".
Asking for a TLS certificate which doesn't back to a domain name is like asking for a certified check drawn on a company that doesn't have a name.
To incease security, we are using JWT. We don't have any database though. The Token will be passed as an MQTT-Password argument. Is there a better alternative?
Yes, there is a better alternative. Have some sort of database (it can be a file system, it doesn't need to be a full-fledged SQL database) hold and manage the created tokens. Without a database to validate the tokens against the current expected values, any kind of token based security (JWT or otherwise) will be useless, as you can't determine if the token is currently valid.
Credential reuse (the replay of should-be-expired credentials) is a major security hole. All one needs to do is obtain the token, and then all future communications are accepted with the same credentials. This is closed by holding the tokens in a database, and expiring the tokens after some time by removing the tokens from the database. This means that any possible breach is limited to a shorter time span.
Without any kind of database, I can only guess that you might be permitting any access with an existing token, meaning that all your tokens are effectively valid forever, as they will be accepted if they exist. You need to possibly modify, and certainly validate, that expired tokens don't grant access to the controlled operations.
Your clients will connect to your MQTT broker, for this to be secure you will need a certificate which is tied to the address (domain name) the broker is running on. Clients need to know that the server they are talking to is authentic, the information needed for this is inside the certificate. If you're looking for a free certificate you could look at Let's encrypt
As for the JWT token, why are you looking for a better alternative? What issues doe you see?
Related
I am building up a small iot-like system, where mqtt devices(clients) are sending and receiving security-related critical information or commands.
I have got to know that TLS connection can be built optionally without client authentication thru PK certificate on the client side.
Normally, mqtt client devices don't have enough resources to support PKI, where at first it has to store a certificate and from time to time, to update it with newly issued ones when validity has passed or when the original certificate has been revoked.
That was, I think, why many of mqtt brokers have an option to configure on/off the client authentication during TLS handshake.
However, my concern is if there would be any security issue from passing the client authentication step, like, for example, a chance that some other malicious devices impersonating one of my devices can connect to the broker could obtain those critical information and commands.
My question is what best options and practices I can take to minimize that kind of risk considering the constraint resource of devices.
Missing client authentication means that everybody including an attacker can claim to be a valid client. There can be use cases like public services where this is not a problem and there are other use cases where the server wants to restrict access to specific known clients only.
There is no definitive answer to this question, it will always depend on the following factors, and only you as the designer can answer them:
What is the threat model you are working with? E.g. Who are you trying to keep out of the system and why, what are the consequences of somebody connecting a rouge client?
How much are you prepared to spend? If you intend to deploy client certificate or even a unique username/password for each device, how will it be protected? Does the hardware you intend to use support a secure enclave/hardware secret store? Meaning how hard would it be for an attacker to extract the client username/password or secret key from the device?
What other security measures do you have in place? Do you have Access Control Lists to protect which topics a client can publish/subscribe to? Do you have monitoring in place to detect malicious actions from clients so they can be disconnected and banned?
I ask this because I work on an application where the X-AUTH-TOKEN can be copied from one request to another and impersonate another person. This makes me nervous, but I'm told since we're going to use HTTPS we don't have to worry about anything.
So, my question is: Is it good enough trust SSL to protect against stealing headers used for auth/sessions?
Thanks,
Using HTTPS encryption will indeed prevent someone from stealing your authentication token if they can intercept the traffic. It won't necessarily prevent a man-in-the-middle attack though unless the client enables peer certificate checking.
This question from the security stackexchange describes how to implement MITM attacks against SSL. If I can convince a client running HTTPS to connect to my server, and they accept my certificate then I can steal your authentication token and re-use it. Peer certificate validation is sometimes a bit of a pain to setup but it can give you a higher chance of whomever you are connecting to are who they say that are.
"Good enough" is a relative definition and depends on your level of paranoia. Personally I would be happy that my connection is secure enough with HTTPS and peer certificate validation turned on.
Presumably also your authentication token times out so the attack window would be time limited. For example the OpenStack authentication token is by default valid for 24 hours before it expires and then you are required to obtain a new one.
The HTTPS standard implements HTTP entirely on top of SSL/TLS. Because of this, practically everything except for the DNS query is encrypted. Since headers are part of the request and response, and only sent after the secure-channel has been created, they are precisely as secure as the implementation of HTTPS on the given server.
HTTPS is an end-to-end encryption of the entire HTTP session, including the headers, so on the face of it, you should be safe from eavesdropping.
However, that is only part of the story: depending on how the clients are actually connecting (is this a website or an API service?), it may still be possible to trick them into sending the data to the wrong place, for instance:
Presenting a "man in the middle" site with an invalid SSL certificate (since it won't be from a trusted authority, or won't be for the right domain) but convincing users to by-pass this check. Modern browsers make a big fuss about this kind of thing, but libraries for connecting to APIs might not.
Presenting a different site / service end-point at a slightly different URL, with a valid SSL certificate, harvesting authentication tokens, and using them to connect to the real service.
Harvesting the token inside the client application, before it is sent over HTTPS.
No one approach to security is ever sufficient to prevent all attacks. The main consideration should be the trade-off between how complex additional measures would be to implement vs the damage that could be done if an attacker exploited you not doing them.
Hopefully a quick question.
I want to secure my WCF service that will be consumed by a known party. Our organisation trust theirs and vice versa.
This service is already restricted by IP address, so we know the caller must have come from their network.
However I would like it to be protected against malicious developers within that organisation. In theory they could write a Bad App and install it anywhere on this network, and call our service, which would return the data.
I think a way around this would be to also use Client Certificates, which would be validated using Peer Trust. Each request would send this certificate, which we would validate on the WCF service, and send back the data.
My question - is this going to protect against the malicious developer scenario outlined above? We would know that the request would have to originate on the server with the client certificate installed (right?) - and I imagine it should be difficult for a malicious developer to get a Bad App on there. It is a shame we can't tie it down to exactly the client application - or could we?
Any help appreciated - just want to make sure I nail my understanding of this!
If you will be granting access to your service based on the specific incoming client certificate, it should be as secure as the private key of that certificate. That is, if the private key is kept safe in the other organization, your service will be as safe (as safe as that public/private key pair of the certificate in terms of encryption).
If the private key is compromised within the other organization, for example, an attacker has access to it on the remote server, or is able to copy it to another remote server, then that attacker has access to your service. Because, once they have the private key, they can use the client certificate to connect using an SSL connection, and then they just have to pass the IP address check. Protect the client certificate's private key.
You may check on the service side if the client has authenticated itself with specific certificate. You may also write Custom Certificate Validator and validate certificate according to your own needs. However, if you assume that the attacker may be able to use private key of trusted certificate in your environment, then I guess you may assume that the attacker can basically do anything and there is no way you can secure your service.
I have a WCF service and client which is going to be deployed to several companies (hundreds). Some companies will run the software in their network and some will run it over the Internet (WCF server at on office, WCF client at another).
We want to encrypt the communication between the WCF server and client. We don't have any need to authenticate the cient / subscriber using WCF security, because we have our own username/password log-in which the clients will use to log on the server.
We can't rely on Windows auth because some of the users will run it over the Internet, and the WCF server may not be on the same domain as the WCF client.
If we use "real" certificates*, companies running the software would have to purchase certificates from a CA and install it, and then configure our software to use it, but this is too complicated for most of them.
We could auto-create certificates during installation of the WCF server, but then we would have to automatically install it into a certificate store and somehow automatically grant IIS permissions to read the certificate. This is more complicated than we would like.
In short, we want a simple solution where the encryption is just based upon a shared secret, in our case the username / password the user is logging on with. I do understand that this won't give the best available encryption, but we're willing to trade some of the security to make the software easier to deploy.
Is this possible?
*With "real" certificates, I mean certificates purchased from a certificate authority, and not one I've created myself / self-signed.
If you want to encrypt the messages on the transport (which is a really good idea!), there has to be some shared knowledge between the sender (the client) and the server. This can be hardcoded, but that's really not a good idea at all - if that "common shared" knowledge is ever compromised, an attacker could decipher and read all your messages.
Also, since it's definitely not recommended practice, there's no support of any kind in WCF to simplify using a shared secret. You're on your own - you have to roll your own 100% of the way.
The only viable way to have a common shared secret exchanged in a safe way is to use a certificate. No way around this, sorry. The certificate doesn't even have to be used for user authentication or anything - but it establishes a shared secret between the caller and the service and thus allows the caller to encrypt the messages in such a way only the intended recipient can actually decrypt and use them.
So I really don't see any way you can get around having certificates on your servers - doesn't need to be on every client, but on every server where your service runs.
Marc
PS: if you really want to investigate the "hardcoded shared secret" approach, you'll need to think about this:
how do you store a shared secret safely on each and every single one of your clients?
how do you use information from that stored shared secret to encrypt your messages?
Typically, the approach would be two-fold:
exchange some form of a private/public key pair; the server generates a key pair and keeps the private key to itself and shares the public key with the client (e.g. over a WCF message, for instance)
using that private/public key pair, exchange a common shared secret, e.g. an "encryption key" that will symmetrically encrypt your messages (and since it's symmetrical, the server can use the same key to decrypt the messages)
setup infrastructure on your client (e.g. a WCF extension called a behavior) to inspect the message before it goes out and encrypt it with your shared secret
All in all, it's really not trivial - anything simpler than that is not worth being called "security" at all.
If you look at all that work you will have to do - wouldn't it be easier to just use the WCF built-in certificate mechanisms??
Decent security worth its salt is hard - so why not leverage what's available instead of doing all the work yourself, or worse: come up with a half-baked solution that's so easy to crack you could just as easily send everything in cleartext..... don't under estimate the complexity and amount of code needed to handle even the most basic security scenarios - WCF does this all for you - for free and in a reliable and safe manner - use it! You won't regret it!
Well, with WCF you could use Password credential at message level and SSL at transport level, which I think would be enough in your case.
See here.
For message security, your client provides some credentials and server provides some credentials. For this setup and with your scenario could you not use the client username and password with a Custom Username Validator, and a server certificate to provide the server credentials. This Application Scenario provides a fair chucnk of the configuration setup you would need to achieve this, except the aspNet membership sections, which you would have to replace with your custom validation config.
You would still need valid certificates on your servers (no certificates required on the clients), but I can't see any way around this.
Take a look at the following sample:
http://www.codeproject.com/KB/WCF/wcfcertificates.aspx
It uses certificates but without a certificate store - so no setup is necessary.
Hmm.. maybe something simple could be used. Move the encryption from software to hardware. VPN from each client network to your own and then you can do whatever you like for WCF transport. The line is not clear text and the problem is solved.
Of course this is easier said than done, but most network vendors provide a pretty easy VPN config and it maybe easier than trying to develop an installer for SSL certs and configure the client.
I hope it helps!
I work at company X and we want to engage in a B2B transaction with company Y. In doing so, Y is requiring client side authentication; they already provide server-side authentication - so this would be a mutual SSL transaction.
My understanding is that I simply need to provide my CA-signed cert as part of my client side HTTPS communication. In doing so, asymmetric cryptographic guarantees (i.e., public/private key technology) ensures that I am who I claim I am - in effect, it is not possible to impersonate me. (the root CA has ensured I am who I am, that is why they signed my cert, and it's possible to prove that I didn't "manufacture" the certificate).
Here's my question: is this all I need to provide company Y?
Alternatively, do I have to provide them with another key in advance, so that they can ensure I am not a rogue who happens to have "gotten a hold" of a root-signed certificate for me (company X)? It would seem that if one has to provide this extra key to all parties he wishes to engage with on the client side, it would seem to make client-side SSL not as scalable as server-side SSL. My guess is that it's not possible for one to "get a hold" of a client side cert; that the actual transmission of the client side cert is further encoded by some state of the transaction (which is not reverse-engineerable, feasibly).
Does this make sense and am I right or am I wrong? If I'm wrong, does Y in effect need to get an "extra" pre-communication key from every party that connects to it? (which they want to verify)?
Thanks.
===
Thanks for the responses below, at least the first two have been helpful so far (others may arrive later).
Let me talk in a bit more detail about my technical concern.
Suppose company Y attempts to "re-use" my client side cert to impersonate me in another client-side transaction with another company (say "Z"). Is this even possible? I am thinking - again, perhaps poorly stated - that some part of the transmission of the client side certificate prevents the entire key from being compromised, i.e., that is not technically feasible to "re-use" a client certificate received because you could not (feasibly) reverse engineer the communication which communicate the client cert.
If this is not the case, couldn't Y re-use the cert, impersonating X when communicating (client-side) to Z?
ps: I realize that security is never 100%, just trying to understand what is technically feasible here and what is not.
Thanks very much!
===
Further technical details, I appreciate any additional input very much - this has been very quite helpful.
From a layman's point of view, my concern is that when a client sends his client cert, what is he sending? Well, he has to encrypt that cert using his private key. He sends the ciphertext with the public key, and then a receiving party can use that public key to decrypt the private-key-encoded payload, right? That makes sense, but then I wonder -- what prevents someone from hearing that communication and simply re-using the private key encoded payload in a replay attack. Just replay the exact ones and zeroes sent.
Here's what I believe prevents that -- it can be found in the TLS RFC, in multiple places, but for example in F.1.1:
F.1.1. Authentication and key exchange
TLS supports three authentication modes: authentication of both
parties, server authentication with an unauthenticated client, and
total anonymity. Whenever the server is authenticated, the channel is
secure against man-in-the-middle attacks, but completely anonymous
sessions are inherently vulnerable to such attacks. Anonymous
servers cannot authenticate clients. If the server is authenticated,
its certificate message must provide a valid certificate chain
leading to an acceptable certificate authority. Similarly,
authenticated clients must supply an acceptable certificate to the
server. Each party is responsible for verifying that the other's
certificate is valid and has not expired or been revoked.
The general goal of the key exchange process is to create a
pre_master_secret known to the communicating parties and not to
attackers. The pre_master_secret will be used to generate the
master_secret (see Section 8.1). The master_secret is required to
generate the certificate verify and finished messages, encryption
keys, and MAC secrets (see Sections 7.4.8, 7.4.9 and 6.3). By sending
a correct finished message, parties thus prove that they know the
correct pre_master_secret.
I believe it's the randomization associated with the session that prevents these replay attacks.
Sound right or am I confusing things further?
As long as you keep the private key safe (and the CA keeps their signing key safe), "company Y" doesn't need any other information to authenticate you. In other words, they can be sure that a request really came from the subject named in the certificate.
However, this doesn't mean that you are authorized to do anything. In practice, most systems that use client certificates have an "out of band" process where you provide the "subject" distinguished name that is specified in the client certificate, and the system assigns some privileges to that name.
In fact, because of some practical limitations, some systems actually associate the privileges with the certificate itself (using the issuer's name and the certificate serial number). This means that if you get a new certificate, you might have to re-enroll it, even if it has the same subject name.
A certificate only assures a relying party you have a certain name. That party needs some additional mechanism to determine what you are allowed to do.
Unlike authentication mechanisms based on "secret" (symmetric) keys—e.g., passwords—a server only needs public information for asymmetric authentication. A private signing key should never be disclosed; it's certainly not necessary for client authentication.
With symmetric, password-based authentication, the client and server get access to the same string of bytes—the secret key. With public-key cryptography, only the public key of a key pair is disclosed. The corresponding private key is never disclosed, and no practical method for figuring out the private key from the public key has been discovered.
As long as you keep your private key safe, the server at company Y cannot forge requests that appear to come from you.
Client authentication replay attacks are defeated by requiring the client to digitally sign a message that includes a number randomly generated by the server for each handshake (this is the "random" member of the "ServerHello" message). If the packet used to authenticate the client in a previous session were re-used, a server will be unable to verify the signature, and won't authenticate the replay attack.
RFC 2246, Appendix F.1.1.2 might be a more helpful reference—especially the third paragraph:
When RSA is used for key exchange, clients are authenticated using
the certificate verify message (see Section 7.4.8). The client signs
a value derived from the master_secret and all preceding handshake
messages. These handshake messages include the server certificate,
which binds the signature to the server, and ServerHello.random,
which binds the signature to the current handshake process.
Your client-side certificate (or more precisely its private key), is only as secure as your company's online and/or physical security let it be.
For extremely secure relations (which typically do not have the requirement of scaling much), it may be acceptable that the provider of the service requires an extra element in the protocol which allows them to identify your site (and more often than not, to identify a particular computer or individual within the company, which is something client certs do not fully do.)
This of course brings the question: what is warranty that this extra bit of authentication device will be more securely held by your company? (as compared to the client-site certificate itself). The standard response for this is that these extra bits of security elements are typically non-standards, possibly associated with physical devices, machine IDs and such, and are therefore less easily transportable (and the know-how about these is less common: hackers know what RSA files to look for, and what they look like, what do they know of the genesis and usage of the KBD-4.hex file ?)
Extra question: Can Y make use of my client-side certificate elsewhere?
No they [normally] cannot! The integrity of this certificate lies in your safe keeping of its private key (and, yes, a similar safekeeping from the certificate providers...). Therefore, unless they are responsible for installing the said certificate, or unless their software on your client (if any) somehow "hacks" into certificate-related storage / files / system dlls, they should not be able to reuse the certificate. That is they cannot reuse the certificate any more easily (which is theoretically NP hard) than anyone that, say, would sniff the packets related to authentication as the client establishes a session with the Y site.
Extra questionS ;-)
- What is the nature of the client cert?
- Man-in-the-middle concerns...
Before getting to these, let's clear a few things up...
The question seems to imply TLS (Transport Layer Security) which is indeed a good protocol for this purpose, but for sake of understanding, the keys (public and private) from the certs (server's and client's) could well be used with alternative protocols. And also, TLS itself offers several different possible encryption algorithms for its support (one of the initial phases of a TLS session is for both parties to negotiate the set of algorithms they'll effectively use).
Also, what goes without saying... (also goes if you say it): the respective private keys are NEVER transmitted in any fashion, encoded or not. The confusion sometimes arise because after the authentication phase, the parties exchange a key (typically for a symmetric cipher) that is used in subsequent exchanges. This key is typically randomly generated, and of totally different nature than the RSA keys whether public or private!
In a simplified fashion, the client's certificate contains the following information:
- The Certificate Authority (CA aka issuer)
- The "owner" of the certificate (aka Subject)
- Validity date range
- the PUBLIC key of the certificate
In more detail, the certificates are typically found in an X.509 wrapper (? envelope), which contains additional fields such as version number, algorithm used, certificate ID, a certificate signature (very important to ensure that the certificate received wasn't tempered with). The X.509 also provide for optional attributes, and is also used for transmitting other types of certificate-related data (such as the CRL)
Therefore the certificate's content allow the recipient to:
- ensure the certificate itself was not tempered with
- ensure that the issuer of the certificate is one accepted by the recipient
- ensure that the certificate is valid/current and not revoked
- know the public key and its underlying size and algorithm
With regards to man-in-the-middle concerns, in particular the possibility of "re-playing" a possibly recorded packet exchange from a previous session.
The protocol uses variable, possibly random MACs (Message Authentication Codes) for that purpose. Essentially, during the negotiation phase, one of the parties (not sure which, may vary...) produces a random string of sorts and sends it to the other party. This random value is then used, as-is (or, typically, with some extra processing by an algorithm known by both parties) as part of the messages sent. It being encoded with the private key of teh sending party, if the the receiving party can decode it (with sender's public key) and recognize the (again variable) MAC, then it is proof that the sender is in possession of the private key of the certificate, and hence its identity is asserted. Because the MACs vary each time, pre-recorded sessions are of no help (for this simple purpose).