You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用ECDiffieHellmanCng交换密钥报错“Key does not exist”求排查

问题分析与解决方案

你的问题出在**CreatePrivateKey方法的逻辑错误**——当你用自己的公钥初始化ECDiffieHellmanCng实例时,这个实例只包含公钥,没有对应的私钥,而调用DeriveKeyMaterial需要当前实例拥有私钥才能和对方的公钥计算共享密钥,所以会抛出CryptographicException: 'Key does not exist.'。

为什么会出错?

在你的原代码中:

  1. CreatePublicKey方法只返回了公钥,但没有保留生成该公钥的私钥。
  2. 当你调用CreatePrivateKey(alicePublicKey, bobPublicKey)时,你用Alice的公钥创建了一个ECDiffieHellmanCng实例——这个实例只有公钥,没有私钥,无法执行密钥派生操作(因为密钥交换需要自己的私钥 + 对方的公钥)。

修正方案

你需要让Alice和Bob各自保留自己的密钥对(公钥+私钥),而不是只保存公钥。下面是修正后的代码:

1. 定义密钥对结构

首先创建一个简单的类来存储公钥和私钥Blob:

public class EcdhKeyPair
{
    public byte[] PublicKey { get; set; }
    public byte[] PrivateKeyBlob { get; set; }
}

2. 生成密钥对(替代原CreatePublicKey)

这个方法会同时返回公钥和对应的私钥Blob:

public EcdhKeyPair CreateEcdhKeyPair()
{
    using (ECDiffieHellmanCng cng = new ECDiffieHellmanCng())
    {
        cng.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
        cng.HashAlgorithm = CngAlgorithm.Sha512;
        
        return new EcdhKeyPair
        {
            PublicKey = cng.PublicKey.ToByteArray(),
            // 导出私钥Blob,后续用于初始化ECDiffieHellmanCng实例
            PrivateKeyBlob = cng.Key.Export(CngKeyBlobFormat.EccPrivateBlob)
        };
    }
}

3. 派生共享密钥(替代原CreatePrivateKey)

这个方法用自己的私钥和对方的公钥来计算共享密钥:

public byte[] DeriveSharedSecret(byte[] ownPrivateKeyBlob, byte[] otherPublicKey)
{
    // 用自己的私钥初始化ECDiffieHellmanCng实例
    using (ECDiffieHellmanCng cng = new ECDiffieHellmanCng(
        CngKey.Import(ownPrivateKeyBlob, CngKeyBlobFormat.EccPrivateBlob)))
    {
        cng.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
        cng.HashAlgorithm = CngAlgorithm.Sha512;
        
        // 导入对方的公钥并计算共享密钥
        using (CngKey otherKey = CngKey.Import(otherPublicKey, CngKeyBlobFormat.EccPublicBlob))
        {
            return cng.DeriveKeyMaterial(otherKey);
        }
    }
}

4. 使用示例

// Alice生成自己的密钥对
EcdhKeyPair aliceKeys = CreateEcdhKeyPair();
// Bob生成自己的密钥对
EcdhKeyPair bobKeys = CreateEcdhKeyPair();

// Alice用自己的私钥 + Bob的公钥生成共享密钥
byte[] aliceSharedSecret = DeriveSharedSecret(aliceKeys.PrivateKeyBlob, bobKeys.PublicKey);
// Bob用自己的私钥 + Alice的公钥生成共享密钥
byte[] bobSharedSecret = DeriveSharedSecret(bobKeys.PrivateKeyBlob, aliceKeys.PublicKey);

// 此时aliceSharedSecret和bobSharedSecret的值完全相同,可以用于后续加密操作

额外注意事项

  • 私钥安全:私钥Blob包含敏感信息,必须妥善存储,不能泄露给第三方。
  • 资源释放:确保所有ECDiffieHellmanCng和CngKey实例都被正确释放(用using块包裹),避免资源泄漏。
  • 配置一致性:双方的KeyDerivationFunction和HashAlgorithm必须完全一致,否则无法生成相同的共享密钥。

内容的提问来源于stack exchange,提问作者Matthew Layton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:31:51