1节一密钥导出函数

1节一密钥导出函数

本文介绍了是否ECDiffieHellmanCng在.NET中有一个实现NIST SP 800-56A,第5.8.1节一密钥导出函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我手头需要导出使用NIST SP 800-56A,第5.8.1节中描述的密钥导出功能键材料的任务。我不是在密码学方面的专家,所以如果这个问题是幼稚的,请原谅我。以下是我迄今所做的:

I have a task at hand that requires deriving key material using the key derivation function described in NIST SP 800-56A, section 5.8.1. I'm not an expert in Cryptography so please excuse me if the question is naive. Here's what I've done so far:


  1. 我有对方的公钥和我的私钥

  2. 现在,我尝试生成像这样的使用ECDH 1.3.132.1.12使用C#共享密钥(.NET 4)ECDiffieHellmanCng类:

  1. I have the other party's public key and my private key
  2. Now I try to generate the shared secret using ECDH 1.3.132.1.12 using C# (.NET 4) ECDiffieHellmanCng class like so:

// The GetCngKey method reads the private key from a certificate in my Personal certificate store

CngKey cngPrivateKey = GetCngKey();

ECDiffieHellmanCng ecDiffieHellmanCng = new ECDiffieHellmanCng(cngPrivateKey);

ecDiffieHellmanCng.HashAlgorithm = CngAlgorithm.ECDiffieHellmanP256;
ecDiffieHellmanCng.KeyDerivationFunction = ?? // What do I set here


最后做到这一点:

ecDiffieHellmanCng.DeriveKeyMaterial(otherPartyPublicKey:);

在哪里/我该如何设置其他参数算法ID,U方信息,甲方V的信息?

Where/how do I set the other parameters Algorithm ID, Party U Info, Party V Info?

修改
我打开使用其他库,例如充气城堡(前提是他们可以从.NET调用)

EDITI am open to using other libraries like Bouncy Castle (provided they can be called from .NET)

推荐答案

TL; DR;我还没有找到一种方式来获得使用KDF在NIST SP 800-56A描述的对称密钥,第5.8.1节使用在.NET 4.0中单独内置类

TL;DR; I haven't found a way to derive the symmetric key using KDF described in NIST SP 800-56A, section 5.8.1 using built-in classes in .NET 4.0 alone

好消息(对我:-))是它采用了可爱BouncyCastle的库在.NET 4.0中是可能的(的NuGet:安装封装BouncyCastle的-外部-Version1.7.0)。具体方法如下:

The good news (for me :-)) is that it IS possible in .NET 4.0 using the lovely BouncyCastle library (NuGet: Install-Package BouncyCastle-Ext -Version "1.7.0"). Here's how:

第1步:获取对方的公钥

STEP 1: Get other party's public key

根据你的情况下,这可以由一个证书读取或来给你为包含加密的数据的消息的一部分。一旦你的Base64编码的连接codeD公共密钥,它读入一个Org.BouncyCastle.Crypto.Parameters.ECPublicKeyParameters对象,像这样:

Depending on your scenario, this may be read from a certificate or come to you as part of the message containing the encrypted data. Once you have the Base64 encoded public-key, read it into a Org.BouncyCastle.Crypto.Parameters.ECPublicKeyParameters object like so:

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

第2步:读您的私人密钥

STEP 2: Read your private-key

这将最通常涉及读取从PFX / P12证书的私钥。 Windows帐户运行code应该有机会获得PFX / P12,另外,如果证书导入证书存储区,你需要通过所有任务授予的权限 - >在certmgr管理私钥菜单。 MSC

This would most-commonly involve reading the private key from a PFX/P12 certificate. The windows account running the code should have access to the PFX/P12 and additionally, if the certificate is imported into a certificate store, you'll need to grant permissions via the All Tasks -> manage private key menu in certmgr.msc

using (StreamReader reader = new StreamReader(path))
{
    var fs = reader.BaseStream;
    string password = "<password for the PFX>";
    Pkcs12Store store = new Pkcs12Store(fs, passWord.ToCharArray());

   foreach (string n in store.Aliases)
   {
       if (store.IsKeyEntry(n))
       {
           AsymmetricKeyEntry asymmetricKey = store.GetKey(n);

           if (asymmetricKey.Key.IsPrivate)
           {
               ECPrivateKeyParameters privateKey = asymmetricKey.Key as ECPrivateKeyParameters;
           }
       }
   }
}

第3步:计算共享的秘密

STEP 3: Compute the shared secret

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

步骤4:prepare信息来计算对称密钥要求:

STEP 4: Prepare information required to compute symmetric key:

byte[] algorithmId = Encoding.ASCII.GetBytes(("<prependString/Hex>" + "id-aes256-GCM"));
byte[] partyUInfo = Encoding.ASCII.GetBytes("<as-per-agreement>");
byte[] partyVInfo = <as-per-agreement>;
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();

步骤5:导出对称密钥

// NOTE: Use the digest/Hash function as per your agreement with the other party
IDigest digest = new Sha256Digest();
byte[] symmetricKey = 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(symmetricKey, 0);

现在你有对称密钥准备做解密。以使用AES执行解密,BouncyCastle的IWrapper可以使用。通过调用WrapperUtilities.GetWrapper(AES //)获得使用Org.BouncyCastle.Security.WrapperUtilities的IWrapper例如AES / CBC / PKCS7。这也将取决于通信双方之间的协议。

Now you have the symmetric key ready to do the decryption. To perform decryption using AES, BouncyCastle IWrapper can be used. Obtain an IWrapper using Org.BouncyCastle.Security.WrapperUtilities by calling WrapperUtilities.GetWrapper("AES//") e.g. "AES/CBC/PKCS7". This will also depend on the agreement between the two communicating parties.

初​​始化密码(IWrapper)对称密钥和初始化向量(IV),并调用展开方法来获取纯文本字节。最后,转换为字符串使用使用的字符编码​​(如UTF8 / ASCII / UNI code)

Initialize the cipher (IWrapper) with symmetric key and initialization vector (IV) and call the Unwrap method to get plain-text bytes. Finally, convert to string literal using the character encoding used (e.g. UTF8/ASCII/Unicode)

这篇关于是否ECDiffieHellmanCng在.NET中有一个实现NIST SP 800-56A,第5.8.1节一密钥导出函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-31 20:40