3057 posts
Location
United States of America
Posted 14 May 2014 - 03:29 AM
So, as most everyone has noticed, there is no safe way of encoding/decoding modem messages. I have decided to make it as hard as possible to determine what it is that is being sent, so I created this. It will transmit parts of the message on 10 different, random channels. The number specified in each function needs to be the same or the message will not get through correctly.
Spoiler
function send(info, mchannel) --info is either a table or a string. mchannel is any number that modems can be opened on, minus 128.
if type(info) == "table" then
info = textutils.serialize(info)
end
for i = 1, #info, #info/10 do
modem.transmit(math.floor(math.random(mchannel, mchannel + 128)), os.getComputerID(), info:sub(i, (#info/10) * i))
end
end
function receive(mchannel)
for i = mchannel, mchannel + 128 do
modem.open(side, i)
end
local info = {}
for i = 1, 10 do
msg = {os.pullEvent("modem_message")}
info[i] = msg[5]
end
info = table.concat(info)
if type(textutils.unserialize(info)) == "table" then
return textutuils.unserialize(info)
else
return info
end
end
995 posts
Location
Canada
Posted 14 May 2014 - 03:35 AM
Why not just have an agreed upon AES key to encrypt messages?
3057 posts
Location
United States of America
Posted 14 May 2014 - 04:23 AM
Why not just have an agreed upon AES key to encrypt messages?
Never heard of it. Google searching did not turn up any results that I could figure out how to implement in lua.
995 posts
Location
Canada
Posted 14 May 2014 - 05:12 AM
There is one implementation of it right on these very forums, so clearly you haven't looked very hard.
1610 posts
Posted 14 May 2014 - 12:58 PM
Why not just have an agreed upon AES key to encrypt messages?
It would likely be a good amount slower.
7508 posts
Location
Australia
Posted 14 May 2014 - 01:15 PM
in all honesty, you could fairly simply write a program to sniff out transmissions from a program using this.
163 posts
Location
Pennsylvania
Posted 14 May 2014 - 01:31 PM
in all honesty, you could fairly simply write a program to sniff out transmissions from a program using this.
Agreed. Unless you also obfuscate/encrypt the data, it's super easy to to just log all traffic and re-assemble it into it original form.
Since the target and number of messages is always the same, if you detect 10 messages fired one after another, and each is heading to the same place, and the first nine are the same length, there's a super high chance that it's coming from your algorithm, so we concatenate the messages. Viola, obfuscation circumvented.
Implementing even a basic rolling cypher instead makes communication less not secure (not quite safer); since it looks like 'normal' traffic it can't be singled out as easily. The best way to secure data is to do so without it looking secure.
3057 posts
Location
United States of America
Posted 14 May 2014 - 01:43 PM
in all honesty, you could fairly simply write a program to sniff out transmissions from a program using this.
Agreed. Unless you also obfuscate/encrypt the data, it's super easy to to just log all traffic and re-assemble it into it original form.
Since the target and number of messages is always the same, if you detect 10 messages fired one after another, and each is heading to the same place, and the first nine are the same length, there's a super high chance that it's coming from your algorithm, so we concatenate the messages. Viola, obfuscation circumvented.
Implementing even a basic rolling cypher instead makes communication less not secure (not quite safer); since it looks like 'normal' traffic it can't be singled out as easily. The best way to secure data is to do so without it looking secure.
Ah, but the idea here is that it sends each message on a different channel! Hacking computer would have to open all 128 channels above the channel you used. I'm looking into converting to binary & using an algebraic equation to encode/decode it (yes I realize this would still be vulnerable, but if they only got 9/10 pieces…)
7508 posts
Location
Australia
Posted 14 May 2014 - 02:20 PM
Ah, but the idea here is that it sends each message on a different channel! Hacking computer would have to open all 128 channels above the channel you used.
not a problem at all.
724 posts
Location
Kinda lost
Posted 14 May 2014 - 02:33 PM
In this situation if all goes down to how many ender-pearls you want to spend on wireless modems.
128 channels per modem
65535/128=512 modems with one channel free ;D
6 modems per computer
86 computers and you are listening to it all.
5 modems plus one wired for database stuff
103 computers + one mainframe and you spy and record all
Doable if someone is bored ;D
Edit - is 0 a valid channel?
Edited on 14 May 2014 - 12:34 PM
7508 posts
Location
Australia
Posted 14 May 2014 - 02:42 PM
In this situation if all goes down to how many ender-pearls you want to spend on wireless modems.
128 channels per modem
65535/128=512 modems with one channel free ;D
6 modems per computer
86 computers and you are listening to it all.
5 modems plus one wired for database stuff
103 computers + one mainframe and you spy and record all
Doable if someone is bored ;D
Edit - is 0 a valid channel?
not even really needed to go that overkill. I quickly whipped up a simple solution that has a fairly good chance of picking up the communications, but once it has picked up something it will always continue to pick it up… it uses 2 modems and ~27 lines of code. with a few more lines of code and no extra modems it could easily be improved to heighten the chance of initially picking up the communications.
Edited on 14 May 2014 - 01:12 PM
724 posts
Location
Kinda lost
Posted 14 May 2014 - 03:14 PM
not even really needed to go that overkill. I wrote a simple solution that has a fairly good chance of picking up the communications, but once it has picked up something it will always continue to pick it up… it uses 2 modems and 27 lines of code. with a few more lines of code and no extra modems it could easily be improved to heighten the chance of initially picking up the communications.
Frequency scanner? You are jumping over frequencies and saving those that got used? Yea that would work too :)/> But overkill looks more awesome in-game :D/> When server has extended rednet range its even better :P/> As for rednet i for one prefer to use my enigma to encode my messages. If someone if preexistent they will break it but i will make them learn history to do it!
7508 posts
Location
Australia
Posted 14 May 2014 - 04:31 PM
Frequency scanner? You are jumping over frequencies and saving those that got used?
Yes and no… threw it together in about a minute, so everything is fairly static, its just more of a proof of concept than something I'd actually put into use
Code
local m1, m2 = peripheral.wrap("left"), peripheral.wrap("right")
local max, messages = 65535, {}
local function close(modem)
for i = 1, max do
if modem.isOpen(i) then
modem.close(i)
end
end
end
local function open(modem, lower, upper, incr)
close(modem)
incr = incr or 1
for i = lower, upper, incr do
modem.open(i)
end
end
open(m1, 1, 2048, 16)
open(m2, 2049, 4096, 16)
while true do
local _, _, channel, _, msg = coroutine.resume("modem_message")
local maxPotential = math.max(channel + 128, max)
local minPotential = math.min(1, channel - 128)
open(m1, minPotential, channel)
open(m2, channel, maxPotential)
table.insert(messages, msg)
end
Edited on 15 May 2014 - 12:55 AM
756 posts
Posted 14 May 2014 - 06:20 PM
Why not just have an agreed upon AES key to encrypt messages?
It would likely be a good amount slower.
I've tried with
KillaVanilla AES-128 implementation, and with proper usage, it's fairly quick, quick enough for most uses at least.
3057 posts
Location
United States of America
Posted 14 May 2014 - 10:40 PM
I'm not saying it's impossible to hack, I'm just saying it's harder to hack than normal. If the hacker is lazy, he won't have thought of listening on all channels. I could send it backwards, but I don't see the point in that. The point of this isn't to make unhackable, its to make it annoyingly difficult to hack.
PS: I'm not hating anyone here, just explaining what I'm trying to do.
350 posts
Posted 14 May 2014 - 11:07 PM
I'm not saying it's impossible to hack, I'm just saying it's harder to hack than normal. If the hacker is lazy, he won't have thought of listening on all channels. I could send it backwards, but I don't see the point in that. The point of this isn't to make unhackable, its to make it annoyingly difficult to hack.
PS: I'm not hating anyone here, just explaining what I'm trying to do.
lazyness? well he can open a lot of channels at the same time. No need to test them all one by one.
7508 posts
Location
Australia
Posted 15 May 2014 - 02:52 AM
The point of this isn't to make unhackable, its to make it annoyingly difficult to hack.
I don't think a minute of coding is really all that annoyingly difficult… I put an extra minute into it this morning and made a truly random scanner that locks onto the signal once found
Code
local m1, m2 = peripheral.wrap("left"), peripheral.wrap("right")
local max, channelFound, messages = 65535, false, {}
local function close(modem)
for i = 1, max do
if modem.isOpen(i) then
modem.close(i)
end
end
end
local function open(modem, lower, upper, incr)
close(modem)
incr = incr or 1
for i = lower, upper, incr do
modem.open(i)
end
end
local function count(t)
local c = 0
for _ in pairs(t) do
c = c + 1
end
return c
end
local function generateRandomSets()
local rands = {}
repeat
rands[math.random(1, max)] = true
until count(rands) == 256
local i = 0
local set1, set2 = {}, {}
for k in pairs(rands) do
i = i + 1
table.insert(i <= 128 and set1 or set2, k)
end
return set1, set2
end
local function refreshModem(modem, channels)
close(modem)
for _,c in pairs(channels) do
modem.open(c)
end
end
local function refresh()
local s1, s2 = generateRandomSets()
refreshModem(m1, s1)
refreshModem(m2, s2)
end
local refreshTimer = os.startTimer(1)
while true do
if not channelFound then
refresh()
end
local event, param, channel, _, msg = coroutine.resume()
if event == "modem_message" then
if not channelFound then
local maxPotential = math.max(channel + 128, max)
local minPotential = math.min(1, channel - 128)
open(m1, minPotential, channel)
open(m2, channel, maxPotential)
print("Found signal in range ("..minPotential..","..maxPotential..")...")
print("Press 'r' to unlock from this range...")
channelFound = true
end
table.insert(messages, msg)
elseif event == "key" and param == keys.r then
channelFound = false
end
end
Don't get me wrong, I do like the thinking outside of the box… just think a little further outside… ;)/>
Edited on 15 May 2014 - 01:05 AM
3057 posts
Location
United States of America
Posted 15 May 2014 - 01:43 PM
The point of this isn't to make unhackable, its to make it annoyingly difficult to hack.
I don't think a minute of coding is really all that annoyingly difficult… I put an extra minute into it this morning and made a truly random scanner that locks onto the signal once found
Code
local m1, m2 = peripheral.wrap("left"), peripheral.wrap("right")
local max, channelFound, messages = 65535, false, {}
local function close(modem)
for i = 1, max do
if modem.isOpen(i) then
modem.close(i)
end
end
end
local function open(modem, lower, upper, incr)
close(modem)
incr = incr or 1
for i = lower, upper, incr do
modem.open(i)
end
end
local function count(t)
local c = 0
for _ in pairs(t) do
c = c + 1
end
return c
end
local function generateRandomSets()
local rands = {}
repeat
rands[math.random(1, max)] = true
until count(rands) == 256
local i = 0
local set1, set2 = {}, {}
for k in pairs(rands) do
i = i + 1
table.insert(i <= 128 and set1 or set2, k)
end
return set1, set2
end
local function refreshModem(modem, channels)
close(modem)
for _,c in pairs(channels) do
modem.open(c)
end
end
local function refresh()
local s1, s2 = generateRandomSets()
refreshModem(m1, s1)
refreshModem(m2, s2)
end
local refreshTimer = os.startTimer(1)
while true do
if not channelFound then
refresh()
end
local event, param, channel, _, msg = coroutine.resume()
if event == "modem_message" then
if not channelFound then
local maxPotential = math.max(channel + 128, max)
local minPotential = math.min(1, channel - 128)
open(m1, minPotential, channel)
open(m2, channel, maxPotential)
print("Found signal in range ("..minPotential..","..maxPotential..")...")
print("Press 'r' to unlock from this range...")
channelFound = true
end
table.insert(messages, msg)
elseif event == "key" and param == keys.r then
channelFound = false
end
end
Don't get me wrong, I do like the thinking outside of the box… just think a little further outside… ;)/>
hmm… what if I generated some random stuff on random channels? It wouldn't be too hard to implement.
1610 posts
Posted 15 May 2014 - 01:56 PM
The point of this isn't to make unhackable, its to make it annoyingly difficult to hack.
I don't think a minute of coding is really all that annoyingly difficult… I put an extra minute into it this morning and made a truly random scanner that locks onto the signal once found
Code
local m1, m2 = peripheral.wrap("left"), peripheral.wrap("right")
local max, channelFound, messages = 65535, false, {}
local function close(modem)
for i = 1, max do
if modem.isOpen(i) then
modem.close(i)
end
end
end
local function open(modem, lower, upper, incr)
close(modem)
incr = incr or 1
for i = lower, upper, incr do
modem.open(i)
end
end
local function count(t)
local c = 0
for _ in pairs(t) do
c = c + 1
end
return c
end
local function generateRandomSets()
local rands = {}
repeat
rands[math.random(1, max)] = true
until count(rands) == 256
local i = 0
local set1, set2 = {}, {}
for k in pairs(rands) do
i = i + 1
table.insert(i <= 128 and set1 or set2, k)
end
return set1, set2
end
local function refreshModem(modem, channels)
close(modem)
for _,c in pairs(channels) do
modem.open(c)
end
end
local function refresh()
local s1, s2 = generateRandomSets()
refreshModem(m1, s1)
refreshModem(m2, s2)
end
local refreshTimer = os.startTimer(1)
while true do
if not channelFound then
refresh()
end
local event, param, channel, _, msg = coroutine.resume()
if event == "modem_message" then
if not channelFound then
local maxPotential = math.max(channel + 128, max)
local minPotential = math.min(1, channel - 128)
open(m1, minPotential, channel)
open(m2, channel, maxPotential)
print("Found signal in range ("..minPotential..","..maxPotential..")...")
print("Press 'r' to unlock from this range...")
channelFound = true
end
table.insert(messages, msg)
elseif event == "key" and param == keys.r then
channelFound = false
end
end
Don't get me wrong, I do like the thinking outside of the box… just think a little further outside… ;)/>/>
hmm… what if I generated some random stuff on random channels? It wouldn't be too hard to implement.
What if you used encryption? :3
7508 posts
Location
Australia
Posted 15 May 2014 - 02:38 PM
hmm… what if I generated some random stuff on random channels? It wouldn't be too hard to implement.
That was just a proof of concept to prove the ease of intercepting your communications with the simplest of scripts. Could easily implement one with a timeout after getting a message, say wait 0.2 seconds, if another message is not received then scan the channels again. Etc etc.
350 posts
Posted 15 May 2014 - 05:44 PM
I may give a try at originalbit's code. It seems pretty safe to use in wireless comunication :)/>
353 posts
Location
Orewa, New Zealand
Posted 12 June 2014 - 11:50 PM
How do you intercept/log rednet messages if they are only being sent to a certain PC ID and if the PC your sending it to only read messages from the correct id, that how my system work, the main PC send messages to id 6 and it sees if the message came from id 2 if it did I allows it through other wise, it won't and will throw up an error telling me what I said, what protocol it had and where it came from…
756 posts
Posted 13 June 2014 - 12:30 AM
You can open all 65535 channels by having a setup of multiple computers with 5 modems on them, connected to a "master" computer via wired modem.
I have a pair of programs that does just that, so this channel hopping strategy is kinda pointless.
Your best bet if to use encryption (There's AES by KillaVanilla)
7508 posts
Location
Australia
Posted 13 June 2014 - 01:53 AM
How do you intercept/log rednet messages if they are only being sent to a certain PC ID and if the PC your sending it to only read messages from the correct id, that how my system work, the main PC send messages to id 6 and it sees if the message came from id 2 if it did I allows it through other wise, it won't and will throw up an error telling me what I said, what protocol it had and where it came from…
In the latest ComputerCraft there is no direct messaging anymore, messages are sent on channels, so if you have the channel open you can hear the message, as such the channels that rednet open are the ID of the computer. As such it means any computer can easily spoof the ID they've come from and negate your validation.
350 posts
Posted 13 June 2014 - 01:52 PM
FlagHacker gave my a really good tip:
Encryption uses keys. This key needs to be the same in the other computer. But like that the hacker can send the encrypted message and the other computer will think that it was an authentic message and will do the normal procedure. However, if this key is a random number (not really random but alaways changing) you can encrypt messages and they will work only once. this can be achieved using os.getTime() and os.day(). You use these as keys and they only work once. BTW: you may want to change the length of the os.getTime() because is so fast that the key will be diferent (os.getTime() includes milliseconds).
7508 posts
Location
Australia
Posted 13 June 2014 - 02:03 PM
FlagHacker gave my a really good tip:
Encryption uses keys. This key needs to be the same in the other computer. But like that the hacker can send the encrypted message and the other computer will think that it was an authentic message and will do the normal procedure. However, if this key is a random number (not really random but alaways changing) you can encrypt messages and they will work only once. this can be achieved using os.getTime() and os.day(). You use these as keys and they only work once. BTW: you may want to change the length of the os.getTime() because is so fast that the key will be diferent (os.getTime() includes milliseconds).
but then you cannot decrypt it. this is a very silly method of encryption, just look into
asymmetric keys.
350 posts
Posted 13 June 2014 - 03:43 PM
FlagHacker gave my a really good tip:
Encryption uses keys. This key needs to be the same in the other computer. But like that the hacker can send the encrypted message and the other computer will think that it was an authentic message and will do the normal procedure. However, if this key is a random number (not really random but alaways changing) you can encrypt messages and they will work only once. this can be achieved using os.getTime() and os.day(). You use these as keys and they only work once. BTW: you may want to change the length of the os.getTime() because is so fast that the key will be diferent (os.getTime() includes milliseconds).
but then you cannot decrypt it. this is a very silly method of encryption, just look into
asymmetric keys.
As i said, the other computer will decrypt using the same key (the key is the time and if the message is sent right after being encrypted, it will send encrypted to the other computer, then this computer can decrypt using the time)
7508 posts
Location
Australia
Posted 13 June 2014 - 04:22 PM
As i said, the other computer will decrypt using the same key (the key is the time and if the message is sent right after being encrypted, it will send encrypted to the other computer, then this computer can decrypt using the time)
and if the send/receive time isn't the same? i.e. it has gone through several repeating computers? this is why asymmetric keys are better, they're not dependent on anything changeable, they're static (well static-ish).
350 posts
Posted 13 June 2014 - 04:53 PM
the send/receive time is the same, the encryption time isnt, but just by a few miliseconds (thats why i use string.sub() to remove the last 3 digits of the os.getTime()) in the case of repeating trough various computers, you can decrypt the mssage and encrypt with the new time.