String Encryption Help

R

rossum

Thank you very much for your help dont want to annoy you to much.

I have changed the requested... and hopefully this is what you ment.

private int CreateSecureRandomInt()
{
RNGCryptoServiceProvider random = new
RNGCryptoServiceProvider();
byte[] randBytes = new byte[4];
random.GetBytes(randBytes);
int i = (BitConverter.ToInt32(randBytes,0));
randBytes = null;

if (i < 0)
CreateSecureRandomInt();
This does not do what I suspect you want it to. Trace the value of
variable i before and after this statement.
while (i > 10)
{
i = i / 10;
}

return i;
}

I ran some tests on your code as written. The results were not good:

Low values = 4983
0 -> 0
1 -> 2321
2 -> 590
3 -> 264
4 -> 236
5 -> 280
6 -> 274
7 -> 247
8 -> 258
9 -> 271
High values = 276
10000 tests total.

Low values are negative numbers, 0 to 9 are the digits and high values
are ten or more. Your code does not return what you seem to want it
to - a single digit in the range 0 to 9. If you want a digit in the
range 1 to 9 then it is better, but the digits are not picked equally,
1 and 2 are more frequent than they should be.

Fixing your if-statement removes negative numbers:

Low values = 0
0 -> 0
1 -> 4661
2 -> 1209
3 -> 519
4 -> 513
5 -> 515
6 -> 541
7 -> 555
8 -> 505
9 -> 506
High values = 476
10000 tests total.

For a correct distribution, each digit should appear about 1000 times.

Your other problems need a bit more study. One line of attack might
be to avoid using integers, you can just get a single byte in the
range 0 to 255 and derive your single digit from that. Hint: because
10 is not a power of 2 and 256 is, you will need to throw some numbers
away for a correct distribution of results.

My test code is below for reference.

A style point, if your function is intended to return a random digit
then it might be better to call it CreateSecureRandomDigit().
I will work on the rest of the "fixes" over the next few days and will post
back.

I tried replacing this ...
tdes.Mode = CipherMode.ECB;

with...
tdes.Mode = CipherMode.CBC;

But it seems to output characters which can not be converted to base64,
All characters can be converted to Base64, you problem is elsewhere.

Are you setting up an Initialisation Vector (IV), which is needed for
CBC mode? You will also need to transmit the IV with your cyphertext.

rossum
which would mean a big change.
I need to do some more reading.

Once again thanks

Regards JJ (UWA)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Test code:

static void Main() {
int numTests = 10000;
int[] counters = new int[10];
int lowValue = 0;
int highValue = 0;
for (int i = 0; i < numTests; ++i) {
int csri = CreateSecureRandomInt();
if (csri < 0) {
++lowValue;
} else if (csri > 9) {
++highValue;
} else {
++counters[csri];
} // end if
} // end for

Console.WriteLine("Low values = {0}", lowValue);
for (int j = 0; j < 10; ++j) {
Console.WriteLine("{0} -> {1}", j, counters[j]);
} // end for
Console.WriteLine("High values = {0}", highValue);
Console.WriteLine("{0} tests total.", numTests);
Console.Write("Press [Enter] to continue... ");
Console.ReadLine();
} // end Main()
 
?

=?ISO-8859-1?Q?G=F6ran_Andersson?=

rossum said:
I ran some tests on your code as written. The results were not good:

If you called the method from a loop, you will be creating a lot of
random generators in a short time. As the system time is used to create
the initial seed in the random generator, this will of course give bad
randomness.

If you are going to create more than one random number, you should
create one random generator, and use that to create all the random numbers.
 
R

rossum

If you called the method from a loop, you will be creating a lot of
random generators in a short time. As the system time is used to create
the initial seed in the random generator, this will of course give bad
randomness.

If you are going to create more than one random number, you should
create one random generator, and use that to create all the random numbers.
I did that, I pulled the RNG declaration outside the function so it
was only declared once. The OP's function is overly complex for
producing a single digit and does not produce linearly random results.

In theory, a cryptographic PRNG should give different numbers every
time it is started, even if new copies are started very close to each
other and with the same seed - relying entirely on the system timer
(as with Random) would disqualify it as a cryptographic PRNG. As far
as I am aware the Microsoft cryptographic PRNG passes those tests.

Update: I just put the CPRNG back inside the function and tested it
with my improved random digit generator:

Low values = 0
0 -> 1031
1 -> 962
2 -> 955
3 -> 1033
4 -> 1015
5 -> 948
6 -> 1019
7 -> 1023
8 -> 973
9 -> 1041
High values = 0
10000 tests total.

It is a good cryptographic PRNG and can cope well with being
instantiated many times quickly. There are some details of it in
section 7.1.3 of RFC 4068 (http://rfc.net/rfc4086.html#s7.1.3.)


rossum
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top