C# 获取临时键x和y坐标

C# 获取临时键x和y坐标,c#,.net,.net-core,cryptography,diffie-hellman,C#,.net,.net Core,Cryptography,Diffie Hellman,使用.NET Core 3.1,C# 我对加密技术一点也不在行。有人能帮我吗 如何获取新生成的临时公钥X和Y字节?[编辑:使其正常工作!请参阅下面的代码] 如何生成未散列的DerivedKeyMaterial?也许这没有意义,但我被要求不要应用ecdh.HashAlgorithm=CngAlgorithm.Sha256但null不是一个选项 这就是我目前抓取X和Y字节的方法,但我认为这是错误的,因为当我在控制台中打印出来时,它与客户端生成的密钥不同 public byte[] GetEphS

使用.NET Core 3.1,C#

我对加密技术一点也不在行。有人能帮我吗

  • 如何获取新生成的临时公钥X和Y字节?[编辑:使其正常工作!请参阅下面的代码]

  • 如何生成未散列的DerivedKeyMaterial?也许这没有意义,但我被要求不要应用
    ecdh.HashAlgorithm=CngAlgorithm.Sha256但null不是一个选项

  • 这就是我目前抓取X和Y字节的方法,但我认为这是错误的,因为当我在控制台中打印出来时,它与客户端生成的密钥不同

    public byte[] GetEphSecret(byte[] myPublicKey) {
        using var ecdh = new ECDiffieHellmanCng();
    
        ecdh.ImportSubjectPublicKeyInfo(myPublicKey, out _);
        ecdh.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
    
    
        ecdh.HashAlgorithm = CngAlgorithm.Sha256;
        ecdh.GenerateKey(ECCurve.NamedCurves.nistP256);
    
        // 1. Obtain Ephemeral Key public x and y [Edit: Succesfully obtained with the following:]
    
        var x = ecdh.PublicKey.ExportParameters().Q.X;
        var y = ecdh.PublicKey.ExportParameters().Q.Y;
      
        CngKey cngKey = ImportEcPublicKey(myPublicKey);
    
        // 2. Is it possible to derive a Key that is not hashed?
        var derivedKey = ecdh.DeriveKeyMaterial(cngKey);
        return derivedKeyMaterial;
    }
    

    由于第一个问题已经由你自己回答了,所以我只回答第二个问题

    不返回原始密钥协议,只返回从该协议派生的值。此外,所使用的函数是不可逆的,因此无法确定原始密钥协议。 密钥派生的详细信息在和属性中配置。在发布的代码中,返回密钥协议的SHA256散列(
    ecdiffiehellmankeydrivationfunction.hash
    CngAlgorithm.SHA256

    没有强制返回原始密钥协议的选项,另请参见和。因此,要确定原始密钥协议,除了使用另一个库或从头开始重新计算密钥协议之外,别无选择

    关于第一个变体,BouncyCastle是一个选项。一种可能的实施方式是:

    私有静态字节[]GetKeyAgreementBC(X9ECParameters ecParams,ECPoint publicKey,字节[]privateKey)
    {
    ECDomainParameters ECDomainParameters=新的ECDomainParameters(ecParams.Curve、ecParams.G、ecParams.N);
    Org.bounchycastle.Math.EC.ECCurve curve curve=eCDomainParameters.curve;
    Org.bounchycastle.Math.EC.ECPoint pubKey=curve.CreatePoint(新的biginger(1,publicKey.X),新的biginger(1,publicKey.Y));
    BigInteger privKey=新的BigInteger(1,privateKey);
    ECPublicKeyParameters ecPubKeyParams=新的ECPublicKeyParameters(“ECDH”,pubKey,SecObjectIdentifiers.SecP256r1);
    ECPrivateKeyParameters ECPrivateKeyParams=新的ECPrivateKeyParameters(privKey,eCDomainParameters);
    IBasicAgreement basicAgreement=AgreementUtilities.GetBasicAgreement(“ECDH”);
    basicgreement.Init(ecPrivKeyParams);
    byte[]keyAgreement=basicAgreement.CalculateAgreement(ecPubKeyParams.ToByteArrayUnsigned();
    返回密钥协议;
    }
    
    关于第二种变体,必须记住,一方的密钥协议是EC点的X坐标,该坐标是通过将该方的私钥与另一方的公钥相乘而获得的,请参见(使用椭圆曲线的算法)。同样,BouncyCastle可用于必要的计算。一种可能的实施方式是:

    私有静态字节[]GetKeyAgreementExplicit(X9ECParameters ecParams、ECPoint publicKey、字节[]privateKey)
    {
    ECDomainParameters ECDomainParameters=新的ECDomainParameters(ecParams.Curve、ecParams.G、ecParams.N);
    Org.bounchycastle.Math.EC.ECCurve curve curve=eCDomainParameters.curve;
    Org.bounchycastle.Math.EC.ECPoint pubKey=curve.CreatePoint(新的biginger(1,publicKey.X),新的biginger(1,publicKey.Y));
    BigInteger privKey=新的BigInteger(1,privateKey);
    Org.BouncyCastle.Math.EC.ECPoint-keyAgreementECPoint=pubKey.Multiply(privKey.Normalize();
    byte[]keyAgreement=keyAgreementECPoint.XCoord.Tobiginger().ToByteArrayUnsigned();
    返回密钥协议;
    }
    
    如上所述,两种实现在功能上是相同的,因此可以互换。可以使用以下代码对其进行测试:

    使用Org.BouncyCastle.Asn1.Nist;
    使用Org.BouncyCastle.Asn1.Sec;
    使用Org.BouncyCastle.Asn1.X9;
    使用Org.BouncyCastle.Crypto;
    使用Org.BouncyCastle.Crypto.Parameters;
    使用Org.BouncyCastle.Math;
    使用Org.BouncyCastle.Security;
    使用Org.BouncyCastle.Utilities.Encoders;
    使用制度;
    使用System.Security.Cryptography;
    ...
    使用(var ecdhAlice=new ecdiffiehellmancing())
    使用(var ecdhBob=new ecdiffiehellmancing())
    {
    //生成Alice的私钥和公钥
    ecdhAlice.HashAlgorithm=CngAlgorithm.Sha256;
    ecdhAlice.keydrivationfunction=ecdiffiehellmankeydrivationfunction.Hash;
    ecdhAlice.GenerateKey(ECCurve.NamedCurves.nistP256);
    字节[]privateKeyAlice=ecdhAlice.ExportParameters(true).D;
    ECPoint publicKeyAlice=ecdhAlice.ExportParameters(false).Q;
    //生成Bob的私钥和公钥
    ecdhBob.HashAlgorithm=CngAlgorithm.Sha256;
    ecdhBob.keydrivationfunction=ecdiffiehellmankeydrivationfunction.Hash;
    ecdhBob.GenerateKey(ECCurve.NamedCurves.nistP256);
    字节[]privateKeyBob=ecdhBob.ExportParameters(true).D;
    ECPoint publicKeyBob=ecdhBob.ExportParameters(false).Q;
    //爱丽丝的关键协议
    字节[]KeyAgreementLocate=GetKeyAgreementBC(NistNamedCurves.GetByName(“P-256”),publicKeyBob,privateKeyAlice);
    字节[]keyAgreementSHA256Alice=SHA256.Create().ComputeHash(KeyAgreementLice);
    byte[]keyAgreementCngAlice=ecdhAlice.DeriveKeyMaterial(ecdhBob.PublicKey);
    Console.WriteLine(“Alice的原始密钥协议(BC):”+Hex.ToHexString(keyAgreementAlice));
    WriteLine(“Alice的散列密钥协议(BC):”+Hex.ToHexString(keyAgreementSHA256Alice));
    Console.WriteLine(“Alice的密钥协议(.NET):”+Hex.ToHexString(keyAgreementCngAlice));
    Console.WriteLine();
    //鲍勃的关键协议
    字节[]keyAgreementBob=GetKeyAgreementExplicit(NistNamedCurves.GetByName(“P-256”),publicKeyAlice,privateKeyBob);
    字节[]keyAgreementSHA256Bob=SHA256.Create().ComputeHash(keyAgreementBob);
    字节[]keyAgreementCngBob=ecdhBob.DeriveKeyMaterial(ecdhAlice.PublicKey);
    WriteLine(“Bob的原始密钥协议(显式):”+Hex.ToHexString(keyAgreementBob));
    Console.WriteLine(“Bob的哈希