tags:

views:

306

answers:

7

I would like to give customers a random-looking order number but use 0, 1, 2, ... in the backend. That way the customer gets a non-password-protected order status URL with the encrypted order number and they cannot look at other customers' order numbers by adding or subtracting 1. This might replace a scheme where random order keys are generated, checked for uniqueness among all the previous orders, and re-generated until unique. When the web server gets a request to view an order, it decrypts the order number and retrieves the order.

To keep the URL short, what "good" encryption algorithm has the shortest block size? Is this scheme a good idea? (What if I was encrypting Apple, Inc. employee ids to keep Steve Jobs from asking for Employee #0?)

Observe that all the package tracking websites allow you to track packages without authentication. It would be fine to limit the amount of information shown on the password-free order status page.

A: 

guid is the way to go for that

* edit *

you might want to look at this http://csharpfeeds.com/post/4382/A_shorter_and_URL_friendly_GUID.aspx

Fredou
A: 

Why? Don't you think a UUID or a Globally Unique Identifier would be best for that? There are libraries for doing that.

Johannes Weiß
A: 

I don't think this scheme is that great of an idea. Why aren't you verifying that a user is logged in and has access to view a specified order?

If you REALLY want to just have all orders out there without any authentication, a GUID would be best.

Or, you could try to come up with order numbers prefixed with something about the customer. Like (PhoneNumber)(1...100)

Bob
Well, you can track FedEx and UPS packages this way.
joeforker
I was thinking (SocialSecurityNumber)(1...100) might work well. :-)
joeforker
@joe - lol SSN's wow! Sounds like an entry for the daily wtf
Gavin Miller
A: 

To meet the requirement you could simply use a hash such as SHA-1 or MD5 on your indexes. These will provide the adequate security you require.

To bring down the size you can change to a different encoding; such as 64 bit.

I'd also very strongly recommend insist on using a salt, otherwise the hash values could easily be broken.

Gavin Miller
A hash will not guarantee uniqueness.
MichaelGG
@Michael - You're missing one of the requirements of the question and that is using linear indexing.
Gavin Miller
With a name like that, I'm disappointed you didn't suggest something based on a linear feedback shift register.
joeforker
@LFSR - I didn't see any linear indexing requirement. He said he wanted natural numbers on the backend, and "random" on the front end. A cipher block fits perfectly. A hash doesn't, since it's not unique.
MichaelGG
@Michael - Sorry, I'm missing something. It's a unique order number with a hash applied? How is it that that would not be unique?
Gavin Miller
Hashes are not guaranteed to be unique over any input, that's why. So, in this case, he's performing H(SALT + ID). He'd have to precompute and check every ID to ensure it's unique. (Sure, SHA1 over a few thousand order ID is _probably_ going to be ok, but he'd have to prove it by hand.)
MichaelGG
Oh, I should also note, if you only expose the hash in URLs, that means you need to compute and store the hash, since you can't reverse it except through brute force.
MichaelGG
Ballsy programmers would trust the hash code, it's an incredibly tiny risk with SHA1 and its peers. For example, git stores every revision of every file by hash and it works fine. For this question if I wanted at least 128 bits I'd use AES. The tricky part is having a short url.
joeforker
+6  A: 

Most block ciphers are going to use larger than 32-bit sized blocks, for security reasons.

However, I found one that is made specifically for what you are doing: Skip32

You may consider using a GUID, but perhaps you have reasons you want to avoid that. (Say, your app is done already.)

Edit: Actually, if a GUID is permissible, then that gives you a range of 128 bits. You could easily use any other block cipher. The benefit to having a larger space (at the cost of long ID strings) is that you'll have much more protection from people guessing IDs. (Not that it an order ID by itself should be a security token anyways...)

MichaelGG
Thanks. If the URL length was not a concern, then if I needed to avoid AUTO INCREMENT I'd use GUIDs, and if sequential ids behind the scenes were fine then I would use AES. Unlike GUIDs, AES lets me avoid storing lengthy identifiers in a unique index for every order.
joeforker
Good answer. For completeness I'll mention that using cleartext order number and appending N bits of a keyed HMAC would be another alternative, and maybe simpler depending on what you have at hand.
Liudvikas Bukys
@Liudvikas: concealing the order number is one of the main points of this exercise, that way the customer cannot guess how small a company we are by how slowly our order numbers increment.
joeforker
+1  A: 

If your idea is that just knowing the order number (or URL) is enough to get information on the order then:

  • The order number space needs to be extremely large, otherwise attackers and/or customers will conceivably search the order space, to see what can be seen.
  • You should consider that an attacker may launch gradual probing from numerous machines, and may be patient.
  • Probing the order number space can be mitigated by rate limiting, but that's very hard to apply in a web environment -- it's hard to distinguish your customer access from attacker access.
  • Consider also that the order number is not much of a secret, people could be sending around in emails; once it's out, it's impossible to retract.

So, for the convenience of one-click check-my-order-without-logging-in, you have created a permanent security risk.

Even if you make the order number space huge, you still have the problem that those URLs are floating around out there, maybe in possession of folks who shouldn't have gotten them.

It would be much much better to require a login session in order to see anything, then only show them the orders they're authorized to see. Then you don't have to worry about hiding order numbers or attackers guessing order numbers, because just the order number isn't enough information to access anything.

Liudvikas Bukys
Good points, but it doesn't have to be a big deal if an attacker knows whether someone's order shipped or not (they could attack UPS instead). The password-free order link could be designed to not display valuable secrets.
joeforker
A: 

I prototyped this idea using Blowfish, a block cipher with 64-bit blocks.

joeforker