使用 Crypto++ 计算 ECDSA<ECP, SHA256> 密钥的共享秘密
Compute shared secret for ECDSA<ECP, SHA256> keys with Crypto++
我正在尝试执行以下操作:
- 接收 EC public 键的 x 和 y 坐标
- 生成随机 EC public 密钥
- 计算两个密钥的共享密钥
我卡在了最后一步,从文档看来我必须使用 ECDH<ECP>::Domain
但没有任何地方解释如何将密钥转换为所需的 SecByteBlock
对象,如何我可以这样做吗?伪代码如下。
std::string x = ...
std::string y = ...
auto make_curve = []{ return ASN1::secp256r1(); };
// Public key
ECDSA<ECP, SHA256>::PublicKey g_a;
g_a.Initialize(make_curve(),
ECP::Point {
Integer { x.data() },
Integer { y.data() }
});
// Private key
ECDSA<ECP, SHA256>::PrivateKey g_b;
g_b.Initialize(RANDOM_POOL, make_curve());
// Compute shared secret
ECDH<ECP>::Domain agreement { make_curve() };
SecByteBlock shared_secret_buf { agreement.AgreedValueLength() };
agreement.Agree(shared_secret_buf, ???, ???);
Wikipedia page 显示您要执行此操作:
所以首先创建一个新的密钥对(你永远不会只生成一个私钥):
ECDH < ECP >::Domain dhB( CURVE );
SecByteBlock privB(dhB.PrivateKeyLength()), pubB(dhB.PublicKeyLength());
dhB.GenerateKeyPair(rng, privB, pubB);
然后你可以像这样执行密钥协议:
if(!dhB.Agree(shared_secret_buf, privB, pubA))
throw runtime_error("Failed to reach shared secret (B)");
好的,现在剩下一个问题:对 public 点进行编码。幸运的是,这在 Wiki 中也有解释,here,基本上你应该可以使用:
void ECP::EncodePoint(BufferedTransformation &bt, const Point &P, bool compressed)
你的 pubA
缓冲区放在 &bt
中(我希望 &P
的输入很清楚,使用 false
进行压缩)。
基本上这个returns一个字节04
,然后用字段的大小(big endian)编码的X和Y的串联。
请注意,这只需要一个 ECP::Point
,并且由于密钥对生成也不使用 ECDSA,因此可以完全删除这部分代码。这很好,因为 ECDH 是一种不同的算法,使用 ECDSA 可能会使代码的可移植性降低,例如使用X25519曲线时。
我正在尝试执行以下操作:
- 接收 EC public 键的 x 和 y 坐标
- 生成随机 EC public 密钥
- 计算两个密钥的共享密钥
我卡在了最后一步,从文档看来我必须使用 ECDH<ECP>::Domain
但没有任何地方解释如何将密钥转换为所需的 SecByteBlock
对象,如何我可以这样做吗?伪代码如下。
std::string x = ...
std::string y = ...
auto make_curve = []{ return ASN1::secp256r1(); };
// Public key
ECDSA<ECP, SHA256>::PublicKey g_a;
g_a.Initialize(make_curve(),
ECP::Point {
Integer { x.data() },
Integer { y.data() }
});
// Private key
ECDSA<ECP, SHA256>::PrivateKey g_b;
g_b.Initialize(RANDOM_POOL, make_curve());
// Compute shared secret
ECDH<ECP>::Domain agreement { make_curve() };
SecByteBlock shared_secret_buf { agreement.AgreedValueLength() };
agreement.Agree(shared_secret_buf, ???, ???);
Wikipedia page 显示您要执行此操作:
所以首先创建一个新的密钥对(你永远不会只生成一个私钥):
ECDH < ECP >::Domain dhB( CURVE );
SecByteBlock privB(dhB.PrivateKeyLength()), pubB(dhB.PublicKeyLength());
dhB.GenerateKeyPair(rng, privB, pubB);
然后你可以像这样执行密钥协议:
if(!dhB.Agree(shared_secret_buf, privB, pubA))
throw runtime_error("Failed to reach shared secret (B)");
好的,现在剩下一个问题:对 public 点进行编码。幸运的是,这在 Wiki 中也有解释,here,基本上你应该可以使用:
void ECP::EncodePoint(BufferedTransformation &bt, const Point &P, bool compressed)
你的 pubA
缓冲区放在 &bt
中(我希望 &P
的输入很清楚,使用 false
进行压缩)。
基本上这个returns一个字节04
,然后用字段的大小(big endian)编码的X和Y的串联。
请注意,这只需要一个 ECP::Point
,并且由于密钥对生成也不使用 ECDSA,因此可以完全删除这部分代码。这很好,因为 ECDH 是一种不同的算法,使用 ECDSA 可能会使代码的可移植性降低,例如使用X25519曲线时。