如何在OpenSSL的EVP_PKEY结构中访问原始ECDH公钥,私钥和参数?

Bob*_*man 17 c openssl pki elliptic-curve diffie-hellman

我正在使用OpenSSL的c库生成椭圆曲线Diffie-Hellman(ECDH)密钥对,遵循此处的第一个代码示例.它掩盖了这一行的实际公钥交换:

peerkey = get_peerkey(pkey);
Run Code Online (Sandbox Code Playgroud)

所述pkey变量和返回值的类型都是的EVP *.pkey包含先前生成的公钥,私钥和参数,返回值仅包含对等方的公钥.所以这提出了三个问题:

  1. 如何get_peerkey()实际提取公钥pkey以便发送给对等方?
  2. 代码如何从pKey密钥交换后提取私钥和params 来存储它们以供以后使用?
  3. 如何从对等方的原始公钥get_peerkey()生成新EVP_PKEY结构?

我已经看到了OpenSSL的功能EVP_PKEY_print_public(),EVP_PKEY_print_private()EVP_PKEY_print_params()但这些是用于产生人类可读输出.我还没有找到任何将人类可读的公钥转换回EVP_PKEY结构的等价物.

Bob*_*man 36

为了回答我自己的问题,私钥和公钥有不同的路径.

要序列化公钥:

  1. 将EVP_PKEY传递给EVP_PKEY_get1_EC_KEY()以获取EC_KEY.
  2. 将EC_KEY传递给EC_KEY_get0_public_key()以获取EC_POINT.
  3. 将EC_POINT传递给EC_POINT_point2oct()以获取八位字节,这只是无符号的char*.

要反序列化公钥:

  1. 将八位字节传递给EC_POINT_oct2point()以获取EC_POINT.
  2. 将EC_POINT传递给EC_KEY_set_public_key()以获取EC_KEY.
  3. 将EC_KEY传递给EVP_PKEY_set1_EC_KEY以获取EVP_KEY.

要序列化私钥:

  1. 将EVP_PKEY传递给EVP_PKEY_get1_EC_KEY()以获取EC_KEY.
  2. 将EC_KEY传递给EC_KEY_get0_private_key()以获取BIGNUM.
  3. 将BIGNUM传递给BN_bn2mpi()以获取mpi,这是一种写入unsigned char*的格式.

要反序列化私钥:

  1. 将mpi传递给BN_mpi2bn()以获得BIGNUM.
  2. 将BIGNUM传递给EC_KEY_set_private_key()以获取EC_KEY.
  3. 将EC_KEY传递给EVP_PKEY_set1_EC_KEY以获取EVP_KEY.

也可以将BIGNUM转换为十六进制,十进制或"bin",尽管我认为mpi使用的字节最少.

  • 感谢您提供后续答复! (3认同)