Est-ce que ECDiffieHellmanCng dans .NET a une fonction de dérivation de clé qui implémente NIST SP 800-56A, section 5.8.1

J’ai une tâche à accomplir qui nécessite de dériver des éléments de clé à l’aide de la fonction de dérivation de clé décrite dans NIST SP 800-56A, section 5.8.1. Je ne suis pas un expert en cryptographie, alors veuillez m’excuser si la question est naïve. Voici ce que j’ai fait jusqu’à présent:

  1. J’ai la clé publique de l’autre partie et ma clé privée
  2. Maintenant, j’essaie de générer le secret partagé en utilisant ECDH 1.3.132.1.12 en utilisant la classe C # (.NET 4) ECDiffieHellmanCng comme ceci:

    // The GetCngKey method reads the private key from a certificatee in my Personal certificatee store CngKey cngPrivateKey = GetCngKey(); ECDiffieHellmanCng ecDiffieHellmanCng = new ECDiffieHellmanCng(cngPrivateKey); ecDiffieHellmanCng.HashAlgorithm = CngAlgorithm.ECDiffieHellmanP256; ecDiffieHellmanCng.KeyDerivationFunction = ?? // What do I set here 

Enfin faire ceci:

 ecDiffieHellmanCng.DeriveKeyMaterial(otherPartyPublicKey:); 

Où / comment définir les autres parameters ID algorithme, Informations sur la partie U, Informations sur la partie V?

EDIT Je suis ouvert à l’utilisation d’autres bibliothèques comme Bouncy Castle (à condition qu’elles puissent être appelées à partir de .NET)

TL; DR; Je n’ai pas trouvé de moyen de dériver la clé symésortingque à l’aide de KDF décrite dans la section 5.8.1 du NIST SP 800-56A à l’aide de classes intégrées dans .NET 4.0 uniquement.

La bonne nouvelle (pour moi :-)) est que cela est possible dans .NET 4.0 en utilisant la ravissante bibliothèque BouncyCastle (NuGet: Install-Package BouncyCastle-Ext -Version “1.7.0”). Voici comment:

ÉTAPE 1: Obtenir la clé publique de l’autre partie

Selon votre scénario, cela peut être lu à partir d’un certificate ou vous être envoyé en tant que partie du message contenant les données cryptées. Une fois que vous avez la clé publique codée en Base64, lisez-la dans un object Org.BouncyCastle.Crypto.Parameters.ECPublicKeyParameters comme ceci:

 var publicKeyBytes = Convert.FromBase64Ssortingng(base64PubKeyStr); ECPublicKeyParameters otherPartyPublicKey = (ECPublicKeyParameters)PublicKeyFactory.CreateKey(publicKeyBytes); 

ÉTAPE 2: lisez votre clé privée

Cela implique le plus souvent la lecture de la clé privée à partir d’un certificate PFX / P12. Le compte Windows qui exécute le code doit avoir access à PFX / P12. De plus, si le certificate est importé dans un magasin de certificates, vous devez accorder des permissions via le menu Toutes les tâches -> gérer les clés privées de certmgr.msc.

 using (StreamReader reader = new StreamReader(path)) { var fs = reader.BaseStream; ssortingng password = ""; Pkcs12Store store = new Pkcs12Store(fs, passWord.ToCharArray()); foreach (ssortingng n in store.Aliases) { if (store.IsKeyEntry(n)) { AsymmesortingcKeyEntry asymmesortingcKey = store.GetKey(n); if (asymmesortingcKey.Key.IsPrivate) { ECPrivateKeyParameters privateKey = asymmesortingcKey.Key as ECPrivateKeyParameters; } } } } 

ÉTAPE 3: Calculez le secret partagé

 IBasicAgreement aKeyAgree = AgreementUtilities.GetBasicAgreement("ECDH"); aKeyAgree.Init(privateKey); BigInteger sharedSecret = aKeyAgree.CalculateAgreement(otherPartyPublicKey); byte[] sharedSecretBytes = sharedSecret.ToByteArray(); 

ÉTAPE 4: Préparez les informations requirejses pour calculer la clé symésortingque:

 byte[] algorithmId = Encoding.ASCII.GetBytes(("" + "id-aes256-GCM")); byte[] partyUInfo = Encoding.ASCII.GetBytes(""); byte[] partyVInfo = ; MemoryStream stream = new MemoryStream(algorithmId.Length + partyUInfo.Length + partyVInfo.Length); var sr = new BinaryWriter(stream); sr.Write(algorithmId); sr.Flush(); sr.Write(partyUInfo); sr.Flush(); sr.Write(partyVInfo); sr.Flush(); stream.Position = 0; byte[] keyCalculationInfo = stream.GetBuffer(); 

ÉTAPE 5: Dérivez la clé symésortingque

 // NOTE: Use the digest/Hash function as per your agreement with the other party IDigest digest = new Sha256Digest(); byte[] symmesortingcKey = new byte[digest.GetDigestSize()]; digest.Update((byte)(1 >> 24)); digest.Update((byte)(1 >> 16)); digest.Update((byte)(1 >> 8)); digest.Update((byte)1); digest.BlockUpdate(sharedSecret, 0, sharedSecret.Length); digest.BlockUpdate(keyCalculationInfo, 0, keyCalculationInfo.Length); digest.DoFinal(symmesortingcKey, 0); 

Vous avez maintenant la clé symésortingque prête à effectuer le déchiffrement. Pour effectuer le déchiffrement à l’aide d’AES, vous pouvez utiliser BouncyCastle IWrapper. Obtenez un IWrapper en utilisant Org.BouncyCastle.Security.WrapperUtilities en appelant WrapperUtilities.GetWrapper (“AES //”), par exemple “AES / CBC / PKCS7”. Cela dépendra également de l’accord entre les deux parties communicantes.

Initialisez le chiffrement (IWrapper) avec la clé symésortingque et le vecteur d’initialisation (IV) et appelez la méthode Unwrap pour obtenir des octets en texte brut. Enfin, convertissez la chaîne en chaîne en utilisant le codage de caractères utilisé (par exemple, UTF8 / ASCII / Unicode).