1

Is there a reliable way in PHP to identify a device that might be behind a Router (so the IP is not unique)?

Background: I have several embedded devices (self programmed & adaptable) that contact a webserver (php+mysql) with status updates. These updates are then - if the source is confirmed - saved to a database.

  • As I understand it $_SERVER['REMOTE_ADDR'] usually can be trusted (except some IIS configuration where it may - under special circumstances - wrongfully return 127.0.0.1; but different story)

  • Anyhow since I use SSL, the IP address really should not be a problem, because a handshake is required and if the IP is faked or simply wrong, the connection should not be established

  • For now I require IP addresses to be whitelisted by admin, for an status update to be accepted

  • The device additionally sends the MAC address via $_POST to identify the different modules with identical IP address (I know this can very easily be forged, and right now will be trusted if the IP address is trusted)


So first of all I am not sure if the IP address in itself is enough for it to be safe from attacks from the outside

Secondly if the device is behind a router, it will have the same IP address as every PC/device on that network. So about anyone there could forge a status update with a fake MAC address (simply as post variable), and since the IP address is whitelisted it will be trusted

So is there any way of confirming the identity of a device, or do you know a better way of doing this?

Aside: Going the other way, and have the webserver poll the different devices might be an option, but since there might be many (> 2000) devices of which we need the very last status (change) I thought it to be inefficient.

I have also heard of using a signed certificate, or multiple (for different clients), but I don't know how to go about that, so thanks in advance for every bit of information.

Usually I don't post (a lot of) questions, but this is really hard to Google - at least for me!

1

2 Answers 2

2

Cryptographic point of view: the only way you can distinguish, from the outside, a fake device from a genuine one is by making the genuine device "know" some value that the attacker does not know.

This can be the equivalent of a "password" (since there is no human involved, that password can be a sequence of 40 random characters, i.e. something quite strong and thus unguessable by attackers). You can store that in a custom HTTP header, or the standard "Authorization" header, or as some cookie value, or encoded as a parameter in the URL; all of these are supported by most Web frameworks, both on client and server.

You can also use X.509 certificates. SSL supports client-side certificate authentication. In that case, the "secret" value on the device is an asymmetric private key (usually RSA) and you must arrange (with a custom PKI) for the issuing of one certificate per device. Certificates are cool if you don't want your server to keep a copy of the device secrets (or hashed version thereof), e.g. because you would like to deploy new devices without having to actually inform the server. If that's not a problem with you, the "password" method will be easier than dealing with certificates.

Either way, you certainly do not want to put the same secret value in any two distinct devices. You really want to have device-specific secrets; otherwise, someone "opening" one of your devices will endanger your whole system. With device-specific secrets, you can disable authentication for some known subverted devices, from the server, without impacting the other devices.


Without a device-side secret value of any kind, your problem has no solution. In the Internet Protocol, machines are isolated from each other; they only see IP addresses, which are not "protected" in any way. The scope of hardware elements such as MAC addresses stops at the first router (and they can be faked easily anyway).

7
  • As you said, it really would have to be device-specific to be safe. My problem now is that the secret should be calculated from "something" (IP, Serialnumber, ...), since programming the client-devices individually is not an option because of the amout of clients. So there would have to be some kind of pattern(?) to automate the assignment of keys, and patterns can be figured out :-/ ... so do you know of a way to safely (automatically) distribute keys or certificates already at the manufactoring point of the clients.
    – Levite
    Commented Jul 31, 2013 at 10:15
  • To get a device-specific secret, have it generate that secret value upon first boot, or generate it externally and then inject it. What may apply depends on the device hardware. For instance, if the device software is contained in a Flash chip, with the firmware loaded in factory, you could make "personalized" firmwares with an embedded key. Even on-board key generation can be done for smart cards, with millions of cards.
    – Tom Leek
    Commented Jul 31, 2013 at 11:11
  • How would you go about creating the secret upon first boot? Would you do that by creating an encoding (eg. md5) of macaddress + random value (based on time maybe). But more importantly how is it that with certificates I won't have to inform the server when deploying new devices; could an attacker not in the same way as my devices issue a certificate? How would the PKI know the difference between those? Anyways great answer, since these are just follow ups, I accept it either way.
    – Levite
    Commented Aug 22, 2013 at 9:41
  • A "first boot" secret is either generated by the device itself (assuming it has a source of good randomness, which might be easier in factory conditions) or generated outside and injected in the device (there again while the device is still in the factory, typically when the firmware itself is pushed into the device). A secret is something unknown by outsiders so there is no point in using time and/or the MAC address, both being public values. A good secret key is pure uniform unpredictable randomness.
    – Tom Leek
    Commented Aug 22, 2013 at 12:17
  • 1
    You don't want different secrets, you want unpredictable secrets, which is something much stronger. To illustrate the concept, imagine a simple counter, incremented with each device: first device gets a 1, second device gets a 2, and so on. All devices get different values, but it would be preposterous to claim that there really is a secret there. Basically, you cannot get secrets out of deterministic operations (e.g. hashing) over public data (e.g. MAC address and current time).
    – Tom Leek
    Commented Aug 22, 2013 at 13:08
1

if the device is behind a router...anyone there could forge a status update with a fake MAC address

MAC addresses don't cross routers.

have the webserver poll the different devices might be an option

Tricky when you don't know their IP addresses / they are behind NAT routers.

is there any way of confirming the identity of a device

Possible solutions:

1) use SSL for data exchanges, and only accept data from devices that include a shared secret in the request (GET/POST/Cookies).

2) Use SSL with Client certificate authentication

3) use a challenge based authenticaton mechanism - note that HTTP digest authentication has a number of issues which reduce it's effectiveness in the absence of SSL - and with SSL, there's not great advantage over standard HTTP authentication

4) validate the request against a time varient hash (subject to replay attacks within time window, requires clock synchronization), e.g.

url="http://yourserver.com/beacon?device=me";
var t = new Date();
t=t.getTime();
url+="&t=" + t;
var hash=md5(url+"sharedSecret");
url+="&hash=" + hash;
3
  • I meant the MAC that is transmitted via POST: "The device additionally sends the MAC address via $_POST to identify the different modules with identical IP address" But going with solution 1 seems to be a good starting point, unless I get my head around certificates
    – Levite
    Commented Jul 31, 2013 at 9:59
  • Polling would be a possibility still, since there would (most likely) be port-forwarding anyways for every device to (remotely) debug them individually. The problem would be with a lot of clients, that polling is very inefficient, since I only need the last status change.
    – Levite
    Commented Jul 31, 2013 at 10:05
  • 4) looks like a great alternative. At least when I put the data (=device status) information also into the hash. Which would make it (in my case) unproblematic, even if a replay attack occured (since only possible in a specific timespan). Thanks!
    – Levite
    Commented Aug 22, 2013 at 8:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .