This question already has answers here:
Generate a random number using the C Preprocessor
(2 answers)
Closed 6 years ago.
I'm developing a method for encrypting game data files which will be used in a game engine that I'm creating. The game data file will be encrypted with a private key and decrypted once loaded into the game engine.
The private key will be set manually in the engine (as a const) so that it is compiled into the engine. The trick, however, is obfuscating it in there so that your average Joe Bloggs can't (easily) find the key simply by disassembling and reverse-engineering the code.
struct Example {
u_int8_t random1;
u_int64_t segment31;
u_int8_t random2;
u_int8_t random3;
u_int64_t segment3;
u_int64_t segment14;
// Etc
};
My idea is to store the key in segments which are jumbled together with randomly generated bytes. My question is this:
Is there any way to randomly generate a number in a C++ macro? The number must be randomly generated at compile time (or the random values each set to a random user-selected value), so any runtime functions are no good.
I'm open to any suggestions if there is a better way of doing this, but I definitely want the game data files encrypted with a private/public key pair, and the public key kept as private as possible.
Since you are generating a constant random number at compile time which will become baked into your program, I don't see a difference between that and simply hard-coding a random number (of your own choosing) into it yourself. I suppose with a macro you get a different random number with each compile. Is that really so critical?
I recommend doing something simpler: If the key were simply ASCII text (bits are bits, right?) you could use an inocuous-looking diagnostic string as your key and no one would notice it.
Still, security by obscurity is generally frowned on by experts in the field (they do a lot of frowning). If you are really doing public key encryption, it is perfectly OK to have the public key exposed. That is the point after all. It is the private key which must be kept secret.
If you really want to do this, then I would look at a random number generation algorithm, and unroll an iteration of it into a (large) macro that essentially takes a seed and evaluates to a large expression that yields a pseudorandom integer as its result. That should do it. If the seed were somehow derived from an unpredictable thing like the time of the compile (__TIME__), it just might work.
There's not currently any rand macro or template metafunction, but it could be created...with a lot of effort.
On the other hand, you could simply touch /dev/random as part of your build process, or some other random source, and create a header with the result. Include this header where you get a random number constant.
Related
I am struggling with finding examples for OpenWall's bcrypt implementation that use crypt_gensalt_rn and crypt_r that also explain in depth exactly what is happening in terms of input, settings etc and more generally the cryptographic component. crypt and crypt_gensalt are not really viable due to them not being MT-Safe so I am trying to better understand the rn, ra, and r implementations.
Summary: I want to better understand what the
the parameters to the function are and what their purposes are.
What are the best practices cryptographically for password hashing using these re-entrant ones and how to use them safely in a MT environment so I am not one of those developers who just uses crypto functions without understanding the implications of them and pitfalls.
when generating random bytes for the salt generator, what is a cryptographically strong source for random bytes?
I am also open to recommendations to other libraries etc. but they need to be production ready.
Tried to solve this on my own. Here is what I found out:
1a. crypt_gensalt_rn:
prefix = Prefix code in the form of $<Algorithim>$ ex. $2a$
count : The number of rounds you want the hashing algorithim to run. Set this value by response time. (ie. if you want to finish a hash in 1s, then run a benchmark and figure out the # of rounds needed to respond in 1s)
rbytes, nrbytes : rbytes is a set of random bytes and nrbytes is the length of said char array of randombytes. You can pass NULL to rbytes and 0 to nrbytes to have the OS get them for you (best practice typically unless OS doesn't have random bytes hardware needed which can result in a security risk)
output, output_size : This is defined by each algorithm individually. In the case of bcrypt it is 32 or the length of the setting string for crypt_ra. This stores in the format of $<Algorithim>$<rounds>$<salt> for bcrypt and many others.
1b. crypt_ra(const char *phrase, const char *setting, void **data, int *size);
phrase : the text you want to hash
setting: the setting string (ie. char* output) made in crypt_gensalt_rn.
data : a pointer to a generic crypt_struct used by most linux libraries. This is where crypt_ra will allocate a struct you need to free.
size : A pointer to an integer that crypt_ra will set to the length in bytes of the crypt struct.
Ra and RN are safe in Multithreaded environments. Make sure if your server doesn't support Random Byte Generation via hardware there can be a security risk (this was reported). Set rounds to a time you want it to take to verify a password not a # of rounds.
You can use the OS if it has the appropriate hardware. Otherwise you can use RNG like mersenne twister.
I am wondering if there is a way to generate a Cryptographic Nonce using OpenSSL or Crypto++ libraries. Is there anything more to it than just generating a set of random bytes using autoseeded pools?
I am wondering if there is a way to generate a cryptographic nonce using OpenSSL or Crypto++ libraries.
Crypto++:
SecByteBlock nonce(16);
AutoSeededRandomPool prng;
prng.GenerateBlock(nonce, nonce.size());
OpenSSL:
unsigned char nonce[16];
int rc = RAND_bytes(nonce, sizeof(nonce));
unsigned long err = ERR_get_error();
if(rc != 1) {
/* RAND_bytes failed */
/* `err` is valid */
}
/* OK to proceed */
Is there anything more to it than just generating a set of random bytes using autoseeded pools?
A nonce is basically an IV. Its usually considered a public parameter, like an IV or a Salt.
A nonce must be unique within a security context. You may need a nonce to be unpredictable, too.
Uniqueness and unpredictability are two different properties. For example, a counter starting at 0000000000000000 is unique, but its also predictable.
When you need both uniqueness and unpredictability, you can partition the nonce into a random value and a counter. The random value will take up 8 bytes of a 16 byte nonce; while the counter will take up the remaining 8 bytes of a 16 byte nonce. Then you use an increment function to basically perform i++ each time you need a value.
You don't need an 8-8 split. 12-4 works, as does 4-12. It depends on the application and the number of nonces required before rekeying. Rekeying is usually driven by plain text byte counts.
16-0 also works. In this case, you're using random values, avoiding the counter, and avoiding the increment function. (The increment function is basically a cascading add).
NIST SP800-38C and SP800-38D offer a couple of methods for creating nonces because CCM and GCM uses them.
Also see What are the requirements of a nonce? on the Crypto Stack Exchange.
You need a unique number for each nonce. You can use either a serial number or a random number. To help ensure uniqueness, it is common, though not required, to add a timestamp to the nonce. Either passing the timestamp as a separate field or concatenating it with the nonce. Sometimes information such as IP addresses and process IDs are also added.
When you use a serial number, you don't need to worry about skipping numbers. That's fine. Just make sure you never repeat. It must be unique across restarts of your software. This is one place where adding a timestamp can help. Because time-in-millis+serial-number is almost certainly unique across restarts of the server.
For the pseudo random number generator, anyone should be fine. Just make sure that you use a sufficiently large space to make the chances of getting a duplicate effectively impossible. Again, adding time will reduce the likelihood of you getting duplicates as you'll need to get the same random number twice in the same millisecond.
You may wish to hash the nonce to obscure the data in it (eg: process ID) though the hash will only be secure if you include a secure random number in the nonce. Otherwise it may be possible for a viewer of the nonce to guess the components and validate by redoing the hash (ie: they guess the time and try all possible proc IDs).
No. If the nonce is large enough then an autoseeded DRBG (deterministic random bit generator - NIST nomenclature) is just fine. I would suggest a nonce of about 12 bytes. If the nonce needs to be 16 bytes then you can leave the least significant bits - most often the rightmost bytes - set to zero for maximum compatibility.
Just using the cryptographically secure random number generators provided by the API should be fine - they should be seeded using information obtained from the operating system (possibly among other data). It never hurts to add the system time to the seed data just to be sure.
Alternatively you could use a serial number, but that would require you to keep some kind of state which may be hard across invocations. Beware that there are many pitfalls that may allow a clock to repeat itself (daylight saving, OS changes, dead battery etc. etc.).
It never hurts to double check that the random number generator doesn't repeat for a large enough output. There have been issues just with programming or system configuration mistakes, e.g. when a fix after a static code analysis for Debian caused the OpenSSL RNG not to be seeded at all.
So, every time I am developing something big, with multiple modules coming together to build a final functionality, I've been wondering the same question: Where to initialize the random seed if more than 1 module needs to use the random function?
If I have a certain class that needs random (e.g. class that initializes itself by sorting an input array with self-implemented quicksort, so I would need a random for the pivot choice), I usually have a private static bool isRandOn; variable, so before I start the random pivot choice, I check that variable and do srand(time(NULL)); if the random is not on yet.
If I have a ton of utility functions in a namespace, I do a very similar thing: I put such a variable in an anonymous namespace inside my utils library, and do the more-or-less same thing as with a class.
The problem I have is when combining those modules. All by it self, I know each module will not set the seed more than once. But, I want to be able to use a various amount of my modules together, I want other people to be able to use one or more of my modules independent of the others...
So, what is the best way to handle multiple random-seed-needing modules? Set the seed in each module? Do not set the seed at all but instead document the usage of random and make the user initialize the seed if he wants to use the module? Something third?
I would suggest using Boost.Random rather than relying on some global state shared at the program level.
Boost.Random has two concepts:
Engine: which generates random numbers
Distributions: which adapt the result from the engines to provide results fitted to a certain distribution (normal, poisson, gaussian, ...)
Each module may then have its own Engine, or indeed several of them: there is no specific reason for a given Engine to be shared between several different functions within the same module.
As a final word: whatever you do make sure you have a way to set the seed(s) deterministically for bug repro purposes. Bug repro may benefit from having multiple engines (isolation of the parts helps).
You can make a special "module" for random number generation, and use that from the other parts of your application. Then you only seed once when the random-number module is initialized.
#penelope gave a correct answer. There is some complex algorithm for generating pseudo-random number sequence behind rand(). This is like some function rand_func(prev_rand), which generates next pseudo-random number from previous. For the first time you call srand(time(NULL)), which sets prev_rand to in these terms supposing time(NULL) to be quite undetermined. So you can safely call srand() (which sets ) multiple times.
The special issue is if you neet predictable pseudo-random sequences: for example, srand(0) etc. But it seems to be not your case.
The best way I came with to avoid repeating always the same initial random sequence is to do the following in each module where you call the random() function:
/* Global variable to remember if we already initialized the PRNG */
static bool seed_initialized = false;
/* Helper function to avoid having always the same sequence again and again */
static void
prng_init (unsigned int seed)
{
if (!seed_initialized)
{
srandom (seed);
seed_initialized = true;
}
}
And, each time you use random() in a function you start the function with something like:
/* Initializing PRNG with a 'reasonably strong' random seed for our purpose */
prng_init (time (NULL) - getpid());
This way, you ensure that:
You will initialize your PRNG at least the first time you go through;
You will never reinitialize the random sequence more than once within the module.
Hope this help!
I'm wondering if it's possible to find a block of text that would hash to a known value. In particular, I'm looking for a function CreateDataFromHash() that could be called as follows:
unsigned char myHash[] = "da39a3ee5e6b4b0d3255bfef95601890afd80709";
unsigned int length = 10000;
CreateDataFromHash(myHash, length);
Here CreateDataFromHash would return the string of the length 10000 containing arbitrary data, which would hash to myHash using SHA1.
Thanks.
There's no known easy or even moderately difficult way to do this in general.
The entire point of hashes (or so-called one-way functions), is that it's easy to compute them, but next to impossible to reverse their computation (find input values based on output). That said, for some hash functions, there are known methods that may allow computing inputs for a given hash value in reasonable time.
For example, this MD5 sum technique will find collisions (but not input for a given output) in about 8 hours on a 1.6GHz computer.
For SHA-1 in particular you may be interested in reading this.
One of the purposes of SHA1 is that this should be very hard to do.
hashing is a one way function. you can't get input from the output.
This would be a "preimage attack". No such thing is publicly known against SHA-1.
The only attack known against SHA-1 is a collision attack. That means I find two inputs that produce the same result, but neither of them is pre-ordained, so to speak. Even so, this attack isn't really feasible for most people -- based on the amount of computation involved, the closest I can figure is that you'd have to spend somewhere in the range of a few million dollars to build a machine that would give you about one colliding pair of keys per week (assuming it ran, doing nothing else 24/7).
You have to brute force it. See
PHP brute force password generator
Get string, do hash, compare, repeat
I want to generate int from a string and be able to generate it back.
Something like hash function but two-way function.
I want to use ints as ID in my application, but want to be able to convert it back in case of logging or debugging.
Like:
int id = IDProvider::getHash("NameOfMyObject");
object * a = createObject(id);
...
if(error)
{
LOG(IDProvider::getOriginalString(a->getId()), "some message");
}
I have heard of slightly modified CRC32 to be fast and 100% reversible, but I can not find it and I am not able to write it by myself.
Any hints what should I use?
Thank you!
edit
I have just founded the source I have the whole CRC32 thing from:
Jason Gregory : Game Engine Architecture
quotation:
"As with any hashing system, collisions are a possibility (i.e., two different strings might end up with the same hash code). However, with a suitable hash function, we can all but guarantee that collisions will not occur for all reasonable input strings we might use in our game. After all, a 32-bit hash chode represents more than four billion possible values. So if our hash function does a good job of distributing strings evently throughout this very large range, we are unlikely to collide. At Naughty Dog, we used a variant of the CRC-32 algorithm to hash our strings, and we didn't encounter a single collision in over two years of development on Uncharted: Drake's Fortune."
Reducing an arbitrary length string to a fixed size int is mathematically impossible to reverse. See Pidgeonhole principle. There is a near infinite amount of strings, but only 2^32 32 bit integers.
32 bit hashes(assuming your int is 32 bit) can have collisions very easily. So it's not a good unique ID either.
There are hashfunctions which allow you to create a message with a predefined hash, but it most likely won't be the original message. This is called a pre-image.
For your problem it looks like the best idea is creating a dictionary that maps integer-ids to strings and back.
To get the likelyhood of a collision when you hash n strings check out the birthday paradox. The most important property in that context is that collisions become likely once the number of hashed messages approaches the squareroot of the number of available hash values. So with a 32 bit integer collisions become likely if you hash around 65000 strings. But if you're unlucky it can happen much earlier.
I have exactly what you need. It is called a "pointer". In this system, the "pointer" is always unique, and can always be used to recover the string. It can "point" to any string of any length. As a bonus, it also has the same size as your int. You can obtain a "pointer" to a string by using the & operand, as shown in my example code:
#include <string>
int main() {
std::string s = "Hai!";
std::string* ptr = &s; // this is a pointer
std::string copy = *ptr; // this retrieves the original string
std::cout << copy; // prints "Hai!"
}
What you need is encryption. Hashing is by definition one way. You might try simple XOR Encryption with some addition/subtraction of values.
Reversible hash function?
How come MD5 hash values are not reversible?
checksum/hash function with reversible property
http://groups.google.com/group/sci.crypt.research/browse_thread/thread/ffca2f5ac3093255
... and many more via google search...
You could look at perfect hashing
http://en.wikipedia.org/wiki/Perfect_hash_function
It only works when all the potential strings are known up front. In practice what you enable by this, is to create a limited-range 'hash' mapping that you can reverse-lookup.
In general, the [hash code + hash algorithm] are never enough to get the original value back. However, with a perfect hash, collisions are by definition ruled out, so if the source domain (list of values) is known, you can get the source value back.
gperf is a well-known, age old program to generate perfect hashes in c/c++ code. Many more do exist (see the Wikipedia page)
Is it not possible. Hashing is not-returnable function - by definition.
As everyone mentioned, it is not possible to have a "reversible hash". However, there are alternatives (like encryption).
Another one is to zip/unzip your string using any lossless algorithm.
That's a simple, fully reversible method, with no possible collision.