I'm working on IoT gateway which will collect data from IoT devices. IoT device is a constrained device which couldn't use HTTPS.
It sends periodically small amount of data - from sensors, with some aditional information as time, message id, unit id etc.
Right now we've got an implementation of gateway as REST API in Java open for everyone. So It accepts requests as JSON from any device, without ensuring that data comes from our device are not corupted or compromised.
Without having ability to secure data by HTTPS, what is the best way to design interface between gateway and device?
Without having ability to secure data by HTTPS, what is the best way to design interface between gateway and device?
You can still use a symmetric encryption/authentication to ensure integrity and confidentiality, which should be feasible even for low end devices
As an inspiration you may have a loot at JWE with a shared key.
You could limit replays using some timestamp/counter or having idempotent consumers.
Regardless that - missing tls/https ypu have to take care of a lot of things, such as how to protect a shared key, update if revoked, etc
If the device can't do https (with any set of cipher suites) you will probably have to make serious compromises and not have some aspects of a secure connection. A bit simplified, but https is pretty much the minimal full suite of how it can be done, there is nothing "unnecessary". You might not need everything, but it entirely depends on your usecase and threat model. Before implementing this, you should have a full understanding of exactly what https provides, and how, so you can use applicable parts. Also note that this is not at all straightforward to implement, a custom implementation will likely be vulnerable.
How constrained is your device really? There are small implementations of TLS that wouldn't require you to compromise on security such as wolfSSL.
Footprint sizes (compiled binary size) for wolfSSL range between 20-100kB depending on build options and the compiler being used.
Regarding runtime memory usage, wolfSSL will generally consume between 1-36 kB per SSL/TLS session.
Anyway, I would not recommend you try and implement your own cipher suite unless you REALLY know what you are doing.
Given the kind of tools you've mentioned having access to (HTTP/JSON), I suggest looking at JOSE, which is a standardized way of signing and encrypting this kind of data. Specifically you'll be interested in JWE, JWS, and JWT. The learning curve for JOSE is unfortunately somewhat steep and the docs are somewhat sparse, but it is quite effective and implemented on a variety of platforms, and will save you a lot of headache in inventing your own protocols (which is quite difficult to do correctly). I've had pretty good luck building custom systems around JOSE.
There are some key questions you need to ask:
Do you need mutual authentication, or only authentication of the device? If the device only writes and never reads, then you likely only need to authenticate the device and not the server.
Can you accept the risk of a single shared secret baked into the devices? The problem with a single shared secret is that if any device is reverse engineered, then all protection is lost until you phase out all devices with that key.
Can you accept the manufacturing cost of a per-device secret? Depending on your manufacturing process, generating a unique secret for each device may be difficult.
Can you accept the on-device storage space and processing requirements of a client certificate? If not, can you accept the logistics of maintaining a server-side database of every device's key? (If you can except neither, then you'll have to go with a single shared secret for the whole system.)
My gut feeling is you're talking about a device that can handle the complexity of a client cert, but not a full HTTPS stack. If you also can handle the complexity of generating a certificate during manufacturing, or your customers are willing to register their devices, then I recommend the following:
During manufacture or registration, generate a certificate and signing request. Send it to your server to be signed, and install the signed X.509 on the device. (Generating a CSR on the device is also an option, but many small devices lack the entropy to generate a decent random number. There are tradeoffs either way.)
Generate a certificate for the server, and install its public key on all devices.
Assuming the amount of data you're sending is small, I'd bundle it all into the JWT (web token), encrypted to the server's public key, and signed with the client's private key. Typically JWTs are used to exchange authentication information, but they're really just a standardized container for sending signed and encrypted JSON data, so they really can be anything you want.
In order to prevent replay attacks, the server needs to keep track of messages its seen before. There are two main approaches I like, depending on your situation:
Make the jti (JWT ID) a combination of the timestamp and a random value (in which case the server just needs to keep a cache of recent JTIs and reject too-old timestamps)
Make the jti a combination of the device id and a monotonically increasing message id. The server then needs to keep track of the last-seen message id for each device, and reject any ids less-than-or-equal to that.
If you don't need encryption, look at JWS instead, which just signs the data. None of these techniques require encryption, and it's a little simpler if you take that part out (you don't need a server certificate, for example). You can still prevent replays, and only allow trusted clients to connect. It is possible for someone to reverse engineer your device and pull out its client cert. The advantage of a client cert is that if you discover the abuse, you can then just ban that one cert. With a shared secret you can't do that.
The basic advantage of all of this is that JOSE is based on JSON, which is something you already understand and know how to parse and work with. But it's also reasonably compact for a string-based protocol. It's also extremely flexible in terms of algorithms, which makes it much easier to implement on smaller hardware. You could build all the same things by hand using public/private keys, but JOSE has already thought through many of the tricky security problems.
If only it were better documented....
I am new to Nservicebus and have recently started working in it. I am stuck on a point and need input from you guys. I have 2 asp.net core web api projects and I want to use NServicebus to send messages between both of them in some scenarios.
What I have found so far that I can provide name to EndpointConfiguration, what if one of my api is deployed on 1 server and 2nd on another server, in that case how my configuration should be?
I tried to gave url instead of name in EndpointConfiguration but it gave me exception.
Thanks in advance for your help
NServiceBus endpoints communicate over some messaging infrastructure your system will be using. Endpoint names represent queues messages sent to. Messaging infrastructure is abstracted by what NServiceBus is calling a Transport. You will need to decide on the transport you'd like to use (see the options here). Once you've decided what transport your solution will use, you could have a look at the samples for that specific transports to have an idea how to set up your endpoints.
For example, if you'll decide to use Azure Service Bus as your transport, you could download and try the Send/Reply sample.
A good starting point could be the tutorials available on the documentation site here.
How to integrate other languages than those from .net world? For example to access messages from the bus in Java or C++? Do I have to listen to the queue in the backend instead? Is there a common Api provided by Rebus?
While Rebus may market itself as a "service bus"(*), it is actually more a kind of a "driver" with a common abstraction that enables .NET programmers to use various queues and persistence technologies without worrying too much about the specifics.
As such, Rebus cannot really be connected to, much as you would not be able to connect to, say, the NpgsqlConnection or the SqlConnection you would use to communicate with your Postgres or SQL Server database.
What you could do, was to interface with Rebus at the transport and/or persistence level, e.g. by using the same wire-level format when exchanging messages.
This would require that the chosen transport (MSMQ, RabbitMQ, SQL Server, etc.) can be interfaced with from the desired platform, and then you would need to be able to supply the correct headers for Rebus to accept the message as valid.
There is no official Rebus implementation for any other platforms besides .NET (.NET 4.5 + .NET Standard 1.3).
To my knowledge, no one has attempted to actually build a Rebus-compatible messaging library on any other platform.
(*) I actually usually use the word "messaging library" to describe it, because I think it carries way less confusion and semantic overload with it.
Yes. I think we need to know a minimal message format that an application for example PHP can compose and send directly to an endpoint queue. That would make life easy in certain cases.
ASP.NET webservices use HTTP protocol to send/receive messages.
But the messaging protocol is SOAP
and SOAP makes use of XML.
This is right?
It is right to some extent, but it is not the whole truth!
I don't think that ASP.NET imposes many constraints on what formats you use to send/receive messages when you implement web services. After all, you're still on top of the .NET framework which offers a really wide variety of options.
That being said, HTTP is the application layer protocol used for message transmission with web services. But other protocol might also be used.
SOAP is XML-based, and is a commonly used as format of exchange of structured information. But you can also have REST services (see http://spf13.com/post/soap-vs-rest) that do not use SOAP. You can even exchange plain text or XML or some private format - it depends on your case.
It really depends on your purpose and the client applications you expect will consume the service. Is this an in-house service where you should follow some obscure internal protocols/formats of communication, or is it a service that has to be accessible from the web and must offer as much compatibility as possible? If it is the latter, go in a standardized manner with SOAP or REST.
Does Node.JS support sending binary data? or does it require a Base64 layer?
Also, how best would I create an encryption layer? I am expecting I will create a module that acts exactly like the net module (as it pertains to tcp client/server communication) and then just call an underlying net module.
However, I would like the encryption layer to be easily added to a file I/O stream. Would those two operations have to work different?
I know little about Node.JS but I know Java and browser based JavaScript very well.
Yes, Node.js supports binary data.
For encrypted communication it has built-in support for SSL / TLS.