views:

66

answers:

3

I want to generate serial number alphanumeric of 8 digits. But i also want to hide/encrypt the number so no one can judge next number. And also i want to keep the length after encryption or sum shuffling mechanism.

For example my series like this: 1000002A 1000002B 1000002C

Any idea?

+1  A: 

you can take md5 of your number, but you would better to generate purely random series and store them somewhere, in DB may be.

Please note that MD5 is not encryption but hashing, it calculates fixed length byte sequence (16) from string of any length. This is one way process you can never calculate initial string based on MD5 result.

Edit: People recommend SHA-2, another hash function: http://msdn.microsoft.com/en-us/library/system.security.cryptography.sha256cryptoserviceprovider.aspx

Edit: To prevent brute force attack you should add salt to your string and then apply hash function. sample: calculate hash from hash("1000002A" + "00523422E8AB604F90C80D43C5F6C0F6")

Andrey
I would advise against using MD5. Something from the SHA-2 family would be better. Also, it might be a good idea to have a unique salt for each number, otherwise finding patterns would be easy.
igorw
@evil3 **100000** 2A can be considered salt :)
Andrey
Sure, but that's not unique. Once you crack one hash you have the salt, giving you the ability to calculate more hashes.
igorw
@evil3: "Once you crack.." Once? IF! (Yes its remotely possible if you have huge resources, and lots/millions of samples, and a motive! Theoretical attacks are still a long way away from reality and practicality)
andora
But the problem is that IF someone finds out the salt (which must not happen by calculating it, you could also loose some usb key or so) then there is NO way to make the stuff secure ever again. (Unlike eg a password which you could change)
Marian
@Marian salt must not be distributed in anyway. it should be very internal part of application. Security of salt is administrative measure, not technical
Andrey
@andrey: Yes sure, but it *may* happen that it becomes public, either by a vulnerablity in the hashing algorithm which allows to calculate from the hash, or by some human error. And *if* it happens, then you don't have a way to fix it.
Marian
@Marian yes, *everything* is possible. But possibility is so tiny that we can neglect it. But let's assume that salt became public. You will have to invalidate all issued codes, generate new salt and start issuing codes again. Since you are criticizing this approach i guess you have better one?
Andrey
(I don't think you can neglect it. It's just a question of time for the hashing algorithm used to not be secure enough anymore, and you are not able to react on that). Replacing all codes is impossible (the old ones are in use, aren't they), and if you just use the new salt for new codes you'd have to store which salt was used for each code (which was the reason why the OP wanted to use that approach originally) (and it's still possible to calculate the old codes).
Marian
@Marian ok, ok. Your suggestions?
Andrey
A: 

You may add a random string only you know to the number and hash both together. This makes it impossible for others to find out the next number. If you'd just hash the serial number, as soon as someone learns about it, he can try out the numbers until he gets the correct hash and could then find out the next number.

However I'd also recommend to just create a random value. If you loose your secret string all number->hash pairs are 'cracked'.

Marian
MD5 string is too long, actually i have to generate barcode with this number and then print on some paper. Again we have to decrypt the number to compare with existing match. Random number means we have to save each number in DB and after generating we have to check with bundle of numbers.
malik
You can take just a substring of the md5/shaX/... hash. Be careful however, the shorter it is the more likely there will be duplicates. You shouldn't take the hex-encoded hash (two chars per byte) but something like base64 or base32 or so to get more bits in the string. - @ the decrypt part: I don't know if there's a way to encrypt a string without it getting longer and without having duplicates... - I don't know where the problem with storing it in the db is.
Marian
Besides: Why is it important for you that the next number cannot be guessed?
Marian
I think that after clarifications the OP was more looking for a way to get the initial number back from the enciphered numbered, without storing the mapping in a DB. Therefore hash functions, like random numbers, won't work.
Bruno
A: 

If you just want to use this serial number as an identifier, you could use random UUIDs. They're 128-bit long, so 32 significant characters in hexadecimal (plus hyphens if you need).

If the ordering of the sequence matters on your side, but not for the public side, you could store the UUID <-> sequence number correspondence in a database.

If size is an issue, you'll find that MD5 hashes are also 128-bit long and that SHA-1 hashes are 160-bit long. I'm not sure how truncating such a hash or UUID affects the randomness. It certainly increases the probabilities of collisions, but there might also be side-effects regarding the entropy.

EDIT: Further comments about size, since it's an important requirement for this question.

If you need the output to be at most 8 characters [0-9A-Z], that's 36^8 possible values. Since 2^41 < 36^8 < 2^42, you'd want a result to use 41 bits at most.

You could use a stream cipher or block cipher of 41 bits (perhaps in combination with a public key algorithm), where you'd be the only one to know the (shared) key. That's probably fine, but you'd need to be careful not to let examples plain text out, since that would probably be quite easy to attack. I don't know enough to give you more precise advice on the secure key-length, but if you look at the comparison of stream ciphers (assuming the information on Wikipedia is accurate), few seem to be under 80 bits and not be attackable in a relatively short time. Similarly, the entry about block ciphers says "As of 2006, 80 bits is normally taken as the minimum key length needed to prevent brute force attacks."

This document might also be of interest: "How to Calculate the Size of Encrypted Data?".

Essentially, it depends on what you mean by "no one can judge next number". I think you may get a degree of obfuscation with such a short length, but that probably wouldn't resist serious attackers, especially since knowing the fact it's a sequence might be helpful to them.

Bruno
I need only 8 digits alphanumeric (0-9A-Z) characters of fixed length, that can encrypt with same length and then needs to decrypt, UUIDS or Guids are too long.
malik
I've just edited to add more about encryption length.
Bruno