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

Blink - Communication API with Sender Verification!

Started by KingofGamesYami, 23 July 2016 - 12:49 AM
KingofGamesYami #1
Posted 23 July 2016 - 02:49 AM
Blink is essentially a replacement for rednet, adding a way to verify the identity of the sender. This does not encrypt or otherwise secure your messages!
Installation
pastebin get YGTnaHtd blink
Usage
Setup
This doesn't have to happen every time you run the program, your choices are automatically saved to a file
Before transmitting messages, you must tell the sender what it's secret key is. This is done using setDeviceKey.

blink.setDeviceKey( "MySecretPassword" )
After this step, you must tell the receiver what that key was. This is done using pair.

blink.pair( SENDER_ID, "MySecretPassword" )
SENDER_ID is the id of the sending computer with that secret key. This can be obtained by running "id" in the shell of that computer.
Starting Up
While your computer is sending or receiving messages, blink.run must be running in parallel with your program. This would look something like this:

parallel.waitForAny( blink.run, function()
--# your program here
end )
If you wish to use an alternative means of running blink.run, such as multishell or statemachine, you are welcome to do so. However, this is by far the simplest way to use it.
Sending and Receiving Messages
The receiving computer must be paired and blink.run must be appropriately integrated
To send a message, you need to know the ID of the computer you wish to contact in addition to your message contents. Optionally, you can specify a timeout, because the function will hang indefinitely if the receiver is not available.

local success = blink.send( 3, "Hello, World!", 1 ) --#sends "Hello, World!" to computer 3 (times out after 1 second)
To receive a message, you can either pull a "blink_message" event or use blink.receive.

local id, message = blink.receive( SENDER_ID )
SENDER_ID must be the id you wish to receive from. The function need not return id, but I do so to retain some similarity with recnet.receive.

local event, message, from = os.pullEvent( "blink_message" )
Really not anything to explain here, if you're at all familiar with the computercraft event system.
Features
  • All computers act as repeaters, therefor a repeat program is as simple as os.loadAPI( "blink" ) blink.run()!
  • Passwords are not send directly, preventing repeat attacks. They are stored in plaintext, however, since any user with access to the computer would be able to send messages as that computer (duh)
  • Automatically finds a wireless modem and opens it. Will provide an error message if no wireless modem is detected.
  • Automatically downloads hash API
  • Saves paired devices and own private key (insecurely, for reasons mentioned above)
Credit
Anavrins, for his sha256 API (downloaded as "hash" automatically).
Alex Kloss for the implementation of base64 I'm using
*Credits are given in more detail in the code itself.
Edited on 24 July 2016 - 12:14 AM
MKlegoman357 #2
Posted 23 July 2016 - 10:15 PM
You should add ability to open the modem yourself (there might be modems already in use or I'd simply want to use a wired modem) and the send method should have a timeout (send(id, message, [timeout])) because right now the computer might hang if the receiving computer is not available.

Otherwise, great API!
KingofGamesYami #3
Posted 24 July 2016 - 02:11 AM
the send method should have a timeout (send(id, message, [timeout])) because right now the computer might hang if the receiving computer is not available.

I agree 100%, can't believe I missed that. I've added this already.

You should add ability to open the modem yourself (there might be modems already in use or I'd simply want to use a wired modem)

I'm thinking about this. I don't know what the best way to set the modem is, I like it being automated myself. I see the point about wired modems though. Perhaps default to wireless, but fallback on wired if I can't find one?
MKlegoman357 #4
Posted 24 July 2016 - 09:00 AM
I'm thinking about this. I don't know what the best way to set the modem is, I like it being automated myself. I see the point about wired modems though. Perhaps default to wireless, but fallback on wired if I can't find one?

The computer might have a wireless and a wired modem and the user might want to use the wired one instead of the wireless. Maybe there should be an 'open([side])' method which would open the modem on the side given or if no side was given open one automatically.
Lupus590 #5
Posted 25 July 2016 - 02:22 PM
send the message via all wired modems and one wireless?
Gorzoid #6
Posted 12 August 2016 - 02:21 AM
But… your just sending everything in raw text, all someone has to do is intercept your message, change the body and your program will think nothing of it. Even if they never even seen the code.
KingofGamesYami #7
Posted 12 August 2016 - 02:35 AM
But… your just sending everything in raw text, all someone has to do is intercept your message, change the body and your program will think nothing of it. Even if they never even seen the code.

They would have to prevent the original message from reaching the client before their edited message.
Gorzoid #8
Posted 14 August 2016 - 11:40 PM
Situation: I have a computer controlling the temperature of my nuclear reactor, there is another computer that reads the internal heat of the reactor. If the reactor is very cold the first computer to heat up and vice versa when its too hot. A l337 h4x0r comes along and reads a packet when computer2 says get hotter. now the attacker just spam sends that message to get hotter, and boom bye bye your base. A suggestion would be maybe to use the same authentication most garage door openers use, when you start a session send a seed to the one sending messages, now every time you send a message use math.random() as your authentication as they will be the same on both sides, but the attacker can't send packets because he was not there when you gave out the seed. Yes if he waited until your computers rebooted he could get the seed, but even then he wouldnt be able to send packets unnoticed as you would be able to notice the desynchronised random numbers. Ofcourse the best option would be to use public key encryption, but I heard that is very slow in cc.
KingofGamesYami #9
Posted 14 August 2016 - 11:52 PM
Gorzoid, every single password sent over modems is unique. An attacker cannot simply can't do what you're saying.

Each time you use blink.send, the first script sends a "Hey, I need a key".

The second script says "Here's a random public key anyone can see".

The first script responds with "Here's the result of my secret key which you happen to know and that random public key, and a message"*

The second script then makes sure the first script's result checks out, and queues a blink_message.

*This is combined using sha256 HMAC

Where in that process can anyone repeat a message?
Gorzoid #10
Posted 15 August 2016 - 11:39 AM
nvm my posts then :wacko:/> I guess I thought
hash.digest( tostring{} ):toHex()
Edited on 15 August 2016 - 09:41 AM