Hi all,这里是整个椭圆曲线系列的第三部分。原文链接如下:Elliptic Curve Cryptography: ECDH and ECDSA​andrea.corbellini.name

想全面了解椭圆曲线的朋友可以先看看前两个部分,翻译得很棒:Avery:ECC椭圆曲线加密算法:介绍​zhuanlan.zhihu.comAvery:ECC椭圆曲线加密算法:有限域和离散对数​zhuanlan.zhihu.com

在之前的文章中,我们已经认识了什么是椭圆曲线,并且为了更好得使用数学方法来处理椭圆曲线上的点,我们定义了「群」,接着我们又进一步将椭圆曲线限制在了整数取模素数的有限域上,椭圆曲线上的点在有限域上形成了循环子群,并且我们也介绍了「基点」、「阶」和「辅因子」的概念。

最后,我们知道在有限域上计算标量积是一个容易的过程,但是离散对数问题却是非常难的,现在我们就来看看这些理论是如何应用在密码学上的。

主要参数

椭圆曲线算法将会运用在有限域上的椭圆曲线所形成的循环子群上,因此,我们的算法需要以下几个参数:素数 p,用于确定有限域的范围

椭圆曲线方程中的a,b 参数

用于生成子群的的基点G

子群的阶 n

子群的辅助因子h

所以,我们算法的主要参数可以定义为一个六元组 (p, a, b, G, n, h)

随机曲线

「离散对数问题很困难」这种说法其实不完全正确,有一类椭圆曲线特别的弱以至于一些不怀好意的算法可以有效率的求解离散对数问题。例如,具有 p = hn(这意味着有限域的阶等于椭圆曲线的阶) 性质的所有曲线对于 smart 攻击是脆弱的,这就可以被用来在经典计算机上,多项式时间内解决离散对数问题。

现在,假设我给你一个曲线的主要参数,有可能我发现了一种新的没人知道的弱曲线,而且我已经在我给你的曲线上构建了一个快速算法,可以用来求解离散对数问题,我怎么样能让你确认我给你的曲线是安全的(换句话说,它不能被我用来做一些特殊攻击)?

为了解决这个问题,有时候我们需要另一个参数:种子 S,这是一个用来生成参数 a, b 或者基点 G,或者三个参数都生成的随机数,这些参数是通过计算种子 S 的哈希值得到的。哈希值,我们知道的,是正向计算容易,反向计算困难的。种子是怎样生成一个随机曲线的:随机数的哈希值被用于计算曲线的不同参数如果想要通过主要参数推导出种子 S 的值,就需要解决一个困难问题:逆向哈希

通过种子生成的曲线是可验证随机性的,使用哈希来生成参数的原则是众所周知的「Nothing-up-my-sleeve number」,这个原则也被运用在密码学中。

种子 S 可以提供一种保证,使提供曲线的人不会知道一些特殊的攻击漏洞。如果我将种子 S 和曲线一起提供给你,这就意味着我不会任意地选择参数 a 和 b,你也就可以相对确认我不能够发起一些特数目的的攻击,为什么是「相对」的呢,这个稍后解释。

生成和检查随机曲线的标准算法在 ANSI X9.62 中有描述,这是一个基于 SHA-1 的算法。如果你感兴趣,可以了解用于在 SECG 规范上生成可验证随机曲线的算法(找到 "Verifiably Random Curves and Base Point Generators")

我写了一个 python 脚本来验证当前所有随 OpenSSL 提供的随机曲线,强烈建议大家看看!

椭圆曲线密码学

花了好长的时间终于到了关键部分,我们简单来描述:私钥是一个范围在

中的随机整数 d,其中 n 是子群的阶

公钥是点 H,H = dG,其中 G 是子群的基点

你看,如果我们知道了 d 和 G(还有主要参数中的其他参数),求得 H 是很容易的。但是如果我们知道 H 和 G,想要求得私钥 d 很困难,因为这要求我们解决离散对数问题。

接下来我们讨论两种基于椭圆曲线密码学的两种公钥算法:用于加密的 ECDH(Elliptic curve Diffie-Hellman)和用于数字签名的 ECDSA(Elliptic curve Diffie-Hellman)

ECDH

ECDH 是椭圆曲线的笛福赫尔曼算法的变种,它其实不单单是一种加密算法,而是一种密钥协商协议,也就是说 ECDH 定义了(在某种程度上)密钥怎么样在通信双方之间生成和交换,至于使用这些密钥怎么样来进行加密完全取决通信双方。

我们需要解决的问题通常是这样的:Alice 和 Bob 想要安全通信,中间人可能会窃听消息,但是没办法解密消息

那么 ECDH 是这样的:Alice 和 Bob 生成各自的私钥和公钥,Alice 的私钥为

,公钥为

。Bob 的私钥为

,公钥为

,注意,Alice 和 Bob 需要使用一样的主要参数:在同一条曲线的同一个有限域上选择一样的基点 G。

Alice 和 Bob 通过不安全信道交换各自的公钥

,中间人可以窃听到

,但是在无法攻破离散对数难题的情况下无法得到

Alice 计算

(使用自身的私钥和 Bob 的公钥),Bob 计算

(使用自身的私钥和 Alice 的公钥),双方求得的 S 是一样的,因为

中间人只知道

以及椭圆的公共参数,是无法算出共享密钥 S的,这其实就是笛福赫尔曼问题:给定三个点 P,aP,bP,那么 abP 的结果是什么?

或者我们可以这么理解:给定三个整数

,那么

的结果是什么?

(这种形式被用在了最原始的基于模运算的笛福赫尔曼算法上)笛福赫尔曼密钥交换:Alice 和 Bob 可以很容易的计算出共享密钥,中间人就必须解决数学困难问题才能求解

笛福赫尔曼原理的介绍可以看这个视频,视频里解释了基于模运算的笛福赫尔曼算法(不是椭圆曲线)。

虽然没有数学证明直接说明椭圆曲线上的笛福赫尔曼问题是困难的,但是这个问题已经被公认为是个困难问题,因为人们相信这个问题的困难性是基于离散对数问题的困难性。但是可以肯定的是,这个问题的难度就到此为止不会更难了,因为只要解决了离散对数问题,笛福赫尔曼问题也就解决了。

现在 Alice 和 Bob 已经获得共享密钥,他们可以使用对称加密算法进行通信了。

举个栗子,他们可以使用 S 的 x 轴坐标作为 AES 或者 3DES 的密钥来加密信息,这多少有点像是 TLS 的操作,不同点是 TLS 将 x 轴坐标和网络连接相关的其他参数串联起来,然后计算这个串的哈希值。

实践 ECDH

我写了另一个 python 脚本来生成基于椭圆曲线的公私钥和共享密钥。

不同于我们之前看到的例子,这个脚本用的是标准化的椭圆曲线,而不是在一个小的域内的简单曲线。我选择的曲线是 secp256k1,由 SECG 发表,这是比特币用来做数字签名的曲线,下面是曲线的主要参数: = 0xffffffff ffffffff ffffffff ffffffff ffffffff ffffffff fffffffe fffffc2f

= 0

= 7

= 0x79be667e f9dcbbac 55a06295 ce870b07 029bfcdb 2dce28d9 59f2815b 16f81798

= 0x483ada77 26a3c465 5da4fbfc 0e1108a8 fd17b448 a6855419 9c47d08f fb10d4b8

= 0xffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141

= 1

你也可以使用其他的曲线和主要参数,但需要保证素数域和曲线的正确性,否则脚本将不能运行

这个脚本特别简单,它包含了一些到目前位置我们讨论到的算法:点加、点乘、ECDH,建议大家看看然后跑一跑脚本,它将产生类似这样的一个输出:Curve: secp256k1

Alice's private key: 0xe32868331fa8ef0138de0de85478346aec5e3912b6029ae71691c384237a3eeb

Alice's public key: (0x86b1aa5120f079594348c67647679e7ac4c365b2c01330db782b0ba611c1d677, 0x5f4376a23eed633657a90f385ba21068ed7e29859a7fab09e953cc5b3e89beba)

Bob's private key: 0xcef147652aa90162e1fff9cf07f2605ea05529ca215a04350a98ecc24aa34342 Bob's

public key: (0x4034127647bb7fdab7f1526c7d10be8b28174e2bba35b06ffd8a26fc2c20134a, 0x9e773199edc1ea792b150270ea3317689286c9fe239dd5b9c5cfd9e81b4b632)

Shared secret: (0x3e2ffbc3aa8a2836c1689e55cd169ba638b58a3a18803fcf7de153525b28c3cd, 0x43ca148c92af58ebdb525542488a4fe6397809200fe8c61b41a105449507083)

ECDHE

你可能听过 ECDHE 而没听过 ECDH,ECHDE 中的 E 代表着「短暂的」,是指交换的密钥是暂时的动态的,而不是固定的静态的。

举个栗子,在 TLS 中就使用了 ECDHE,连接建立时,服务器和客户端都动态生成公私钥,这些密钥在之后会用于 TLS 认证和通信双方之间的信息交换。

使用 ECDSA 签名

假设这样一个场景:Alice 想要使用她的私钥

来签名,Bob 想用 Alice 的公钥

要验证签名,只有 Alice 才能提供正确的签名,而每个人都可以验证签名。

ECDSA 是 DSA 作用于椭圆曲线的一个变种算法。Alice 和 Bob 仍然使用同样的曲线,ECDSA 需要使用明文的哈希结果,而不是明文本身。哈希函数的选择取决于使用者,但是需要明确的是必须选择加密安全的哈希函数,为了使哈希结果的比特长度和 n (子群的阶)的比特长度一致,消息的哈希结果需要被截断,被截断后的哈希值会是一个整数,我们用

来表示。

Alice 使用算法来签名的步骤如下:在

范围内选取一个随机数

(

是子群的阶)

计算点

(

是子群的基点)

计算数字

(

轴坐标)

如果

,另选一个

并重新计算

计算

(

是 Alice 的私钥,

的乘法逆元)

如果

,另选一个

并重新计算

就是签名。Alice 用自己的私钥和随机数 k 签名了哈希值 z。Bob 用 Alice 的公钥来验证签名的正确性

通俗的说,这个算法一开始生成了 k,得益于点乘(这是一个数学困难问题)k 被隐藏在了 r 中,然后通过等式

将 r 绑定到了消息散列值上。

为了计算 s,我们必须计算 k 的逆 mod n,在之前的文章中说过只有在 n 是素数的情况下才能保证这一过程,如果子群的阶不是一个素数,ECDSA 将不起作用。几乎所有标准的曲线都是素数阶的,这肯定不是巧合,非素数阶的那些曲线是不能被 ECDSA 使用的。

验证签名

为了验证签名,我们需要 Alice 的公钥

,被截断的哈希值 z,还有签名

计算整数

计算整数

计算点

只有当

的时候,签名才被成功验证

算法的正确性

算法的逻辑一开始看不是很容易理解,如果我们把前面用到的公式整合联立一下,就变得清晰了

我们从

开始,通过公钥的定义我们知道

(

是私钥),所以我们得到:

使用

的定义,可以得到:

这里为了简单先忽略

,因为由

生成的循环子群的阶为

,所以这里的

其实也是没必要的。

再往前,我们定义了

,式子两边同乘以

再同除

,也就是:

,把这个结果带到上面关于 P 的等式中得到:

这不就是我们在签名时候的第二个步骤得到的等式吗!在生成签名和验证签名的时候,我们使用了不同的等式计算了同样的点 P,这就是这个算法能够使用的原因。

实践 ECDSA

我仍然写了个生成和验证签名的python 脚本,这个脚本中的代码和之前 ECDH 中的代码有一部分相同,特别是主要参数和公私钥对生成算法。

脚本产生类似这样的一个输出:Curve: secp256k1

Private key: 0x9f4c9eb899bd86e0e83ecca659602a15b2edb648e2ae4ee4a256b17bb29a1a1e

Public key: (0xabd9791437093d377ca25ea974ddc099eafa3d97c7250d2ea32af6a1556f92a, 0x3fe60f6150b6d87ae8d64b78199b13f26977407c801f233288c97ddc4acca326)

Message: b'Hello!'

Signature: (0xddcb8b5abfe46902f2ac54ab9cd5cf205e359c03fdf66ead1130826f79d45478, 0x551a5b2cd8465db43254df998ba577cb28e1ee73c5530430395e4fba96610151)

Verification: signature matches

Message: b'Hi there!'

Verification: invalid signature

Message: b'Hello!'

Public key: (0xc40572bb38dec72b82b3efb1efc8552588b8774149a32e546fb703021cf3b78a, 0x8c6e5c5a9c1ea4cad778072fe955ed1c6a2a92f516f02cab57e0ba7d0765f8bb)

Verification: invalid signature

脚本首先签名了一段消息(字节串 “Hello”),接着验证签名。然后,脚本接着尝试基于其他消息(”Hi there!”)去验证同样的签名,然后验证失败了。再接着,脚本尝试用正确的消息去验证签名,但是验证的过程使用了另一个随机的公钥,然后验证失败了。

k 的重要性

在生成 ECDSA 签名的过程中,保证 k 的绝对私密非常重要。如果所有的签名都使用一样的 k,或者使用的随机数生成器不够随机(可预测),那么攻击者就能够找出私钥!

索尼在几年前就犯过这样的错误,正常来说, PlayStation 3 只能运行被索尼的 ECDSA 算法签名过的游戏,如果我想创建一个 PS3 的新游戏,我并不能在没有索尼签名的情况下向市场推广我的游戏。问题来了,索尼在 PS3 中的所有签名都是用固定的 k 生成的。很明显,索尼的随机数生成器的灵感来自于 XKCD 或 Dilbert我还是把这两张可爱的图贴上来了

在这种情况下,我们就可以很容易反推出索尼的私钥

,只需要买两个游戏,取出它们的哈希值

、签名(

),当然还有椭圆曲线的公共参数,接着:注意

(因为

,而

,因为

相等,所以

也相等)

想想看

(这个结果直接来自于

的等式)

等式两边同乘

得到

最后得到的这个等式使我们仅仅需要两个哈希和对应的签名,我们就可以得到 k,现在我们可以通过 s 的等式得到私钥了:

类似的方法在 k 可预测的情况下也是能够使用的。

周末愉快

椭圆曲线系列的最后一篇文章,会介绍一些涉及离散对数算法的技术、椭圆曲线密码学现存的问题以及其与 RSA 的比较。

(ps. 如果翻译得不够准确,欢迎指出和探讨;如果读下来能有些收获,告诉我!我会很高兴的!)

python椭圆曲线加密信息_ECC椭圆曲线加密算法:ECDH 和 ECDSA相关推荐

  1. python椭圆曲线加密算法_ECC椭圆曲线加密学习笔记

    0x00 前言 之前做题的时候遇到一个ECC相关的题目,学习了好几篇大佬的文章ECC的剖析文章,学习之后也记录一下,写一遍加强自己的巩固. 此文章严格意义上来讲应该算是读书笔记,在总结过程中观摩了很多 ...

  2. python椭圆曲线加密算法_ECC 椭圆曲线加密算法学习————安全性问题与实战...

    0x00 前言 之前学习了ECDSA 和 ECDH 算法.不难发现椭圆曲线的离散对数难题对该密码的安全性有着多么重要的作用.之前谈及,椭圆曲线的离散对数难题非常难,尽管如此,也应该有些方法可以解开这个 ...

  3. python椭圆曲线加密算法_椭圆曲线加密中的加法乘法浅析

    本文不深入椭圆曲线加密算法的全部知识,只针对椭圆曲线加密中需要用到的加法和乘法计算规则进行浅析. 实际练习中碰到一个比较简单密码学的问题,但是涉及到了椭圆曲线加密算法,题目描述如下: 已知椭圆曲线加密 ...

  4. 拓展 欧几里得算法 求逆元_ECC椭圆曲线加密算法:有限域和离散对数

    Hi all,我来翻译第二篇啦.若大家发现那些翻译的不够准确还望指出,不胜感激.首先放上原文链接: http://andrea.corbellini.name/2015/05/23/elliptic- ...

  5. ecc椭圆加密算法c语言,ECC 椭圆曲线加密算法学习————ECDH与ECDSA

    0x00 前言 之前学习了实数域上的椭圆曲线与有限域$\mathbb {F}_{p}$上的椭圆曲线.详细可以参考ECC椭圆加密算法学习----从实数域到有限域的椭圆曲线. 不难发现,在实数域的标量乘法 ...

  6. 椭圆曲线加密——椭圆曲线的动态展示python代码分享

    学校信息安全课老师让我来讲一下椭圆曲线加密,当看到椭圆曲线公式的时候,就想研究一下改变a或者b会对椭圆曲线的形状带来哪些影响,于是自己搜集一些资料绘制出了随a, b变化的椭圆曲线.a,b使用进度条来改 ...

  7. python 椭圆曲线加密_椭圆曲线加解密算法Python3完整实现

    信息安全课程的实验,根据课件及网上资料,参考实现 代码中注释比较完善,算法的实现整体流程如下: - 实现基本流程:考虑K=kG ,其中K.G为椭圆曲线Ep(a,b)上的点,n为G的阶(nG=O∞ ), ...

  8. 3椭圆曲线密码学:ECDH和ECDSA

    原文链接:Elliptic Curve Cryptography: ECDH and ECDSA 这篇文章是ECC系列的第三篇. 在之前的文章中,我们已经知道了椭圆曲线是什么,并且为了对椭圆曲线上的点 ...

  9. 椭圆曲线介绍(三):椭圆曲线密码学,ECDH和ECDSA

    内容来自ANDREA CORBELLINI的椭圆曲线密码学的介绍:Elliptic Curve Cryptography: a gentle introduction 本文是椭圆曲线介绍中的第三篇:E ...

  10. 椭圆曲线加密与NSA后门考古

    本文主要介绍椭圆曲线的基本原理以及基于椭圆曲线的密码学实现,包括ECC加密.ECDH秘钥交换以及ECDSA签名算法,并介绍其中潜在的一些安全问题.其中分析了两个ECC实现相关的真实案例,分别是索尼PS ...

最新文章

  1. 全了!从Python入门到精通
  2. 如何使用ember下拉框组件??
  3. [转载]INF文件格式说明
  4. yelee主题安装gitalk(转载+整理)
  5. 数据库:推荐几款 Redis 可视化工具,你都用过吗?
  6. 照片打印预览正常打印空白_小米发布口袋照片打印机,可无墨打印3寸背胶照片...
  7. linux下搭建nagios监控
  8. 从“谈芯”走向“用芯” RISC-V 未来前景光明?
  9. user_agent
  10. 无线通信-信道模型概念
  11. 指数分布java_终于搞清楚正态分布、指数分布到底是啥了!
  12. linux内核模块的依赖性、查看、加载与删除
  13. c语言字符串输出大写字母个数,欧洲区预选赛视频直播 -官方网站
  14. Java如何设置word中某段文字的字体/段落样式
  15. 【宏基因组学】微生物宏基因组学论文摘要集锦
  16. opencv颜色识别思路
  17. N4BiasFieldCorrection
  18. [Latex] 插入图片 | 插入表格 | 符号、文本粗体 | 单栏、双栏添加行号 | 添加空格 | 注释快捷键 | 维度 | 脚注 | 公式 | 分点 |
  19. 火狐浏览器httpRequest插件
  20. BIG5到GB的转换技术

热门文章

  1. mybatis mysql begin end_sql中的begin....end
  2. 在信息流上,百度或许可以给谷歌信息流支个招
  3. 二元分类(Binary Classfication)与logistic回归
  4. 软件测试及标准(基于ISO/IEC/IEEE 29119系列)
  5. python刷leetcode_GitHub - eppoha/leetcode-python: 利用python分类刷leetcode题目
  6. 语法俱乐部1:基本句型及补语
  7. 论文翻译:2021_语音增强模型压缩_Performance optimizations on deep noise suppression models...
  8. html支付系统时间,中国人民银行支付系统介绍
  9. 最小二乘法概念和代码示例
  10. 苹果微信分身版ios_苹果ios微信分身多开双开助手免费版