I have private keys that are close to 2kb big.
Now I want to password encrypt them in the following manner.
- Generate the private key of an asymmetric encryption algorithm (public key can be derived from private key later) with a random number (I'm using a system PRNG).
- Generate a random salt of length 48 bytes (also from system PRNG)
- Hash the salt with argon2 and a secret password (arbitrary length, but I limited it to 64 bytes max) and a fix public payload (length 8 bytes) to an "encoded password"
- Use the encoded password to seed a PRNG to generate another secret seed of 48 bytes length
- Split the secret seed into 4 arrays of length 7 bytes, 11 bytes, 13 bytes, 17 bytes
- XOR each byte of the private key with the corresponding byte of each of those 4 arrays, using the arrays as ring arrays (if you reach the end of an array just start over from the beginning of the respective array)
I'm not sure if I'm overlooking something but wouldn't this encrypt the private key with the security of my chosen password? I'm not sure if the pseudo-block I'm generating with the 4 arrays is really as secure as I think it is. It should have period of 17017 bytes before it repeats itself. Since I can guarantee that my private key is shorter I thought this was secure.
So am I correct in assuming that if my password is shorter than 48 bytes the security of the encrypted data is that of the password length or if its longer then it's 48 bytes since it's limited by the length of the salt.
I would then save the key in a file containing the salt in cleartext and the encrypted private key. I am unconcerned with file access or any other sidechannel attacks by overwriting the salt or encrypted key. So the only way to decrypt the private key is to know the password or brute force either the password (if it's short) or 48 bytes of randomness.
My thought is that two arrays a1, a2 with random bytes in them and with the length of a (different) prime number XOR'ed in a ring fashion will produce a random byte stream with a period of len(a1) * len(a2), when it starts to repeat. More random byte arrays with lengths that are prime numbers will extend the period by the multiplicative of their respective lengths. As long as all the arrays have different lengths this should hold true, no?
Also could I skip the secret seeding if my encoded password is also 48 bytes in length?