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

时间:2013-08-09 20:58:24

标签: c openssl pki elliptic-curve diffie-hellman

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

peerkey = get_peerkey(pkey);

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

  1. get_peerkey()如何实际仅从pkey中提取公钥以发送给对等方?
  2. 代码如何从pKey中提取私钥和参数以存储它们以供以后在密钥交换后使用?
  3. get_peerkey()如何从对等方的原始公钥生成新的EVP_PKEY结构?
  4. 我见过OpenSSL函数EVP_PKEY_print_public()EVP_PKEY_print_private()EVP_PKEY_print_params()但这些函数用于生成人类可读的输出。我还没有找到将人类可读的公钥转换回EVP_PKEY结构的任何等价物。

1 个答案:

答案 0 :(得分: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()以获取八位字节,这只是无符号字符*。
  4. 要反序列化公钥:

    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。
    4. 要序列化私钥:

      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 *。
      4. 要反序列化私钥:

        1. 将mpi传递给BN_mpi20bn()以获得BIGNUM。
        2. 将BIGNUM传递给EC_KEY_set_private_key()以获取EC_KEY。
        3. 将EC_KEY传递给EVP_PKEY_set1_EC_KEY以获取EVP_KEY。
        4. 也可以将BIGNUM转换为十六进制,十进制或“bin”,尽管我认为mpi使用的字节最少。