从 class ECDiffieHellmanCng 中提取共享密钥
Extract the shared secret from class ECDiffieHellmanCng
我目前正在开发一个 SSH 客户端,该客户端必须能够通过 ECDH KEX(NIST-256、384 和 521)与服务器交换密钥。
我做了一些(实际上很多)研究,找到了 .NET class ECDiffieHellmanCng
,并且能够提取服务器的 public 密钥并将其导入到class。
但是,问题是我无法在不导出共享机密的情况下提取它 (ECDiffieHellmanCng.DeriveKeyMaterial(CngKey otherpartyPublicKey)
)。
有没有办法直接访问共享密钥("k" 在 RFC 文件中的称呼)?
Here 是 ECDH 实现的 RFC 中的第 7 页以及我需要共享密钥的原因:
The exchange hash H is computed as the hash of the concatenation of
the following.
string V_C, client's identification string (CR and LF excluded)
string V_S, server's identification string (CR and LF excluded)
string I_C, payload of the client's SSH_MSG_KEXINIT
string I_S, payload of the server's SSH_MSG_KEXINIT
string K_S, server's public host key
string Q_C, client's ephemeral public key octet string
string Q_S, server's ephemeral public key octet string
mpint K, shared secret <-- this is why I need the pure secret
before any derivation
感谢任何解决方案或提示!
即使经过大量研究我也找不到方法,所以答案是否定的 - 你无法提取秘密。
我的总体解决方案是完全放弃 ECDiffieHellmanCng class,而是用 C# 包装 OpenSSH 库。
希望这至少能对有相同想法的其他人有所帮助。
您实际上不需要 k
,那么,您只需要计算 H。ECDiffieHellman class 允许您这样做。
byte[] prepend = Concat(V_C, V_S, I_C, I_S, K_S, Q_C, Q_S);
byte[] exchangeHash = ecdh.DeriveKeyFromHash(otherPublic, new HashAlgorithmName("whatever your hash algorithm is"), prepend, null);
虽然这是使用 .NET 4.6.2(目前处于预览阶段)API:DeriveKeyFromHash
如果您使用的是较旧的框架,它仍然可行,但需要专门使用 ECDiffieHellmanCng 类型:
ecdhCng.SecretPrepend = prepend;
ecdhCng.SecretAppend = null;
ecdhCng.HashAlgorithm = new CngAlgorithm("whatever your hash algorithm is");
ecdhCng.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
byte[] exchangeHash = ecdhCng.DeriveKeyMaterial(otherPublic);
我目前正在开发一个 SSH 客户端,该客户端必须能够通过 ECDH KEX(NIST-256、384 和 521)与服务器交换密钥。
我做了一些(实际上很多)研究,找到了 .NET class ECDiffieHellmanCng
,并且能够提取服务器的 public 密钥并将其导入到class。
但是,问题是我无法在不导出共享机密的情况下提取它 (ECDiffieHellmanCng.DeriveKeyMaterial(CngKey otherpartyPublicKey)
)。
有没有办法直接访问共享密钥("k" 在 RFC 文件中的称呼)?
Here 是 ECDH 实现的 RFC 中的第 7 页以及我需要共享密钥的原因:
The exchange hash H is computed as the hash of the concatenation of the following.
string V_C, client's identification string (CR and LF excluded)
string V_S, server's identification string (CR and LF excluded)
string I_C, payload of the client's SSH_MSG_KEXINIT
string I_S, payload of the server's SSH_MSG_KEXINIT
string K_S, server's public host key
string Q_C, client's ephemeral public key octet string
string Q_S, server's ephemeral public key octet string
mpint K, shared secret <-- this is why I need the pure secret before any derivation
感谢任何解决方案或提示!
即使经过大量研究我也找不到方法,所以答案是否定的 - 你无法提取秘密。
我的总体解决方案是完全放弃 ECDiffieHellmanCng class,而是用 C# 包装 OpenSSH 库。
希望这至少能对有相同想法的其他人有所帮助。
您实际上不需要 k
,那么,您只需要计算 H。ECDiffieHellman class 允许您这样做。
byte[] prepend = Concat(V_C, V_S, I_C, I_S, K_S, Q_C, Q_S);
byte[] exchangeHash = ecdh.DeriveKeyFromHash(otherPublic, new HashAlgorithmName("whatever your hash algorithm is"), prepend, null);
虽然这是使用 .NET 4.6.2(目前处于预览阶段)API:DeriveKeyFromHash
如果您使用的是较旧的框架,它仍然可行,但需要专门使用 ECDiffieHellmanCng 类型:
ecdhCng.SecretPrepend = prepend;
ecdhCng.SecretAppend = null;
ecdhCng.HashAlgorithm = new CngAlgorithm("whatever your hash algorithm is");
ecdhCng.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
byte[] exchangeHash = ecdhCng.DeriveKeyMaterial(otherPublic);