生成 EC Diffie-Hellman 公钥和私钥对

2024-02-22

我需要生成 EC Diffie Hellman 密钥对。我正在使用名为 curve 的 secp256r1 和 OpenSSL。到目前为止,这就是我所拥有的:

unsigned char *ecdh(size_t *secret_len)
{
    EVP_PKEY_CTX *pctx, *kctx;
    EVP_PKEY_CTX *ctx;
    unsigned char *secret;
    EVP_PKEY *pkey = NULL, *peerkey, *params = NULL;
    /* NB: assumes pkey, peerkey have been already set up */

    /* Create the context for parameter generation */
    if(NULL == (pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL))) 
        printf("Error in EC key generation\n");

    /* Initialise the parameter generation */
    if(1 != EVP_PKEY_paramgen_init(pctx)) 
        printf("Error in EC key generation\n");

    /* We're going to use the ANSI X9.62 Prime 256v1 curve */
    if(1 != EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, NID_X9_62_prime256v1)) 
        printf("Error in EC key generation\n");

    /* Create the parameter object params */
    if (!EVP_PKEY_paramgen(pctx, &params)) 
        printf("Error in EC key generation\n");

    /* Create the context for the key generation */
    if(NULL == (kctx = EVP_PKEY_CTX_new(params, NULL))) 
        printf("Error in EC key generation\n");

    /* Generate the key */
    if(1 != EVP_PKEY_keygen_init(kctx)) 
        printf("Error in EC key generation\n");

    if (1 != EVP_PKEY_keygen(kctx, &pkey)) 
        printf("Error in EC key generation\n");

    /* Get the peer's public key, and provide the peer with our public key -
     * how this is done will be specific to your circumstances */
    peerkey = get_peerkey(pkey);

    /* Create the context for the shared secret derivation */
    if(NULL == (ctx = EVP_PKEY_CTX_new(pkey, NULL))) 
        printf("Error in EC key generation\n");

    /* Initialise */
    if(1 != EVP_PKEY_derive_init(ctx)) 
        printf("Error in EC key generation\n");

    /* Provide the peer public key */
    if(1 != EVP_PKEY_derive_set_peer(ctx, peerkey)) 
        printf("Error in EC key generation\n");

    /* Determine buffer length for shared secret */
    if(1 != EVP_PKEY_derive(ctx, NULL, secret_len)) 
        printf("Error in EC key generation\n");

    /* Create the buffer */
    if(NULL == (secret = OPENSSL_malloc(*secret_len))) 
        printf("Error in EC key generation\n");

    /* Derive the shared secret */
    if(1 != (EVP_PKEY_derive(ctx, secret, secret_len))) 
        printf("Error in EC key generation\n");

    EVP_PKEY_CTX_free(ctx);
    EVP_PKEY_free(peerkey);
    EVP_PKEY_free(pkey);
    EVP_PKEY_CTX_free(kctx);
    EVP_PKEY_free(params);
    EVP_PKEY_CTX_free(pctx);

    /* Never use a derived secret directly. Typically it is passed
     * through some hash function to produce a key */
    return secret;
} 

我发现要使这个功能正常工作,我需要一个EVP_KEY对象与第二方的公钥。我在字节数组中有这个公钥及其长度。如何将其转换为所需的类型?而且我在 OpenSSL 中找不到 secp256r1 曲线,但我在做了一些研究后在代码中使用了该曲线。这是对的吗?

Thanks !


对等点的公钥是曲线上的一个点。从crypto\ec\ec_lcl.h:

struct ec_key_st {
    int version;

    EC_GROUP *group;

    EC_POINT *pub_key;
    BIGNUM   *priv_key;

    unsigned int enc_flag;
    point_conversion_form_t conv_form;

    int     references;
    int flags;

    EC_EXTRA_DATA *method_data;
} /* EC_KEY */;

I believe你需要打电话EC_POINT_new (c_lcl.h是私有标头,因此您无权访问该结构)。

幸运的是,有很多函数可以操纵它们。来自EC_POINT_new(3) http://www.openssl.org/docs/crypto/EC_POINT_new.html docs:

EC_POINT 可以与各种外部进行转换 交涉。支持的表示形式为八位字节字符串、BIGNUM 和十六进制。外部表示的格式为 由point_conversion_form描述。请参阅 EC_GROUP_copy(3) 了解 point_conversion_form 的描述。八位字节字符串存储在 缓冲区以及相关的缓冲区长度。一个点保存在 BIGNUM 是通过将点转换为八位字节字符串来计算的 然后将该八位字节字符串转换为 BIGNUM 整数。点在 十六进制格式存储在以 NULL 结尾的字符串中 其中每个字符是可打印值 0-9 或 A-F 之一(或 a-f)。

另请参阅EC_POINT_set_affine_coordinates_GFp, EC_POINT_set_affine_coordinates_GF2m and EC_KEY_set_public_key:

$ grep -R EC_KEY_set_public_key *
crypto/ec/ec.h:int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub);
...

您可以在 OpenSSL wiki 上查看如何设置该点的示例:椭圆曲线密码学 http://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

生成 EC Diffie-Hellman 公钥和私钥对 的相关文章

  • 如何使用带有进度条的 HttpClient 下载文件?

    我创建了一个名为SiteDownload并添加了一些下载图像的链接 using System Collections Generic using System Linq using System Net using System Threa
  • strtok() 和空字段

    我正在将一些 C 结构序列化为字符串 然后将其反序列化strtok 但不幸的是 strtok 不检测空字段 例如 1 2 4 有没有替代功能 在linux上有strsep http www mkssoftware com docs man3
  • C++ 标准是否允许未初始化的 bool 导致程序崩溃?

    我知道一个 未定义的行为 C 几乎可以让编译器做任何它想做的事情 然而 我遇到了一次令我惊讶的崩溃 因为我认为代码足够安全 在这种情况下 真正的问题仅发生在使用特定编译器的特定平台上 并且仅在启用优化的情况下发生 我尝试了几种方法来重现问题
  • OpenGL,如何独立旋转对象?

    到目前为止我的代码 void display void glClear GL COLOR BUFFER BIT GL DEPTH BUFFER BIT Clear Screen And Depth Buffer glLoadIdentity
  • 子进程中的变量修改

    我正在研究科比和奥哈拉伦的作品Computer Systems A Programmer s Perspective 练习 8 16 要求程序的输出如下 我更改了它 因为他们使用了一个你可以在他们的网站上下载的头文件 include
  • 运行 C# exe 文件

    复制 为什么我的 NET 应用程序在从网络驱动器运行时会崩溃 https stackoverflow com questions 148879 why does my net application crash when run from
  • 如何在C中将2个4位无符号数组合成1个8位数

    我有 2 个 4 位数字 X0X1X2X3 和 Y0Y1Y2Y3 我想将它们组合起来 这样我就可以创建一个像这样的 8 位数字 X0X1X2X3 Y0Y1Y2Y3 gt X0Y0X1Y1X2Y2X3Y3 我知道如何连接它们以创建X0X1X1
  • const_iterators 更快吗?

    我们的编码指南更喜欢const iterator 因为它们比正常的要快一点iterator 当您使用时 编译器似乎会优化代码const iterator 这真的正确吗 如果是的话 内部到底发生了什么使得const iterator快点 编辑
  • 有没有办法关闭 Hangfire 使用 Serilog 进行的日志记录?

    有没有办法关闭 Hangfire 使用 Serilog 进行的日志记录 我们正在使用我们自己的抽象 我不希望在使用 Serilog 时来自 Hangfire 记录器的所有额外噪音 INIT call under web project na
  • 使用 INF 文件 C++ 以编程方式安装驱动程序

    这里有人可以告诉我如何安装第 3 方设备驱动程序吗 如果提供了所有必需的文件 即 inf 文件 sys 等 则以编程方式进行 这 该解决方案应运行的最低操作系统是Windows2000 我尝试复制 inf文件放入Win文件夹 INF文件夹和
  • 具有多重继承的不明确基数

    我正在尝试在一个大库中编写一些类的子类 我收到 基础不明确 错误 这是该问题的一个可编译示例 include
  • 使用 unrar 库 - 将文件提取到文件流缓冲区中

    我需要的是能够将 rar 文件中的文件提取到流中 我正在创建一个测试用例来了解如何使用解压源文件 http www rarlab com rar unrarsrc 3 9 9 tar gz 我已经搜索和修补了一段时间 但我不知道如何使用该库
  • 如何修改 edmx 的默认代码生成策略?

    我想修改默认的代码生成策略 该怎么做 我只是想修改类名 lt code Escape container gt to Entities并将默认连接字符串更改为name Default 我不想为该项目创建模板文件 我想编辑它以便它可以在全球范
  • 通过 MVC 将数据写入数据库的最佳方法是什么?

    我正在使用 MVC 和 EF Core 开发一个家庭作业项目 我正在寻找将数据写入数据库的最佳方法 我是初学者 有两张桌子 Predbilje ba 报名 和Seminari 研讨会 public class Predbilje ba Ke
  • 我的 Opencv 应用程序处理速度非常慢

    我正在构建一个 OpenCV 应用程序 它从相机捕获视频 并在删除背景后将其覆盖在另一个视频上 我无法达到合理的速度 因为它以大约 1 fps 的速度播放输出 而我的背景去除以 3 fps 的速度工作 有没有办法以正常速度显示背景视频并以
  • Lambda 按值捕获和“mutable”关键字

    关键词的必要性mutable在 lambda 中 是造成极大混乱的根源 考虑代码 int x 10 function
  • int 类型的构造函数

    考虑到成本 这些情况是否相同 case 1 int a 5 case 2 int a 5 case 3 int a a 5 这三种语法是不同的 请耐心等待 我使用用户定义类型而不是 int 稍后我将回到 int T a 5 Direct i
  • 恐怖分子已弃用

    正在接听另一个问题 https stackoverflow com q 11830514 1468366 我偶然发现了man page http linux die net man 3 herror一个名为的函数herror 看起来很像pe
  • 使用 Powershell 或 C# 获取 Azure“文件和文件夹”作业状态

    我一直在尝试找到一种方法来获取在 AzureRM 中运行的几个客户上运行的 文件和文件夹 备份作业的状态 可以在 AzureRm 门户中手动找到状态 恢复服务保管库 gt 作业 gt 备份作业 使用powershell不显示任何作业信息 G
  • InvalidOperationException:没有为方案“CookieSettings”注册身份验证处理程序

    我正在使用 ASP Net MVC core 2 1 开发一个应用程序 其中不断出现以下异常 InvalidOperationException 没有为方案 CookieSettings 注册身份验证处理程序 注册的方案有 Identity

随机推荐