如何访问OpenSSL'中的原始ECDH公钥、私钥和参数;s EVP_PKEY结构?

如何访问OpenSSL'中的原始ECDH公钥、私钥和参数;s EVP_PKEY结构?,c,openssl,pki,elliptic-curve,diffie-hellman,C,Openssl,Pki,Elliptic Curve,Diffie Hellman,在第一个代码示例之后,我使用OpenSSL的c库生成一个椭圆曲线Diffie-Hellman(ECDH)密钥对。它掩盖了公钥的实际交换: peerkey = get_peerkey(pkey); pkey变量和返回值都属于EVP*类型pkey包含先前生成的公钥、私钥和参数,返回值仅包含对等方的公钥。因此,这提出了三个问题: get_peerkey()如何从pkey中提取公钥发送给对等方 代码将如何从pKey中提取私钥和参数以存储它们,以便在密钥交换后使用 get_peerkey()如何从对等方

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

peerkey = get_peerkey(pkey);
pkey
变量和返回值都属于
EVP*
类型
pkey
包含先前生成的公钥、私钥和参数,返回值仅包含对等方的公钥。因此,这提出了三个问题:

  • get_peerkey()
    如何从
    pkey
    中提取公钥发送给对等方
  • 代码将如何从
    pKey
    中提取私钥和参数以存储它们,以便在密钥交换后使用
  • get_peerkey()
    如何从对等方的原始公钥生成新的
    EVP_PKEY
    结构

  • 我已经看到了OpenSSL函数
    EVP\u PKEY\u print\u public()
    EVP\u PKEY\u print\u private()
    ,以及
    EVP\u PKEY\u print\u params()
    ,但这些函数用于生成人类可读的输出。我还没有找到任何等价物将人类可读的公钥转换回
    EVP_PKEY
    结构。

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

    要序列化公钥,请执行以下操作:

  • 将EVP_PKEY传递给EVP_PKEY_get1_EC_KEY()以获取EC_KEY
  • 将EC_密钥传递给EC_KEY_get0_public_KEY()以获取EC_点数
  • 将EC_点传递到EC_点_点2oct()以获取八位字节,它们只是无符号字符*
  • 要反序列化公钥,请执行以下操作:

  • 将八进制数传递到EC_POINT_oct2point()以获取EC_POINT
  • 将EC_点传递到EC_KEY_set_public_KEY()以获取EC_密钥
  • 将EC_密钥传递给EVP_PKEY_set1_EC_密钥以获取EVP_密钥
  • 要序列化私钥,请执行以下操作:

  • 将EVP_PKEY传递给EVP_PKEY_get1_EC_KEY()以获取EC_KEY
  • 将EC_密钥传递给EC_KEY_get0_private_KEY()以获取BIGNUM
  • 将BIGNUM传递给BN_bn2mpi()以获取mpi,这是一种写入的格式 无符号字符*
  • 要反序列化私钥,请执行以下操作:

  • 将mpi传递给BN_mpi2bn()以获取BIGNUM
  • 将BIGNUM传递给EC_KEY\u set_private_KEY()以获取EC_密钥
  • 将EC_密钥传递给EVP_PKEY_set1_EC_密钥以获取EVP_密钥

  • 也可以将BIGNUM转换为十六进制、十进制或“bin”,尽管我认为mpi使用的字节数最少。

    感谢您提供后续答案!反序列化公钥may在4年零5个月前就开始工作了,但今天听起来相当复杂!!!:p EVP_PKEY_get1_EC_密钥应该从八位字节创建EC_点,但它从输入中获得一个EC_点*!我试图通过EC_POINT_new创建密钥,但后来无法使用create EVP_密钥创建密钥!