This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Communeguy's profile picture

Stab at a Keysystem

Started by Communeguy, 29 March 2016 - 11:15 PM
Communeguy #1
Posted 30 March 2016 - 01:15 AM
I'm building a city - as one does - and among the various structures in the city is a ReactorCraft reactor complex. While I'm building in single player, I intend to eventually move the map to a server once it's built, so securing the complex proper occurred to me. I was planning on doing this using Immibis's RFID system, but I need to make sure the system archetecture makes sense, which is why I am here.

Originally, I intended to simply have an RFID reader at the complex gate to let you in or out. This is kind of a second layer of security already, since reaching the gate means having the right Rail Ticket, but that's neither here nor there, and ultimately you could walk. It occurred to me later, while planning, that different parts of the facility should be more or less accessable.

Eventually, I boiled this down to a credential system with three levels 1-3, with 1 being an admin with (basically) root access, 2 being complete access, and 3 being access to only reactor control (I know that sounds weird, but it's less dangerous to let people turn the damn thing on or off than it is to let them at any of the machinery or fuel directly).

What I envision is this:
-1. RFID-sensing Door Lock
–Reads Nearby RFID
–Sends the hash of the RFID code to the Server
–Waits to be told to open the door or not
–Loops
-2. Admin Terminal
–Authenticates an Admin (somehow - against the server?)
–Sends messages to the server to add/remove users or update their clearances
–Can request the (encrypted and replacement) RFID code for a given user and print it to an RFID Card
-3. The ServerTM
–Holds UserID, RFID Hashes, and Level
–Also holds DoorID and Level
–Receives hash of inputted RFID and Door ID
–Checks if RFID hash has Level <= the Door ID's level
–Sends the Open Signal. Or Doesn't.
–Updates the DB when told to by the admin terminal
–Regenerates a new RFID code for a given user on request and sends it to the admin terminal to write, probably encrypted

Vulnerabilities Are:
-If network is tapped and sniffed you could get the hash of RFIDs, but you shouldn't be able to reverse that.
-You MIGHT be able to get the admin credential, unless that's hashed too.
-If you pulsed open signals on a network tap you could theoretically force a door to open by standing near it with ANY RFID card.
-There's absolutely nothing to suggest that an RFID card can't be copied, but I can't think of a good second factor for this system

Apparent Strengths:
–Passwords are not Sent in the Plain
–Passwords are not stored in the plain
–Doesn't need users to remember anything apart from bringing their keys with them
–Keys can be invalidated if lost or privelages are abused.
–Server means that one operation removes, adds, or updates a user for the whole facility, instead of walking around to update individual doors.

Anyone see any vulnerabilities or fixes? I intend to build the code myself, but I've never had to secure a system at all, and I rarely network. I don't intend do do my own crypto - various hash codes in LUA already exist. If the code works, I will probably reuse it in multiple complexes/buildings throughout the city.

Thanks for input, Sorry to bore;
–CG
KingofGamesYami #2
Posted 30 March 2016 - 02:01 AM
Hashing doesn't make one whit of difference if you're sending that data over rednet - it's easy to spoof any computer ID on a rednet message, so any computer could receive/send that hash.

What you need is a rolling code.

I'm unfamiliar with RFID, however I believe Dog created a system for it; you might look at that.
Communeguy #3
Posted 30 March 2016 - 02:32 AM
I knew there had to be a way to prevent replay attacks, I just couldn't think for the life of me how. Am I right in thinking I could salt the RFID-Hash with the rolling code to verify both "this is a valid signal" and "this person is trying to open the door"?

I mean, really, the only points of access into the network (apart from the admin terminal) are all buried, and the admin terminal itself is behind locks. If we're at the part where people are breaking blocks to get into the network, they could just knock down walls in the facility and take stuff that way.

Thanks though. I'll factor this sort of thing into my thinking.
Dog #4
Posted 30 March 2016 - 02:32 AM
I'm unfamiliar with RFID, however I believe Dog created a system for it; you might look at that.
Actually, I haven't done anything for Immibis' Peripherals - not sure why, either…

FWIW, I did find 2 RFID programs for Immibis' Peripherals here and here for reference.
Edited on 30 March 2016 - 12:33 AM
Communeguy #5
Posted 30 March 2016 - 02:59 AM
I'm unfamiliar with RFID, however I believe Dog created a system for it; you might look at that.
Actually, I haven't done anything for Immibis' Peripherals - not sure why, either…

FWIW, I did find 2 RFID programs for Immibis' Peripherals here and here for reference.

Thanks for these!
KingofGamesYami #6
Posted 30 March 2016 - 03:38 AM
I knew there had to be a way to prevent replay attacks, I just couldn't think for the life of me how. Am I right in thinking I could salt the RFID-Hash with the rolling code to verify both "this is a valid signal" and "this person is trying to open the door"?

I mean, really, the only points of access into the network (apart from the admin terminal) are all buried, and the admin terminal itself is behind locks. If we're at the part where people are breaking blocks to get into the network, they could just knock down walls in the facility and take stuff that way.

Thanks though. I'll factor this sort of thing into my thinking.

What I would do, not saying it's ideal or anything, is use the rolling code as the "password" for an encryption / decryption function. I know AES was ported to CC a while back, you could use that.
Communeguy #7
Posted 30 March 2016 - 04:49 AM
I am now arriving at an impasse my flowcharts can't solve.

For obvious reasons, it's important to verify both that the client (that is, the door) and the server are who they say they are. You would think this would be as easy as setting a couple name variables and asking for them upon an exchange, but that's easily spoofed. Do I need to do something similar to RSA signature creation where I *insert overcomplicated explanation of how signatures work here*, and the server says "Yup, that's a valid client" and the client says "Yep, that's the server I want"? Is that spoofed easily? Is there a more elegant solution? I am thinking of something similar to a certificate, but I can't think of how to do it without some secret or another being stored on the client side.
Edited on 30 March 2016 - 02:51 AM
Bomb Bloke #8
Posted 30 March 2016 - 07:01 AM
In general, there's nothing stopping one user from sitting down next to a given computer - assuming their character has physical access to it - and copying everything off it to a new computer. That new system, assuming it knows the ID of the old one, would then be able to mimic it pretty much perfectly.

This is glossing over a few details (there are some checks you can put in to attempt to prevent this, and these can in turn be coded around by your attacker, and so on), but the winner boils down to whether it's you or your attacker who has the most free time to kill.

Assuming you prevent such access, a rolling code is really all you need. So long as no one gets their hands on the key used to generate the code sequence, you're all good. Your server knows the codes are coming from the client because only the client has the correct key.

If you're going to be one of the OPs on this server, then you have the option of using Command Computers. These can only be accessed by OPs in creative mode - you can hook up external buttons or a monitor or something to allow other users to interact with the scripts you run on them, but they otherwise can't play with the things.

Without using those, you still have the option of warded blocks and so on from other mods.
Communeguy #9
Posted 31 March 2016 - 02:42 AM
In general, there's nothing stopping one user from sitting down next to a given computer - assuming their character has physical access to it - and copying everything off it to a new computer. That new system, assuming it knows the ID of the old one, would then be able to mimic it pretty much perfectly.

This is glossing over a few details (there are some checks you can put in to attempt to prevent this, and these can in turn be coded around by your attacker, and so on), but the winner boils down to whether it's you or your attacker who has the most free time to kill.

Assuming you prevent such access, a rolling code is really all you need. So long as no one gets their hands on the key used to generate the code sequence, you're all good. Your server knows the codes are coming from the client because only the client has the correct key.

If you're going to be one of the OPs on this server, then you have the option of using Command Computers. These can only be accessed by OPs in creative mode - you can hook up external buttons or a monitor or something to allow other users to interact with the scripts you run on them, but they otherwise can't play with the things.

Without using those, you still have the option of warded blocks and so on from other mods.

Thanks Bomb Bloke - I think you're right, using certs would be a waste of time, both in terms of complexity and reproducability.

Before I go even more prematurely Grey coding this, I just want to make sure the following process makes sense. Note that I only describe the "open the door" process here. Note that there's no step to prevent from sending the RFID data to the wrong server - someone's not going to use my client code to copy the extant RFIDs. They're going to build some elegant five-line copy thing to just keep copying to RFID cards and then try the products until they work. This is the problem with single-factor authentication. I'm also not sure this really counts as a "rolling code", since I can't figure out how to make one work for multiple "keys" in a network, but lets try.
  1. A given client detects the RFID signal and records the RFID data to memory. This gets zero'd eventually.
  2. The client takes the [bleh] hash of its own ComputerID variable.
  3. The client uses hashComputerID as the symmetric encryption key for a message to the target server, containing it's programmed Door ID variable.
  4. The server knows the hashes for all valid (pre-authorized) doors. It tries them all in sequence and verifies that the transmitted doorID and the expected DoorID are the same. DoorID is a configuration variable and NOT the computer ID.
  5. REGARDLESS OF SUCCESS: The server sends a go-ahead code. It then disregards all further communications for 30 seconds if it failed to authenticate. This is done so that the client itself is not notified if it failed to transmit. This code is single-use, which is important.
  6. The client, upon receipt of the message from the server, hashes that to a standard bitsize and again uses it as an encryption key.
  7. The client hashes the RFID data and transmits that, encrypted using the above key.
  8. The server compares the recieved-and-decrypted hashRFIDData to a table of known hashes and authorization levels, possibly indexed by user (for logging purposes? Later feature?)
  9. The server makes sure that the clearance level is sufficient for the door it believes it is talking to.
  10. If successful, the computer sends a pass message TRUE, using the same sequential key. If not, it sends false.
  11. On reciept of "true", door opens, on the receipt of false, it doesn't.
  12. Client clears its RFID Data variable, possibly by writing a random value to it.
  13. GOTO1.
I'm sure there's flaws in this galore, but I am old and tired and I don't know what they are just yet.

ETA: In fact, this doesn't even roll properly from the client side, making the server vulnerable to replay attacks. One possible solution would be to do something like use hash(compID * return of os.time()) with adequate imprecision.
Edited on 01 April 2016 - 01:47 AM