0%

周谈(31)-ECC曲线的应用

前言

ECC椭圆曲线的应用有两种:

  • ECDSA 数字签名验签, 主要是使用私钥对信息的摘要加密,然后发送刚给对端,对端使用发送方的公钥解密得到摘要信息,再计算一下信息的摘要,对比一下确认摘要是否一致。主要用于确认这个信息是发送方发送的,没有被篡改过。
  • ECDH 密钥交换,主要用于协商通信双方使用的对称密钥。

ECDH

DH密钥协商具体的流程下面如下:

1
2
3
4
5
6
7
8

A: g,p 协商生成公开的整数g,大素数p。明文形式发给B
B: B获取到g,p
A: 生成隐私数据: a (a<p),计算得出 g^a%p,发送给B
B: 生成隐私数据: b (b<p),计算得出 g^b%p,发送给A
A: 计算得出 [(g^ b%p)^a]%p = g ^ab%p,生成秘钥
B:计算得出 [(g^ a%p)^b]%p = g ^ab%p,生成秘钥

通信双方根据公开的g, p和各自私有的数各计算出一个值,然后发送给对端。再根据这个值和对端的数据,生成相同的数作为后续通信的共同的密钥。

ECDH密钥协商算法是ECC算法和DH密钥交换原理结合使用,用于密钥磋商。

ECC是建立在基于椭圆曲线的离散对数问题上的密码体制,给定椭圆曲线上的一个点P,一个整数k,求解Q=kP很容易;给定一个点P、Q,知道Q=kP,求整数k则是一个难题。

在密钥协商的阶段,通信时分别使用对端的公钥加密信息,然后双方都对接收到的信息使用自己的私钥解密,从而保证通信的安全。

ECDSA

签名就比较简单了,就是发送方使用自身的私钥签名,接收方使用发送方的公钥解密摘要,对比签名。

ECC签名生成算法的输入输出如下:

ecc_sign

最后输出是一对整数(R, S)。

验签的话,输入输出是消息,还有签名(R, S)和公钥。

ecc_ver

也是算出摘要,然后结合S计算出参数、导入参数的G点和公钥,计算出一个新的点,最终对比点的X坐标是否等于R来决定验签是否通过。

具体的计算过程可以看NIST.FIPS.186-5-draft.pdf的第6章。

内核中的应用

EDCH在内核中用的是crypto_kpp这种算法,比如secp192r1曲线的实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

// crypto/ecdh.c中 linux 5.17版本
static struct kpp_alg ecdh_nist_p192 = {
.set_secret = ecdh_set_secret,
.generate_public_key = ecdh_compute_value,
.compute_shared_secret = ecdh_compute_value,
.max_size = ecdh_max_size,
.init = ecdh_nist_p192_init_tfm,
.base = {
.cra_name = "ecdh-nist-p192",
.cra_driver_name = "ecdh-nist-p192-generic",
.cra_priority = 100,
.cra_module = THIS_MODULE,
.cra_ctxsize = sizeof(struct ecdh_ctx),
},
};

可以看到内核中实现的ecdh的设置私钥、导出公钥、密钥交换的接口。

ECDSA在内核中用的是akcipher_alg算法,比如secp384r1曲线对应的实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
static struct akcipher_alg ecdsa_nist_p384 = {
.verify = ecdsa_verify,
.set_pub_key = ecdsa_set_pub_key,
.max_size = ecdsa_max_size,
.init = ecdsa_nist_p384_init_tfm,
.exit = ecdsa_exit_tfm,
.base = {
.cra_name = "ecdsa-nist-p384",
.cra_driver_name = "ecdsa-nist-p384-generic",
.cra_priority = 100,
.cra_module = THIS_MODULE,
.cra_ctxsize = sizeof(struct ecc_ctx),
},
};

ECDSA实现了公钥设置和验签的接口。其实,akcipher_alg接口中也有签名、加解密,不过在内核中没有实现这些接口。

更多

这周写完了ECC曲线的代码,调试过程中还存在一些问题,下周重点就是解决这些个问题。
限制于硬件资源,工作进展还是很慢的,一个是多人共用资源,另外一个是环境时钟频率很低,运行缓慢。第三个就是底层支持不给力,硬件手册很多注意点没有提及,协调比较困难。第四就是驱动这玩意我也是刚开始玩,入门而已,缺乏深入。

本来打算周末的时候要呆在家中鲁一把代码的,被家里一些事情耽搁了,这两天做了专职的司机,开车开得手臂都感觉有点儿酸了。


行动,才不会被动!

欢迎关注个人公众号 微信 -> 搜索 -> fishmwei,沟通交流。

博客地址: https://fishmwei.github.io

掘金主页: https://juejin.cn/user/2084329776486919