Ways to generate symmetric and asymmetric keys
You seem to ask for a comparative study on the PRNG (pseudo-random number generators) used by default by OpenSSL and the Linux kernel. This could most probably fill a volume full of mathematical formulas, and to make it worse OpenSSL and the Linux PRNG are not independent since OpenSSL will use /dev/urandom as a default seed, and there are ongoing work to provide an alternative PRNG for Linux (you can see Stephan Müller work on the subject here and there and also his discussions on the linux kernel mailing list).
However, the fact is that in most cases both will share the same strengths and weaknesses:
- Strength: both are mature and well audited code generally accepted as cryptographically secure PRNG,
- Weakness: as their name state they both are pseudo random number generator, meaning they both are deterministic algorithms which, given the same seeds, will produce the same output. The unpredictability of the produced numbers is therefore directly dependent on the unpredictability of the seeds.
So, security-wise, your main concern here may not be which one from OpenSSL or /dev/urandom
to use (especially when you know now that the former relies on the latter behind the scene), but to ensure the quality of the seeding. In particular, what you may want is one or several sources of TRNG (True Random Number Generator), ie. some hardware component specially designed to serve unpredictable random data suitable for cryptography.
This will guaranty you that the quality of the seeds used by the above mentioned algorithms will not be dependent on external factors as the system I/O, load, etc. (when available these entropy sources will most likely still be used, but merged with the TRNG input). In most situations, this will have more impact on your overall keys strengths than choosing between two well-established PRNG implementations.
Now to answer your doubts:
Doubt 1:
How does the length of the key, e.g. 128, 192 or 256, affect encryption and decryption? Is is only time taken for encryption and decryption?
Yes, it is: larger key require more computational power to encrypt and decrypt. The idea behind this is that, while it will require more efforts from the legitimate devices knowing the right key, it will also require "exponentially" more effort from any potential attacker.
Regarding the right length, you will already find a lot of discussions on this website on this subject (like this nice table), with some general cases and some taking some constraints into account (like embedded devices which have very limited computational power).
Doubt 2:
Which method is more random, Method 1 or Method 2? I am inclined to think that Method 2 is random enough and the manual page of random, urandom suggest to use urandom in case one is not sure about it. However we have seed enough entropy to generate more secure random number.
Method 3 may block suddenly and for an undetermined amount of time. If this not what you want (and usually you don't want this), then the choice is indeed between methods 1 and 2.
From there, the choice is merely a matter of personal preference. I would say that the syntax using OpenSSL is more portable, and easier which can help to avoid bugs (for instance using -n
(number of lines) instead of -c
(number of bytes) as parameter of the head
command ;) ).
Doubt 3:
Can we ask OpenSSL to take random number from /dev/urandom?
This is the default behavior, but if you want to ensure this OpenSSL documentation is your friend and would advise you to add the -rand
parameter:
openssl rand -rand /dev/urandom 128 > sym_keyfile.key
Doubt 4:
Is OpenSSL help suggesting to use pkcs#8 for generating both the private and public key or only for generating the public key from the private key?
As stated in LvB comment, this is about how the keys are stored, and not generated (this is like storing a file in either a .zip
, .rar
or .tar.gz
archive).
In case you have a free choice, OpenSSL indeed advises you to use modern and standardized formats instead of the historical SSLeay format:
- With PKCS8 you will store the private key in one (possibly encrypted) file, and the public key / certificate in another (plaintext) file.
- With PKCS12 you will bundle both the private and public components in a single file (which may seem more practical but implies that if the
.p12
file is encrypted, then even the public certificate will not be readable without deciphering the file first).
Practically, the choice will often be down to what is supported by the applications which will use the keys. Its documentation will often mandate you where and how to store the key material.
Doubt 5:
Do you suggest any other method to generate more secure asymmetric keys?
I already mentioned TRNG devices above, and I would also advise you to stay on known land by using mature and well known software implementations. Software implementing poor algorithms or good algorithms but with a buggy implementation can equally annihilate your security.
And at last, stay informed since mistakes can happen everywhere, but they are most likely to be detected and solved soon in well-established solutions than in exotic ones.
Rather than trying to implement hybrid encryption yourself, I'd recommend using openssl smime
subcommand. Another option is to use gpg
, which is probably much more suitable than openssl for signing and encrypting files.
Both openssl smime
and gpg
does hybrid encryption automatically.