Generating public/private key pair based on input - cryptography

OpenSSL provides tools to generate random public/private key pairs. Is there any mechanism to deterministically generate a pair based on some initial value?
For example, given the string 'abcd', generate a public/private key pair, such that the same public/private key pair can be generated again using the same string.

For sure, just use your password in a PBKDF to generate a key like array of bytes (random salt and high iteration count required). Then use this array of bytes as seed for a PRNG. Make sure that you always use the same PRNG! Then use that PRNG as input for RSA_generate_key. Make sure that generate key implementation is not changed.
Please read the answers on Initialize a PRNG with a password on crypto.stackexchange.com. Note that usually the private key is encrypted instead, e.g. using the PKCS#12 container. Note that both PKCS#12 containers and the method above are vulnerable to brute force attacks. Most passwords do deliver a very limited amount of entropy, making these brute force attacks more feasible. The advantage of the PKCS#12 container is that you do not have to store it with the ciphertext, it is only required during signature generation or decryption. Using a 128 bit hex value as password would alleviate the issue of brute forcing, but you likely won't be able to remember it.
Note that RSA key pair generation takes a lot of time (and finding a large prime has a nondeterministic running time, so it may take very long for specific key pairs). EC F(p) keys would be much less cumbersome.
Feasible? Certainly. Useful? Possibly. Fraught with danger? Certainly.

Related

Do I need to hash a Redis key before using *SET?

I'm under the impression that one should hash (i.e. sha3) their Redis key before adding data to it. (It might have even been with regard to memcache.) I don't remember why I have this impression or where it came from but I can't find anything to validate (or refute) it. The reasoning was the hash would help with even distribution across a cluster.
When using Redis (in either/both clustered and non-clustered modes) is it best pracatice to hash the key before calling SET? e.g. set(sha3("username:123"), "owlman123")
No, you shouldn't hash the key. Redis Cluster hashes the key itself for the purpose of choosing the node:
There are 16384 hash slots in Redis Cluster, and to compute what is the hash slot of a given key, we simply take the CRC16 of the key modulo 16384.
You can also use hash tags to control which keys share the same slot.
It might be a good idea if your keys are very long, as recommended in the official documentation:
A few other rules about keys:
Very long keys are not a good idea. For instance a key of 1024 bytes is a bad idea not only memory-wise, but also because the lookup of the key in the dataset may require several costly key-comparisons. Even when the task at hand is to match the existence of a large value, hashing it (for example with SHA1) is a better idea, especially from the perspective of memory and bandwidth.
source: https://redis.io/docs/data-types/tutorial/#keys

Key types supported by Redis

What are the different key types supported by Redis? The documentation mentions all the various types (strings, set, hashmap, etc) of values supported by Redis, but I couldn't quiet find the key type information.
From redis documentation (Data types intro):
Redis keys
Redis keys are binary safe, this means that you can use any binary sequence as a key, from a string like "foo" to the content
of a JPEG file. The empty string is also a valid key. A few other
rules about keys:
Very long keys are not a good idea. For instance a key of 1024 bytes is a bad idea not only memory-wise, but also because the
lookup of the key in the dataset may require several costly
key-comparisons. Even when the task at hand is to match the
existence of a large value, hashing it (for example with SHA1) is a
better idea, especially from the perspective of memory and
bandwidth.
Very short keys are often not a good idea. There is little point in writing "u1000flw" as a key if you can instead write
"user:1000:followers". The latter is more readable and the added
space is minor compared to the space used by the key object itself
and the value object. While short keys will obviously consume a bit
less memory, your job is to find the right balance.
Try to stick with a schema. For instance "object-type:id" is a good idea, as in "user:1000". Dots or dashes are often used for multi-word
fields, as in "comment:1234:reply.to" or "comment:1234:reply-to".
The maximum allowed key size is 512 MB.
From my experience any binary sequence typically means a String, but I may not be familiar with languages where you can achieve this by using other data types.
Keys in Redis are all strings, so it doesn't really matter what kind of value you pass into a client. Under-the-hood the RESP protocol is used and it will pass the value as a string to the engine.
Example:
ZADD some_key 1 some_value
some_key is always a string, even if you pass 3 as key, it is handled as a string. This is true for every client.

Naming Convention and Valid Characters for a Redis Key

I was wondering what characters are considered valid in a Redis key. I have googled for some time and can not find any useful info.
Like in Python, valid variable name should belong to the class [a-zA-Z0-9_]. What are the requirements and conventions for Redis keys?
Part of this is answered here, but this isn't completely a duplicate, as you're asking about allowed characters as well as conventions.
As for valid characters in Redis keys, the manual explains this completely:
Redis keys are binary safe, this means that you can use any binary sequence as a key, from a string like "foo" to the content of a JPEG file. The empty string is also a valid key.
A few other rules about keys:
Very long keys are not a good idea, for instance a key of 1024 bytes is a bad idea not only memory-wise, but also because the lookup of the key in the dataset may require several costly key-comparisons. Even when the task at hand is to match the existence of a large value, to resort to hashing it (for example with SHA1) is a better idea, especially from the point of view of memory and bandwidth.
Very short keys are often not a good idea. There is little point in writing "u1000flw" as a key if you can instead write "user:1000:followers". The latter is more readable and the added space is minor compared to the space used by the key object itself and the value object. While short keys will obviously consume a bit less memory, your job is to find the right balance.
Try to stick with a schema. For instance "object-type:id" is a good idea, as in "user:1000". Dots or dashes are often used for multi-word fields, as in "comment:1234:reply.to" or "comment:1234:reply-to".
The maximum allowed key size is 512 MB.

what is difference between decoding time for aes 128/192/256, is aes192/256 too paranoic?

given this supercomputer : http://en.wikipedia.org/wiki/Tianhe-1A - that is no.1 at TOP500, operating at 2.5 petaFLOPS, how long it would take on average to decrypt properly encoded (that is with random password) string in these three ciphers ?
A bruteforce attack in the key space on even AES128 isn't currently feasible. But as security is only as strong as the weakest part of it, you usually attack the password which almost always has an entropy much smaller than the keysize.
You can't encode based on a password with raw AES. AES uses a key.
You first need to derive a key from the password, and this step is crucial to the security. Typically you use a password-based-key-derivation-function such as PBKDF2 to derive the key from the password. You need to use a random salt and an appropriate number of iterations.
And of course the password entropy is very important. An attacker will first try dictionary words and their variations and then continue on to brute forcing short passwords. How fast this is depends on the number of iterations of your key derivation.
There are recent attacks that reduce the effectiveness of AES256. Therefore, Bruce Shneier reccommends AES128.

RSA Cryptography in c#

Suppose an RSA algorithm created private key on two machines. Is there any possibility that both keys are the same?
Short answer: No. There is a theoretical possibility, but even if you create a key every second you aren't likely to get the same one twice before the sun explodes.
Yes. Have you heard of the pigeon-hole principle?
Normally, you create RSA keys by randomly selecting extremely large numbers and checking whether they're prime.
Given the sizes of the numbers involved (100+ digits), the only reasonable possibility of a collision is if there's a problem in the random number generator, so that (at least under some circumstances) the numbers it picks aren't very random.
This was exactly the sort of problem that led to a break in the SSL system in Netscape (~4.0, if memory serves). In this particular case, the problem was in generating a session key, but the basic idea was the same -- a fair amount of the "random" bits that were used were actually pretty predictable, so an attacker who knew the sources of the bits could fairly quickly generate the same "random" number, and therefore the same session key.
yes. but probability is very low
In the RSA cryptosystem with public key (n,e), the private key (n,d) is generated such that n = p * q, where p, q are large N-bit primes and ed − 1 can be evenly divided by the totient (p − 1)(q − 1).
To generate the same private key, you essentially need to generate the same p,q,e so it is an abysmally small probability.