secure communication between objects
|
October Brotherhood
Registered User
Join date: 24 Jun 2005
Posts: 70
|
11-23-2005 09:20
well.. it doesn't have to be super secure, but it wouldnt' hurt.
20 little objects out there communicating back to one main object.
how do i keep it low lag and fairly secure?
a good example of this might be 20 tringo cards talking to the tringo board.
i'm not asking for anyone to write this up for me, just some tips or strategies i should consider or things i should think about before attempting this. example code is always greatly appreciated though!
|
Lee Ludd
Scripted doors & windows
Join date: 16 May 2005
Posts: 243
|
11-23-2005 09:48
1. Use a VERY hard to guess channel number for each object, and make it a negative number. E.g. -13250348912. (Only objects, not avatars, can say things on a negative channel). 2. Filter on exactly the message(s) you're going to send. E.g., if you're only going to say "go" to an object, then only listen for a message that says "go". 3. If it will work for you to turn the listen on when somebody touches (or collides with) the object, and turn off after a certain length of time, do that. 4. Use the lowest volume possible: a whisper if the objects will be less than 10m from the main object, a say if less than 30, a shout if more than 30. The lag gurus seem to agree that listening on a unique and remote channel does not cause much lag. I believe this is true, but if someone has any real statistical evidence to back up this claim, I would sure like to see it.
|
JackBurton Faulkland
PorkChop Express
Join date: 3 Sep 2005
Posts: 478
|
11-23-2005 09:51
Randomize your channels 
_____________________
You know what Jack Burton always says... what the hell?
|
Ushuaia Tokugawa
Nobody of Consequence
Join date: 22 Mar 2005
Posts: 268
|
11-23-2005 09:55
If your 20 objects are all going to be owned by the same person then you can filter out messages from other peoples objects in the listen event: listen(integer channel, string name, key id, string message) { if (llGetOwner() == llGetOwnerKey(id)) { // do stuff } }
|
October Brotherhood
Registered User
Join date: 24 Jun 2005
Posts: 70
|
11-23-2005 10:10
these are all great ideas thankyou for the input! any more suggestions are greatly appreciated!!
|
JP Burleigh
Registered User
Join date: 15 Oct 2005
Posts: 11
|
11-23-2005 11:15
However, each of these suggestions makes the communication difficult to guess but not secure. It seems to me that if I knew there was an inter-object communication occuring in an area that I wanted to listen in on I could drop a channel scanner there to isolate the communication. Depending on the nature of the object/communication I could then insert my own objects to fake out the overall system. This may or not be a problem depending on your usage.
It seems to me that the only way to ensure secure communications is to only accept messgaes from specific known and trusted handles. However, this is often not viable given that handles are often reset.
A complex algortithm to randomly set each communication may make this more difficult.
- JP
|
October Brotherhood
Registered User
Join date: 24 Jun 2005
Posts: 70
|
11-23-2005 12:19
i'm thinking the same thing JP i wish there was a way to instant message an object.
|
Lee Ludd
Scripted doors & windows
Join date: 16 May 2005
Posts: 243
|
11-23-2005 13:45
A channel number is a long integer between -2,147,483,648 and 2,147,483,647; over 2 billion negative numbers. It would take a channel scanner over 1 billion attempts, on average, to detect an open channel. If it took a scanner a millisecond to detect a hit (VERY optimistic), it would take it more than 11 days of continuous operation to detect. I think a randomly selected channel number provides adequate security for most SL needs.
|
October Brotherhood
Registered User
Join date: 24 Jun 2005
Posts: 70
|
11-23-2005 14:04
fair enough 
|
Ziggy Puff
Registered User
Join date: 15 Jul 2005
Posts: 1,143
|
11-23-2005 14:39
If someone rezzed a hundred objects, each of which had a hundred scripts in it, it probably wouldn't take 11 days any more. What is adequate depends on the application. There have been recent threads discussing this, and IIRC many different schemes were proposed, offering different levels of security. Searching through the archives for those discussions might provide some interesting insights.
|
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
|
11-23-2005 16:13
How long does it take if you channel-hop? integer data_channel = 0; integer next_data_channel = INITIAL_DATA_CHANNEL; integer control_channel = 0; integer next_control_channel = INITIAL_CONTROL_CHANNEL; integer message_countdown = 0;
send_message(string message) { if(message_countdown-- <= 0) { data_channel = next_data_channel; control_channel = next-control_channel; next_data_channel = llFloor(llFrand(MAXINT)); next_control_channel = llFloor(llFrand(MAXINT)); llSay(control_channel, llList2CSV([next_control_channel,next_data_channel])); message_countdown = MAX_MESSAGES_PER_CHANNEL; } llSay(data_channel, message); }
The chance of catching the ONE message passed over the immediately invalidated control channel to find out what the next data channel is...? I don't think Linden Labs will be around long enough.
|
Yumi Murakami
DoIt!AttachTheEarOfACat!
Join date: 27 Sep 2005
Posts: 6,860
|
11-23-2005 16:54
From: Argent Stonecutter
The chance of catching the ONE message passed over the immediately invalidated control channel to find out what the next data channel is...? I don't think Linden Labs will be around long enough.
I'm not sure, but I think this is technically less secure than using a hard to guess channel number, because if a listener listens on any random channel, it has a non-zero, increasing-over-time, chance of it being selected and the listener snagging a message. If you keep the same channel, the chance doesn't increase over time. I *think*.
|
Argent Stonecutter
Emergency Mustelid
Join date: 20 Sep 2005
Posts: 20,263
|
11-23-2005 21:09
From: Yumi Murakami I'm not sure, but I think this is technically less secure than using a hard to guess channel number, because if a listener listens on any random channel, it has a non-zero, increasing-over-time, chance of it being selected and the listener snagging a message. If you keep the same channel, the chance doesn't increase over time. I *think*. Whether you keep the same channel or you channel-hop, and someone is actively trying to break it, you will eventually be overheard. Here if you are overheard the listener will catch at most MAX_MESSAGES_PER_CHANNEL before you switch to another channel they don't know. The attacker will only have a small number of messages to examine to figure out your protocol, and by the time they figure it out you're on another channel. If you channel hop, some innocent repeater may forward up to MAX messages to a person, but something listening on one channel is 64 times less likely to catch you, and they would also have to know what you're doing AND have an interest in attacking your protocol. This is a lesser risk than sticking to one channel. To further reduce the risk, you can encode the message... and even a cyclical substitution cipher will significantly increase the difficulty of figuring out what's going on. Something more complex is possible, but given the low performance of LSL simpler is better.
|
Manuel Paz
Registered User
Join date: 20 Oct 2005
Posts: 10
|
12-06-2005 11:19
u ppl seen cryptography in LSL wiki?
|
SiRiS Asturias
Chaotic Coder
Join date: 27 Sep 2005
Posts: 93
|
Least we get 128, LoL!
12-06-2005 14:08
Above all are good examples of trying to evade detection, I would recommend using them all at once if you can. Below are also some further measures to take to ensure that even if they do manage to "snoop" in on one of your connections, they will not be able to understand what they are getting. =) Bellow are LL Opcodes tha can be used for cyptograpy purposes: llBase64ToString - Converts a Base 64 string to a conventional string. llMD5String - Performs a RSA Data Security, Inc. MD5 Message-Digest Algorithm on string with nonce (also known as salt). Returns a 32-character hex string. (128-bit in binary.) Note:128-bit encryption is very easibly decyphered, but still a deterrent. llStringToBase64 - Converts a string to the Base 64 representation of the string. llXorBase64Strings - Performs an xor on two Base64 strings and returns a Base64 string. llModPow - Returns a raised to the b power, mod c. ( (a ^ b)%c ). b is capped at 0xFFFF (16 bits). (Used as a weak RSA encryption.) /54/50/42686/1.html Wiki page for communications: http://secondlife.com/badgeo/wakka.php?wakka=Communications Hope this helps you out some more...
|
Lex Neva
wears dorky glasses
Join date: 27 Nov 2004
Posts: 1,361
|
12-07-2005 09:47
One time I helped write a game in which many game objects were communicating their status back to a server object. We didn't care whether or not people could hear what they were saying, only that the server could be sure that the object that had sent a message was one that was written by us, not someone else. We ended up having the game objects name themselves like this:
llSetObjectName(llMd5Sum((string)llGetKey(), MAGIC_NUMBER))
Then when the server received a listen event, it simply checked that the name matched the above process done on the object's key. Completely secure, so long as no one gets your MAGIC_NUMBER, which is a secret number the game objects and server all know.
|
Maria Loudon
Dark Kat
Join date: 26 Nov 2005
Posts: 16
|
12-07-2005 11:15
... IF the objects are linked u could use llMessageLinked. if not then ya use some random channel. You could also encript the data based on a key. If the objects are rezed then you can pass the key in the param.
|
Eloise Pasteur
Curious Individual
Join date: 14 Jul 2004
Posts: 1,952
|
12-07-2005 15:52
The honest answer is you can't make totally secure communications.
Random channels plus encryption, plus things like coded messages if it's not transmitting genuine text (use allez for go! say... which is a simple one if you speak French, but won't shout out to most English speakers that see it, and will also skew letter count mechanisms) and even better mixes of commands for it, plus letter grouping (everything in 6 letter blocks etc.) but any coding, including 256-bit encryption is really a question of how hard you're willing to try to crack it.
Some of the big ones have probable times greater than human history of course, and the SL ones are way easier than that, but you're still looking at it being doable if people REALLY want to, you also have to ask yourself how secure you need it and why. I'm pretty sure a lot of the boutiques etc. do most of their security stuff off world, SL is just a conduit for money and deliveries.
|
Manuel Paz
Registered User
Join date: 20 Oct 2005
Posts: 10
|
12-24-2005 09:38
Er... Wouldn't this be 100% secure? (Sorry, don't know how to properly insert code.) listen(integer channel, string name, key id, string message) { if ( llGetOwnerKey( id ) == llGetOwner() ) { llOwnerSay("Yes, Master..."  ; //do stuff here } else { llShout(0,"Ya tawkin' ta me, punk?"  ; //don't do stuff here } }
|
Keiki Lemieux
I make HUDDLES
Join date: 8 Jul 2005
Posts: 1,490
|
12-24-2005 12:27
Is there a function that reverses llMD5String? Or does it only encode messages, not decode them?
_____________________
imakehuddles.com/wordpress/
|
Ordinal Malaprop
really very ordinary
Join date: 9 Sep 2005
Posts: 4,607
|
12-24-2005 12:33
From: Keiki Lemieux Is there a function that reverses llMD5String? Or does it only encode messages, not decode them? The whole point of it is that it's supposed to be one-way, so you can't decode what the original message was, only duplicate it (and if you're using challenge-response, that's not going to help the eavesdropper).
|
Ordinal Malaprop
really very ordinary
Join date: 9 Sep 2005
Posts: 4,607
|
12-24-2005 12:45
Okay, what about:
1. The source object (call it the game server) rezzes pieces, passing them a parameter that combines: (a) a random channel to communicate on (b) a random password Integers are 32 bits so you've got 16 for a channel and 16 for a password, or a variation thereof. The server and pieces listen on the given channel.
2. Each piece, when rezzed, starts a challenge-response process, sending a message to the game server, which sends back a randomly-generated challenge. The piece then combines that with the password, makes an MD5 hash of that, and sends it back. If the game server recognises that as the same as the as its own hash of challenge + password, it adds the piece's key to a list of approved keys.
This all has to happen within, say, a second or two of the piece being rezzed.
3. From then on, anything saying anything on that channel with a key on the approved list is treated as authenticated. There is no way as far as I know of spoofing keys. This means that all the lag occurs within a few seconds of rezzing pieces - after that, they're authenticated and can communicate as normal.
4. Every game, you generate a new channel and a new password to pass to pieces. The security of this is going to depend on how long your games are. But given that every time a new game starts, someone is going to have to be able to find a 16-bit channel, then find the correct 16-bit password and send a challenge-reponse to confirm that, all within a few seconds, I think that's pretty safe. (And bear in mind that your game could lock out if it receives incorrect responses, because there's no reason a piece would ever get that wrong.)
|
Adam Zaius
Deus
Join date: 9 Jan 2004
Posts: 1,483
|
12-24-2005 13:41
Since it's christmas here now, I dont have too much time to post; but, lots of these idea's actually are not secure -- if someone via some mysterious exploit opens your scripts source; 99% of these will break. Good security involves using real cryptographic algorithms in the way they are intended. In LSL with the limited space and speed we have, the options are limited; however: 1. Channel Hopping is a bad idea. It makes your code more exploitable, not less; since your publishing the next channel your hopping to; given the range, it's possible that you hit a low number or two, which is open to scanners. 2. llGetOwnerKey() works well, if you do not own, or wear any attachments or build any objects you didnt create, in the vicinity. Now, onto solutions: 1. on_rez(i) { integer randchan = llFloor(llFRand(214748364  ); llListen(randchan,"",llGetOwner(),""  ; llInstantMessage(llGetOwner(),"Feed key on " + (string)randchan); } listen(c,n,k,msg) { secretkey = msg; llListenRemove(listener); } --- Use the above to load in your secret key at runtime, it will stay in the scripts memory, even if you take it to inventory. Hence, if someone makes another permissions exploit, your still somewhat secure. 2) MD5 is the fastest hashing algorithm we have in LSL; implmenting other ones requires more than 16KB of memory to do effectively. However, MD5 is still reasonably secure. llSay(channel, msg + "," + llMD5String(msg + secretkey + counter++)); Will place a salted authentication token at the end of your string, when you recieve the message, split it back into it's parts, and try make the MD5String again from the message. Compare to the attached one, if it does not match; then the message should be discarded not used. The 'counter' should obviously be implemented in a better manner; however it is important to have one element of the salt always changing. Often this is done through challenge-response based authentication, but that would probably take a few more paragraphs to write out, and I've got to run. On a final note -- some weaker forms of crypotgraphy are possible in LSL. DES and 3DES are possible to implement in LSL, without too much trouble. -Adam Edit: XOR'ing isnt very secure if you are sending non-numeric data, and even then, with enough source data, (and with a bit of commonality between it) it can be split back up into unique elements and completely reversed.
|