|
Edison Swain
Registered User
Join date: 7 Dec 2006
Posts: 51
|
01-14-2007 01:48
Hi all,
I have a question about how to authenticate that an object is something that I actually created. Once it's been sold, I can't use keys, since keys change as an object goes in and out of a user's inventory. Here's the basics of the situation:
I sell a few different copies of Object A to various people. (Object A is no-mod/no-copy but could be given to a third party or resold, and I anticipate that will occasionally happen)
I have Object B sitting on my property. People can come by and use their Object A to talk to my Object B and do various different things.
I'd really like my Object B to be able to authenticate that the copy of Object A it is talking to is actually a legitimate Object A that I sold.
Currently, when I sell a copy of Object A, an external database will generate a unique serial number which gets written into Object A's Description field. What I'm thinking is to also generate a random passcode stored in the database with that serial number. This passcode also gets sent to Object A when it is sold. This passcode would get stored in Object A as a global variable. I'd change the serial number to be stored in Object A's Name field instead of the Description field. (Having the serial number visible to the user is useful for technical support issues.)
This way, Object B can use a Sensor to Detect Object A's Name field. When it senses an Object with an appropriate name, it can send out an email to that object and request the correct passcode.
Object A will only be in one of 4 possible different states, so it should be pretty easy to have it always checking for new email with some regularity. When it gets a request for the passcode, it extracts the key from the email address, uses llGetOwnerKey to find out the owner of the Object that sent the email, checks that against llGetCreator which should verify that I am the person who owns the object sending the email request (so it doesn't just shout out the passcode to anyone who asks!) and if it checks out, then Object A emails back the passcode. (I'm avoiding hardcoding the key for Object B into the script for Object A, since I may want create additional copies of Object B later, and I'd like them to work with the existing Object A's I've already sold! Very convoluted - I know!)
Object B can verify through the external database that the serial number and passcode match, thus authenticating a legitimate copy of Object A.
If Object B doesn't get an email back within a certain amount of time, or if it gets an incorrect passcode back, then it just won't consider Object A legitimate and can ignore it.
I think this should serve my purposes, but I feel like I'm a little bit over my head when it comes to any type of communication protocols like this. I don't think I need any type of encryption here, just authentication. And it seems like this should work?
I'd love to hear from anyone who thinks that this won't work, or if anyone could point out things that I am missing that would make this fail. Any and all advice appreciated!
Thanks so much!
|
|
Domino Marama
Domino Designs
Join date: 22 Sep 2006
Posts: 1,126
|
01-14-2007 03:03
Email seems excessive if Object A has to be near Object B to work. You don't mention whether Object A is a worn object like a hud or something that will be rezzed. If the later then an on_rez event in Object A that calls out to a listening Object B would seem a lot cleaner solution, otherwise having a "Connect" option in Object A's menu could again avoid repeatedly checking emails. For authentication which would work via chat and email check out this post /54/c6/159952/1.html#post1382074 about HMAC. You could add the results of a llGetCreator() call to the secret key used for the 2nd MD5 sum to ensure the script is in an object you made.
|
|
Pale Spectre
Registered User
Join date: 2 Sep 2005
Posts: 586
|
01-14-2007 03:06
From: Edison Swain I have a question about how to authenticate that an object is something that I actually created. Once it's been sold, I can't use keys, since keys change as an object goes in and out of a user's inventory. I'll be honest and admit I only quickly scanned your whole post - it is kinda long  - however, did you check out llGetCreator? This will return the key of the original Creator, which can in turn become the Creator's name using llKey2Name(llGetCreator()). This will not uniquely identify an object so I suspect it may not be sufficient for your purposes but it is very simple.  In the past I've used this to restrict a copyable version of a script to be used by a single individual. Which isn't fool-proof but it does make it less likely for a copyable version of a script getting released into the wild to be used by anyone.
|
|
Domino Marama
Domino Designs
Join date: 22 Sep 2006
Posts: 1,126
|
01-14-2007 03:26
One other thought, as your application relies on an external database, you could always store Object B's key in there and have Object A look it up via http before initiating the request.
|
|
Edison Swain
Registered User
Join date: 7 Dec 2006
Posts: 51
|
01-14-2007 11:35
Hey Domino,
Thanks for the ideas and that link - I may be able to use that info to find something that I'm happy with.
I appreciate the help.
|
|
Arachnid Baxter
Registered User
Join date: 8 Jan 2007
Posts: 44
|
01-14-2007 14:46
If your sole purpose is authentication, you can make the HMAC somewhat simpler again: 1) Object B requests that Object A authenticates itself, sending a randomly generated key 2) Object A combines the randomly generated key with the secret key (known to both objects) and MD5s it. Only one MD5 is required, since both strings are a known format. 3) Object A sends the resultant hash back to object B. 4) Object B calculates the hash from the same parameters and ensures it matches.
However, you _have_ to make sure that Object A will only respond to challenges sent by objects that you own. Otherwise, a fake one could simply locate another (legitimate) Object A and forward the challenge to it. Alternately, you could incorporate the key of the requesting object into the value you hash, so it won't be valid for anyone except the requester.
If this is unclear, I can whip up a couple of sample functions when I get home, but that won't be for a few hours yet.
|
|
Edison Swain
Registered User
Join date: 7 Dec 2006
Posts: 51
|
01-14-2007 15:38
Hey Arachnid, Thanks so much for the detailed explanation. I really appreciate it. From your other post that was linked earlier and this one, I think I understand how the process works now. (I didn't really understand MD5 hashes before) I guess the biggest question really is this part: From: someone However, you _have_ to make sure that Object A will only respond to challenges sent by objects that you own
Having Object A compare llGetCreator with the llGetOwnerKey that it get's from Object B's UUID should do the trick, shouldn't it? I'll try and put something together with this today, and if I have any questions, I'll let you know.
|
|
Arachnid Baxter
Registered User
Join date: 8 Jan 2007
Posts: 44
|
01-14-2007 15:45
From: Edison Swain Having Object A compare llGetCreator with the llGetOwnerKey that it get's from Object B's UUID should do the trick, shouldn't it? Yup, that should work just fine.
|