I've wrote following C# method that basically takes 3 seeds and gives you number in 0-100 range. I then use that number for variety of purposes but for this question the most important one is the ability of clients to see server and supply client value. Here is the method:
// random sha512
private const decimal DIVIDER = (uint.MaxValue - 1)/100M;
public static decimal Random0To100(string secret, string server, string client)
{
// add 3 strings together, calculate SHA512 hash
var str = secret + server + client;
var byt = Encoding.ASCII.GetBytes(str);
byte[] hashByte = null;
using (SHA512 shaM = new SHA512Managed())
{
hashByte = shaM.ComputeHash(byt);
}
// convert hash into hexadecimal string
var hexHash = BitConverter.ToString(hashByte).Replace("-", "");
// get unsigned 32 integer from first 8 chars of hash
var hex8 = hexHash.Substring(0, 8);
uint l = Convert.ToUInt32(hex8, 16);
// get number between 0 and 100 from hash with 2 decimals
var num = l / DIVIDER;
var fin = Math.Round(num, 2);
// return result, like 71.28
return fin;
}
Secret seed is 512 bit value sent in as a string.
The thing I am curious about is if it's possible for end-user to guess secret seed if he is given ability to supply BOTH server & client values (and see the 0-100 output obviously) for extended period of time (say the time is 24 hours and the only restriction I impose is that those server/client are at least 10 char long when added TOGETHER).
If you deem that it is theoretically possible to guess secret, please advise as to what I can do without changing the algorithm too much. I was thinking about variety of things:
- Increase seed size (1024, 2048... etc)
- Increase range from uint (32bit), to ulong (64bit)
- Enforce stronger requirements for server/client strings
Basically, I just want to make sure that it's not possible for someone to guess seed or random number while still providing users with ability to supply both server & client values (obviously for server value I'll re-generate it on server on user request, not allow him to supply it directly).
Because of high number of comments (most of which point to unrelated things), let me try to clarify the question. In a nutshell what I am trying to do is generate a random number that users can later verify was not fixed/influenced in any way by me. So, I will generate secret seed using RNGCryptoServiceProvider and it'll be say 512 chars long. Then I'll give ability to clients to generate 10 numbers for raffle (they can request generation of new server seed for each request they send in, plus send arbitrary string as a client seed). After those 10 numbers I'll generate new secret seed, publish old one so they see nothing influenced by me and so on...
So, I am:
- NOT trying invent new crypto standard
- NOT trying to generate true random numbers
I am building a method that takes in a string (secret+server+client seed) and produces number from 0.00 to 100.00. And the only thing I was wondering was whether or not somebody can guess secret string if he is able to get enough numbers back from that method (+ he sees server string and can send arbitrary client string). That's all. No homebrew crypto. No true random.
So, if anyone with computer science knowledge can confirm that what I am doing in algorithm is not prone to attack (user can guess secret seed after sending server/client seeds and getting several values back), or suggest a better way and post code that explains it - I would be extremely grateful. Otherwise, if you can only talk about theory and post unrelated links, I beg you to please just leave the question alone and not pollute it. Thanks.
To show in practice, these are 5 random numbers along with server/client seeds (server = server seed, c = client seed, number = generated number from that method; server and client seeds are short on purpose).
server | C | Number |
---|---|---|
k23op | 0 | 96.40 |
gfsqu | 1 | 22.07 |
n0dpd | 2 | 91.62 |
ds02d | 3 | 48.25 |
hf03d | 4 | 55.26 |
Let me know if you can guess the secret seed. If you need more computing power, send me algorithm you are trying to execute, I'll review it and put it to run on multiple servers.