I think this question is related to cryptography.
Say Player A and B want to play Rock Paper Scissor game through the Internet.
There is not a server that both play trust, and they do not trust each other not to cheat.
I want to know how can they play a fair game with given scenario.
To be more precise, if neither player cheated, there should be a mechanism to let both player ensure that neither cheated.
Here is a naive solution that does not work:
First, both players send their choices to a server. After server receive both choices, it sends out the choices to both player.
The reason why this won't work is that the server might be an accomplice of player A. It will secretly send player B's choice before receiving player A's choice. Then player A can make a choice that wins player B. Throughout this process, Player B has not way of knowing whether player A cheated.
You could use a secure hashing function and random number generators to make players commit to their move before revealing it.
Something like this:
Each player generates a random string, and sends it to the other player.
Each player generates a second random string, and keeps it secret (temporarily).
Each player chooses their move, and generates a signature for it, using the hashing function, and concatenating the two random strings to create a secret. Perhaps HMAC_SHA512( my_string + other_string, move ) in pseudo-code, where first param is the MAC's secret, and by + I mean string concatenation. Equally HMAC_SHA512( my_string, other_string + move ) works.
Players publish their signatures to each other. At this stage, they have made a public commitment to make a move with a matching signature.
Players then reveal their moves and second secret strings to each other, allowing the signatures to be verified.
This relies on the fact that if would be very hard to find a hash collision (two secrets which when combined with the other players "salt" and the move that would create the same signature). Technically, the hash function needs to have collision resistance and second preimage resistance to work well in this scenario - the former often implies the latter, and most HMAC functions available in a modern crypto library have these properties, at least from a practical standpoint of no known attacks better than brute-force. Once committed to a move signed with HMAC-SHA512 using a combined secret (combining the secret with data from the other player means you must look during the game, not search in advance for a collision), the players would find it impossible to declare anything other than the original signed move without being noticed.
It is also important that the generated random strings cannot be guessed, or all possibilities tried. They should be long (say 32+ bytes) and generated using a secure random number generator. If a player can simply try all the possible random strings, they could figure out what was being signed and respond with the correct counter-move.
Note that this method does not rely on a server. The server, or network, could create a man-in-the-middle attack here (by discarding one or both players' communication, and replacing with its own - it would not necessarily control the game result, but might mean the players were not really playing each other, but the server), so it is better if the communication is done securely peer-to-peer. If peer-to-peer is costly, then the only thing that has to be sent this way is the signature - if any component in-between the players then tries to change anything it would show up as the signatures not matching to published values.
Related
I've been fussing with this dilemma for a while now and I thought I'd approach SO.
A bit of background on my scenario:
I have Playlists which contain 0 or more PlaylistItem children.
Playlists are created infrequently. As such, I am OK with requesting a GUID from the server, waiting for a response and, on success, refreshing the UI to show the successfully added Playlist.
PlaylistItem objects are created frequently. As such, I am NOT OK with a loading message while I wait for the server to respond with a UUID.
This last fact is an optimization, I know, but I think it greatly improves the usability of the program.
Nevertheless, I would like to discuss my options for uniquely identifying my object client-side. I'll first highlight the two options I have tried and failed with, followed by a third option I am considering. I would love some insight into other possible solutions.
Generating a PK UUID client-side which will be persisted to the server.
This was my first choice. It was an obvious decision, but has some clear shortcomings. The first issue here is that client-side UUIDs can't and shouldn't be trusted for this sort of purpose. A malicious user can force PK collisions with ease. Furthermore, my understanding is that I should expect a greater collision chance if I chose to generate UUIDs client-side. Scratching that.
Generate a composite PK based on Playlist GUID and position in Playlist
I thought that this was a tricky, but great solution to my issue. A PlaylistItem's position is unique to a given Playlist collection and it is derivable both client-side and server-side. This seemed like a great fix. Unfortunately, having my position be part of the PK breaks the immutability of my PK. Whenever a PlaylistItem is reordered or deleted -- a large amount of PlaylistItem keys would need to be updated. Scratching that.
Generating a composite PK based on Playlist GUID and an auto-increment PlaylistItem ID
This solution is similar to the one above, but ensures that the PK is immutable by separating the composite key from the position. This is the current solution I am toying with. My only concern is that a malicious user could force collisions by modifying the auto-incremented id of the client before sending along. I don't think that this sort of malicious act would cause any harm to the system, but something to consider.
Okay! There you have it. Am I being stupid for doing all of this? Do I just suck it up and force my server to generate the GUIDs for my PlaylistItem objects? Or, is it possible to write a proper implementation?
UPDATE:
I am hoping to represent the user's action visually before the server has successfully saved to the database and implement the needed recovery techniques if the save fails. I am unsure if this is fool-hardy, but I will explain my reasoning through a use case scenario:
The client would like to add a new PlaylistItem. To do so, a request to YouTube's API is made for all the necessary information to create a PlaylistItem. The client has all necessary information to create a PlaylistItem after YouTube's API has responded, except for the ability to uniquely identify it.
At this point, the user has already waited X timeframe for YouTube's API. Now, I would like to visually show the PlaylistItem on the client. If I opt to wait for the server, I am now waiting X + Y timeframe before there is a visual indication of success. In testing, this delay felt awkward.
My server is just a micro instance on Amazon's EC2. I could reduce Y timeframe by upgrading hardware, but I could eliminate Y completely with clever programming. This is the dilemma I am facing.
Okay, as you seemed to like it when I suggested it in a comment :)
You could use a high/low approach, which basically allows a client to reserve a bunch of keys at a time. The simplest way would probably be to make it a composite primary key, consisting of two integers. The client would have one call along the lines of "give me a major key". You'd autoincrement the "next major key" sequence, and record which client "owns" that major key. That client can then use any minor key alongside that major key, and know that they'll be isolated from any other clients.
When the client performs an insert, you can check that the client is using the right major key, i.e. one assigned to them.
Of course, an alternative way of approach this would be to just make the primary key { client ID, UUID } and let the client just specify any UUID...
I'm a total noob when it comes to cryptography but I believe this falls under the "zero knowledge" category.
I have two associated pieces of information:
tag - Known by both parties. Unique per scenario.
identity - Known by only one party. Potentially associated to multiple tags. Comes from a pool known by both parties.
I need a way to prevent the party with the association to change the value of the identity. There are around one hundred concurrent associations per scenario. The pool of potential identities can be relatively small, even smaller than the number of tags.
The most primitive option would be to hash the tag and identity together but with such a small pool of potential identities I fear it would be trivial to brute force the hash...
During the scenario more and more of these associations will become public. At least at that point I should be able to confirm that the other party did not modify the association. I don't really have to confirm this before then because unrevealed associations are not relevant. I just need to prevent the knowing party to pick and choose on revealing.
Is such a thing even possible? How could it be done? How difficult would it be to implement?
You shouldn't implement this yourself.
you have two parties, Alice and Bob. ALice as the (identity, tag) pair. Bob only has the tag.
Alice wants to prove to Bob she has an identity in that pair that she did not change but she does not want to reveal that identity to BoB.
What you want is a "Signature scheme with efficient protocols". I know of no API's that expose this functionality. However, these are widely used in anonymous credential systems that can be used for your purposes.
Thankfully, there are two systems that support this type of thing. One is IBM Idemix which uses the above technique and is where you should look first. The other is Microsoft's U-Prove.
I'm thinking through how to develop a validation on my Rails app that essentially checks to make sure that the credit card used for any given transaction by any user is unique in our system, such that all credit card may be used to purchase an item only once across the entire application for all users, for all time.
The thinking behind this restriction is that this app will sometimes run time-sensitive promotional deals, and we want to do our best to institute a "one purchase per credit card" system for these deals.
I was thinking of hashing the credit card number and just storing that hash in the db, then cross-referencing it at the time of each new purchase (so my payment gateway keeps the actual number, and I just keep a hash in the DB), but on further research, this seems like a bad idea.
So I'm back to the drawing board and looking for new ideas. Anyone know a good approach to this problem, while keeping as PCI-compliant as I can be?
I'm developing with Rails 3 and using ActiveMerchant to integrate with my payment gateway, Authorize.net, if that helps at all.
Certainly some hashing is a bad idea - either because it's low security, has some intercepts, or so commonly used there's rainbow tables. That doesn't mean all hashing is a bad idea - the only way to cross reference is going to be some way of uniquely and predictably identifying the information. Unless PCI specifically prohibits it - hashing is still the way to go.
Salt
Make sure you salt your hash - this prevents rainbow attacks, or at least requires the rainbow-attacker build a table with your salt in mind. In particular if you can keep the salt reasonably secure {I say only reasonably because in order to generate you need to have the salt which means it'll be in code somewhere}.
Choose a Good Algorithm
While MD5 is now infamous, and implemented in all kinds of languages, it's also so common that you can find pre-made rainbow tables. It's also extremely quick to generate a hash. Your system can probably tolerate a small amount of delay, and use a much more processor-intensive hash. This makes the cost of generating a rainbow table much more expensive. Check out the Tiger algorithm for example.
Hash more than once
If you have multiple related data points, multiple hashes are going to make it way harder to do a rainbow attack. For example: Hash(Hash(Card#+salt1)+expireDate+salt2) - requires knowledge of both the card # and the date to generate (easy for you) but can't easily be reverse-engineered (rainbow requires for every card # * every useful expire date + knowledge of both salts).
Edit: (your comments)
Reasonably secure: Only transmit it over an encrypted connection (SFTP, SSH), don't store it unencrypted - including live/iterative and backup copies, keep the file with the salt outside of the web tree (cannot be directly accessed/accidentally released), make sure permissions on the file are as restrictive as possible (don't allow group/global file access).
Dynamic salt throwing a random value into the hash is great for reducing rainbow attacks - you store that random piece in the table with the hashed value - now when building a rainbow you have to build one for every dynamic salt. However for your needs you can't do this - you need to know the right random salt to use the second time you create the hash (otherwise you'll never get an intercept on the second card use)... for that to be predictable/repeatable you'd then have to base the dynamic salt on some part of the number... which is effectively what multiple hashing with another data point does. The more data points you have the more you can hash in this direction - if you have the CVV for example (3 hashes), or perhaps you hash 8 digits at a time (for a total of 3 hashes: hash(hash(hash(1..8+salt1)+9..16+salt2)+expDate+salt3)).
Best Hash it's a moving target, but there's a good discussion on security.stackexchange. Which points to SHA-512.
faking your true credit card number online is the best way to prevent this from happening. Citibank clients can login and make use of this tool provided with all accounts. Just generate a number and exp date for use online, and all is fine , for now.
I think you are looking in the wrong direction. I would just check last 4 of card, ip and shipping addresses. The risks of storing that data versus the damage if a small number of users gamed the last 4 & ip solution is not worth it. (He says not knowing the nature of the purchases.)
Since address isn't collected...First 4, Last 4 and 4 Digit Expiration (all hashed of course) should provide the uniqueness you need to ensure that card was only used once.
If you want a "one purchase per user" system then why don't you just check the user's purchase history whenever they try to buy a special-purchase item to ensure that they haven't bought it previously?
user could register for multiple accounts.
although by checking users history, as well as enforcing 1 item per address for each purchase- you will likely be fine- you could also limit things by users name/ birthday/ whatever other identifying information.
Credit Card information can also change by the way- its actually very easy to purchase 100 gift credit cards with unique numbers so if you want to police things down to the most minute level... I dont think you will be able to just by cc numbers
I have a vb application where I was using an online mysql database for user access. The online database had username, password, then a bunch of single digit (basically yes/no) fields for determining which items that user was allowed to access. When a user would log in, the database retrieved all the 'yes' answers and enabled those buttons, and retrieved all the 'no' answers and disabled those buttons.
My issue is there is a very good possibility that any given user will not be online. So I thought of copying the online database to a local device (this program is going to be running on windows tablets that may or may not have internet - possibly never having internet connection). This would suffice except a user may use a different tablet and that device wouldn't know what the user is allowed to access (based on a lack of internet connection).
So my new approach is when a user registers, having them provide first name, last name, phone number, and email address. At this point in time I would also select which buttons they are authorized to use. I want to put all that info into a code (probably a hash) so the next time the user would login (online or offline), they would use their first name, last name, and the generated code. The user could even go to a different device and still get the same result. I hope this makes sense.
So basically I am looking for a way (I am pretty sure hashing is involved) that would allow a user to register with some info, receive a code that ties it together, then log on to any windows tablet that is running my program without the device ever having to go online to download a new list of authorized users.
Thanks in advance.
A hash is part of what you're thinking of, but not the whole thing. A key part of a hash is that it's not reversible, and so you can't use a hash on it's own to communicate information like which buttons to enable/disable. It does sound like you also need to implement hashing elsewhere in your system (NEVER store unhashed passwords!). The rest of what you need for this question are secure check digits.
The idea is that you generate a number with a few holes/empty spaces, where different parts of the number have different meaning. It might look something like:
4325_-23R3_-F257_-D982_-__
A few of those characters are a hash of the user information, with the bits from other characters corresponding to your Yes/No database fields. Once you have this much, you have an algorithm (using a secure key) that computes what characters belong in the missing spaces, and then you can issue the final number to your user. Your software will take the number entered by the user, and check to the make sure the check digits it comes up with match the check digits entered.
There is a downside to this approach. Allowing offline activation means including including the key used to compute the check digits with your product, and as with any digital security once you put that kind of thing out in the wild crackers will be able to find a way to get at it.
Now let's move on to the big gaping security hole in your current code. You state that your database stores a username and password. I'm hoping that you're just simplifying things, but this is a huge problem, to that point that I can't in conscience leave it unchallenged. Instead of storing the actual password, you should hash the password and store only the hash. When someone wants to log in, you hash the attempted password they try to use and compare the hashes. This is a big deal, and if you're not doing that, you're doing it wrong.
That also over-simplifies it a bit. You also want to salt your passwords before hashing them, to help thwart dictionary attacks on common hash results. Additionally, choice of hashing algorithm matters. md5 does not cut it here. Your best option is bcrypt or scrypt, but you can use sha1 for now if you really have to.
The biggest thing to know here is that you should never try to build your own authentication system. It's easy to get it close enough that it passes all your tests, but is still wrong in some subtle way that won't know about until a year later when you find out you were hacked six months ago. Instead, look for a pre-written component or product for your existing platform to handle this. Rely as much as possible on code from projects (and programmers) that specialize in this area.
Could anyone explain to me in simple programmatic terms how these RSA key dongles work? I know Blizzard has them for WoW and paypal as well as some of the trading sites.
Thanks!
The fob has a clock and a serial number that is used as a seed for a PRNG. When you hit the "show me a code" button, the fob displays a number that is the product of that timestamp and the serial number run through the PRNG. The server knows your fob's serial number and time, and does the same operation. If your codes match, you're authenticated.
You can calculate the previous/next N values on the server end to account for clock skew.
Programmatic terms aren't necessary. Just imagine two pieces of hardware (your dongle and something at the company) that generate the same numbers at the same regularly scheduled intervals. It would be virtually impossible to guess what the number is due to some proprietary algorithms, so if the number you type in (or is automatically sent by the dongle) matches the number at the server, your identity is validated.
At least with the dongle I have, you also have to supply a pin known only by you and the server. So, in order to be authenticated you need both something physical and something in your head. That combination is pretty hard to fake. Even if someone gets the dongle, unless they know your pin it's worthless. And if they know your pin, that information is worthless without the dongle.
Security Now! episode 103 talks about how they work. (That link is to the show notes, but there's a link at the top of the page to the audio podcast.)
Basically, the key fob is synchronized with a server and they're both seeded to generate the same sequence of pseudo-random numbers. The server knows it's you if you input the right number at the right time.