Reputation: 45
Context: VS 2015 winforms, Windows 7, using SecurityDriven Inferno library.
I'm coding an offline app which produces encrypted files to be sent as email attachments (thus not used in a client-server context). The files are first encrypted with Inferno(ETM_Transform), then sent with (sometimes, to reset password) another file, handling DHM key exchange.
The public key of each user is stored in a datatable created and persisted by the app, allowing quick access during key exchange process. For the private key, however, my problem is that the users (including myself) would prefer to recreate their private key from a pass phrase, eliminating the need to hide the key away, increasing security and portability. So I would need to build a key from the stored public key and the hashed pass phrase.
Is this a sound approach or perhaps there's a better one for this specific context?
Here is a very short code example which throws the exception: "The requested operation is not supported". How should I proceed to import the data into the key?
internal static void CreateKey(string passPhrase)
{
byte[] keyType = new byte[] { 0x45, 0x43, 0x4B, 0x34 };
byte[] keyLength = new byte[] { 0x30, 0x0, 0x0, 0x0 };
CryptoRandom cr = new CryptoRandom(); // rng used for this example
byte[] prKey = cr.NextBytes(48); // salt+hash passphrase and pass it to the private key part
byte[] pbKey = cr.NextBytes(96); // the public part, if I understand the format correctly for a cngkey using ECDH_P384
byte[] blob = Utils.Combine(keyType, keyLength); // same as concat
blob = Utils.Combine(blob, pbKey, prKey);
CngKey key = CngKey.Import(blob, CngKeyBlobFormat.EccPrivateBlob);
}
Upvotes: 2
Views: 347
Reputation: 11
CngKey
DHM blob has a specific format which includes a header - it is not a mere random byte array. You are missing that header, which is why you get an exception. Be glad that you get an exception, since what you're attempting to do is conceptually wrong. ECDH_P384
is not designed for every random private-key combination to be a valid/proper private key. You should not hand-generate a CngKey
- leave CngKey
generation to corresponding CngKey
methods.
curve25519
, on the other hand, is designed for any random private-key to be valid. You can look at reinventing or reimplementing Minilock.
Upvotes: 1
Reputation: 33266
You can't randomly generate the public key. The public key is calculated from the private key (and the curve), and you are likely getting an error that a) the public X does not match what is expected from the private key, and b) that the Y coordinate is incorrect for the given X coordinate.
You would need to compute the value of a public key from your chosen private key. As far as I know, neither .Net nor Windows CNG expose that functionality.
Upvotes: 2