C# ECDH与蹦蹦跳跳城堡

C# ECDH与蹦蹦跳跳城堡,c#,bouncycastle,kdf,C#,Bouncycastle,Kdf,我有一个规定 使用静态统一模型C(0e,2s,ECC CDH)密钥协商技术(如NIST特别出版物800-56Ar214中规定,共享秘密归零的要求除外)计算共享秘密Z: 基于SHA-256的单步密钥派生函数(KDF),如中所述 NIST特别出版物800-56Ar2;及 椭圆曲线运算的p-256曲线 我已经阅读并试图实现我发现的东西,但它不起作用 此时,我可以验证共享密钥是否正确,但我无法获得正确的密钥,也无法(在不编辑Bouncy Castle源代码的情况下)了解如何将其他信息引入计算。我找了

我有一个规定

使用静态统一模型C(0e,2s,ECC CDH)密钥协商技术(如NIST特别出版物800-56Ar214中规定,共享秘密归零的要求除外)计算共享秘密Z:

  • 基于SHA-256的单步密钥派生函数(KDF),如中所述 NIST特别出版物800-56Ar2;及

  • 椭圆曲线运算的p-256曲线

我已经阅读并试图实现我发现的东西,但它不起作用

此时,我可以验证共享密钥是否正确,但我无法获得正确的密钥,也无法(在不编辑Bouncy Castle源代码的情况下)了解如何将其他信息引入计算。我找了又找

代码非常简单


我被难住了,如果我做错了什么,我将非常感激任何帮助。谢谢

我的解决方案是编写单步KDF代码,而不是使用Bouncy Castle生成共享秘密。希望这有助于其他努力工作的人

//
///使用哈希SHA256获取单步KDF。
///NIST SP800 56Ar2第5.8.1.1节
/// 
///其他信息。
///私钥。
///公钥。
///所需密钥位的长度。
///字节[]。
私有静态字节[]getSingleStepKDF_SHA256(字节[]OtherInfo,
字节[]私钥,
字节[]公钥,
Int32所需密钥位长度
)
{
ByteAccumulator ba=null;
字节[]数据=null;
字节[]secret=null;
int KEYDATALINBITS=0;
整数字节=0;
uint reps=0;
uint-cntr=0;
secret=getSharedSecret(私钥、公钥);
if(secret!=null)
{
#区域单步KDF
keyDataLenInBits=所需的KeyBitLength;
keyLenInBytes=(int)(所需的KeyBitLength/8);
reps=(uint)(keydatalenibits/128);//我们的哈希长度是128字节
如果(重复次数>(UInt32.MaxValue-1))
新的例外(“重复次数过大”);
cntr=1;
if((4+(secret.Length*8)+(OtherInfo.Length*8))>256)
新的异常(“数据太大”);
ba=新的ByteAccumulator();
ba.IsBigEndian=true;
data=General.CatArray(位转换器.GetBytes(cntr).Reverse().ToArray(),
秘密
其他信息);
对于(int i=1;i
   private static Byte[] getSingleStepKDF_SHA256(  Byte[] OtherInfo, 
                                                    Byte[] PrivateKey, 
                                                    Byte[] PublicKey,
                                                    Int32  DesiredKeyBitLength
                                                 )
    {
      BigInteger                  bi              = null;
      X9ECParameters              curve           = null;
      ECDomainParameters          ecParam         = null;
      ECPrivateKeyParameters      privKey         = null;
      ECPublicKeyParameters       pubKey          = null;
      ECDHWithKdfBasicAgreement   agree           = null;
      ECPoint                     point           = null;
      ECDHKekGenerator            ecGen           = null;

      /***********************************************************************
       * 
       * I currently do not know how to include OtherInfo into the 
       * calculation.  I have tried actually modifying ECDHKekGenerator by
       * overloading CalculateAgreement to accept OtherInfo. This had no
       * affect on the resulting key.  I have tried using KdfParameters but
       * ECDHWithKdfBasicAgreement raises an exception when I do that.
       * 
       * The shared seceret is always correct.
       * 
       ************************************************************************/

      curve     = NistNamedCurves.GetByName( "P-256" );
      ecParam   = new ECDomainParameters( curve.Curve, curve.G, curve.N, curve.H, curve.GetSeed() );
      privKey   = new ECPrivateKeyParameters( new BigInteger( PrivateKey ), ecParam );            
      point     = ecParam.Curve.DecodePoint( PublicKey );   
      pubKey    = new ECPublicKeyParameters( point, ecParam );
      ecGen     = new ECDHKekGenerator( DigestUtilities.GetDigest( "SHA256" ) );
      agree     = new ECDHWithKdfBasicAgreement( NistObjectIdentifiers.IdAes256Cbc.ToString(), ecGen );

      agree.Init( privKey );

      //  The shared secret is calculated in this method as well as the key
      bi = agree.CalculateAgreement( pubKey );

      return bi.ToByteArrayUnsigned().Take( ( int )( DesiredKeyBitLength / 8 ) ).ToArray();
    }