java调用ecdh_椭圆曲线ECC ECDH原理 javacard实现

椭圆曲线原理:

椭圆曲线的图像并不是椭圆形,椭圆曲线源自于求椭圆弧长的椭圆积分的反函数。

定义:

椭圆曲线可用下列方程来表示,其中a,b,c,d为系数。

E: y2 =ax3 + bx2 +cx +d

椭圆曲线运算:(相当于交换群)

A+B:

过曲线上两点A,B画一条直线,找到直线与椭圆曲线的的交点,将该交点关于x轴对称位置的点定义为A+B。

A+A:

画出曲线在A点的切线,找到该切线与椭圆曲线的交点,将该交点关于x轴对称位置的点定义为A+A,即2A。

-A:

A点关于X轴对称位置的点定义为-A。

那A+(-A)怎样定义?

认为A和-A间的这条直线在无穷远处相交,这个点图像上画不出来,记为O。

基于上边的运算,如果有椭圆曲线上一个点G,可以求2G,3G,。。。点的坐标。就是说给定G,求xG并不困难。但反过来很难!(椭圆曲线上的离散对数问题)

椭圆曲线上的离散对数问题

本质上就是“已知点xG求数x的问题”。

密码学中的椭圆曲线

密码学中的椭圆曲线运算不是在光滑曲线上进行,并不能使用上面的实数域上的椭圆曲线,因为

1. 实数域上的椭圆曲线是连续的,有无限个点,密码学要求有限点。

2. 实数域上的椭圆曲线的运算有误差,不精确。密码学要求精确。

所以我们需要引入有限域上的椭圆曲线。就是说不是在实数域R上,而是在有限域Fp上。

(x,y坐标的取值只能在有限域Fp中取)

Fp中只有p(p为素数)个元素0,1,2 …… p-2,p-1;

Fp 的加法(a+b)法则是 a+b≡c (mod p);即,(a+c)÷p的余数 和c÷p的余数相同。

比特币中ECDSA使用的椭圆曲线参数:secp256k1

有限域Fp定义:

p = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F

= 2256 - 232 - 29 - 28 - 27 - 26 - 24 - 1

Fp上的曲线E:y2 = x3 + ax + b定义如下:

a = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

b = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000007

压缩形式(1字节压缩标志位+32字节x坐标)的基点G是:

G = 02 79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798

未压缩形式(1字节压缩标志位+32字节x坐标+32字节y坐标):

G = 04 79BE667E F9DCBBAC 55A06295 CE870B07 029BFCDB 2DCE28D9 59F2815B 16F81798 483ADA77 26A3C465 5DA4FBFC 0E1108A8 FD17B448 A6855419 9C47D08F FB10D4B8

参数n,它是使得 nG=0 的最小正整数:

n = FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141

参数h,它是椭圆曲线群的阶跟由G生成的子群的阶的比值。是设计secp256k1时使用的参数,在具体实现中使用这个参数主要是出于安全性考虑,忽略它不影响理解。

h = 01

79d79741b92d0b8dcbd5a62708928722.png

私钥公钥地生成过程:

用户随机生成一个小于 n 的大整数 k ,这就是私钥。

然后计算 Q=kG ,这就是公钥(注意,公钥是椭圆曲线上的一个点)。

ECDH过程:

假设公私钥是用于密钥交换,那么步骤如下(这里的乘法是指椭圆曲线上点的乘法):

part1:

小红生成私钥kA,将它乘以基点G得到公钥QA,即 kA *G=QA

小明生成私钥kB,将它乘以基点G得到公钥QB,即 kB *G=QB

part2:

小红计算 ( xk, yk ) = kA *QB, xk即为交换得到的密钥。

小明计算 ( xk, yk ) = kB *QA, xk即为交换得到的密钥。

最后,小红跟小明得到的密钥是相同的。

由以上过程,ECDH的part2部分最终交换得到的密钥是只用到曲线上的点32字节的x坐标值,是没用到y坐标的。

而part1部分,这个公钥QA则必须是全的xy坐标都有。

注:ledger源码中由32字节ECC私钥生成65字节(1+32x+32y)ECC公钥的过程实际只用到了part1,只要得到Q的x和y坐标。

javacard中的ECDH

javacard.security.KeyAgreement

KeyAgreement类是密钥协商算法的基类,例如Diffie-Hellman和EC Diffie-Hellman [IEEE P1363]。 KeyAgreement算法的实现必须扩展此类并实现所有抽象方法。撕裂或卡重置事件将初始化的KeyAgreement对象重置为先前通过调用init()初始化时所处的状态。

在用这个类实现ECDH时,

首先,

private KeyAgreement keyAgreement;

keyAgreement=KeyAgreement.getInstance(KeyAgreement.ALG_EC_SVDP_DH_PLAIN_XY,false);

getInstance

功能是创建所选算法的KeyAgreement对象实例。

public static final KeyAgreement getInstance(byte algorithm,

boolean externalAccess)

throws CryptoException

algorithm - 所需的密钥协商算法:例如:ALG_EC_SVDP_DH_PLAIN_XY

35ef2aee2c3aef1ca4da334a98261c5b.png

externalAccess - 如果为true,则表示实例将在多个applet实例之间共享,并且当KeyAgreement实例的所有者不是当前选定的applet时,也将访问KeyAgreement实例(通过Shareable接口)。如果为true,则实现不得为内部数据分配CLEAR_ON_DESELECT瞬态空间。

然后,

keyAgreement.init(privateKey)

privateKey存了对应于小红的私钥kA

注意:

这个privateKey一定要在之前设定好secp256k1对应的参数(ledger源码中定义了Secp256k1类,只需调用Secp256k1.setCommonCurveParameters(privateKey)设置参数),

并且也放入了私钥值kA(调用setS()来存)

init()

功能是使用给定的私钥初始化对象。

检查密钥与KeyAgreement算法的一致性。例如,密钥类型必须匹配。对于椭圆曲线算法,key必须表示曲线域参数上的有效点。其他关键组件/域参数强度检查是特定于实现的。

接着,就是流程中小红生成QA(QA结果存放在publicPoint中),

keyAgreement.generateSecret(Secp256k1.SECP256K1_G, (short)0,

(short)Secp256k1.SECP256K1_G.length, publicPoint, publicPointOffset);

generateSecret

函数generateSecret就是实现密钥交换中的这两部分的曲线上乘法,例如kA*G=QA

输出的结果根据所选择的算法不同是不同的,具体的:

带有_PLAIN:输出结果就是原始的,与之对应不带有PLAIN的则是输出将原始结果通过SHA-1散列后得到的20字节的结果。

带有_XY:输出结果是未压缩完整的结果QA(65字节),与之对应的不带有_XY的则是压缩形式的结果(只有QA的x坐标,即32字节)

带有_DHC:和带有_DH的输出是一样的,只是DHC是 with cofactor multiplication and compatibility mode

注:综上,ledger中源码应选择同时带有_PLAIN和_XY的算法,即 ALG_EC_SVDP_DH_PLAIN_XY

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/338343.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C 常用新特性(上)

下面是正文:auto类型推导auto可以让编译器在编译器就推导出变量的类型,看代码:利用auto可以通过右边的类型推导出变量的类型。什么时候使用auto呢?简单类型其实没必要使用auto,然而某些复杂类型就有必要使用auto&#…

等级保护测评工作重点难点_重点保护

等级保护测评工作重点难点在“ Java的一些句子 ”一文中,我写道: “受保护的方法和字段可以在同一包中的类中使用(到目前为止与私有包相同),此外,还可以从其他类中使用受保护的方法和字段,这些类…

c编译程序是什么?

c编译程序是由计算机厂家提供的一套软件。c编译程序又称c语言编译器,是指用c语言书写的源程序,翻译成等价的机器语言格式目标程序的翻译程序。编译程序属于采用生成性实现途径实现的翻译程序。它以高级程序设计语言书写的源程序作为输入,而以…

运动基元_基元需要走吗?

运动基元我目前正在使用JSF作为视图技术,使用JPA作为持久层的企业应用程序。 它可能是支持bean或服务方法中的某种东西,但令我震惊:是否有充分的理由在企业应用程序中使用原语? 当我开始围绕J2SE 1.2(或者是J2SE 5.0&…

mysql 三种工作模式_mybatis三种批量插入方式对比【面试+工作】

准备:1.表结构CREATE TABLE t_user (id varchar(32) CHARACTER SET utf8 NOT NULL COMMENT 主键,name varchar(50) CHARACTER SET utf8 DEFAULT NULL COMMENT 用户名,del_flag char(1) CHARACTER SET utf8 DEFAULT NULL COMMENT 删除标示,PRIMARY KEY (id)) ENGINEI…

C 常用新特性(下)

多线程什么是多线程这里就不过多介绍,新特性关于多线程最主要的就是std::thread的使用,它的使用也很简单,看代码:这里记住,std::thread在其对象生命周期结束时必须要调用join()或者detach(),否则程序会term…

ant 路径_在Ant中显示路径

ant 路径在博客文章Java and Ant Properties Refresher和Ant <echoproperties /> Task中 &#xff0c;我写了一篇关于如何了解Ant构建如何看到属性的文章&#xff0c;这有助于更好地理解该构建。 通常情况下&#xff0c;在构建过程中看到构建中使用的各种路径也很有价值&…

java8默认垃圾回收器,Java 8的默认垃圾收集器

What is the default garbage collector for Java 8?When I check the JMX Beans, they reveal it to be the parallel collector for the new generation and the old serial collector for the old generation.解决方案Selecting the default garbage collector (among othe…

c语言中结束本次循环的语句是什么

c语言中结束本次循环的语句是“continue”。控制语句continue只能作用于循环体中&#xff0c;其作用是结束本次循环&#xff0c;跳到判断循环的位置&#xff0c;即重新开始下一次循环。在C语言中&#xff0c;控制语句“continue”用于循环体中结束本次循环&#xff0c;重新开始…

jdk8 字符串_在JDK 8中连接字符串

jdk8 字符串JDK 8引入了语言功能&#xff0c;例如lambda表达式 &#xff0c; 流 &#xff0c;甚至是新的Date / Time API &#xff0c;这些都会改变我们编写Java应用程序的方式。 但是&#xff0c;还有一些新的API和功能可能不太“改变游戏规则”&#xff0c;但仍为Java编程语言…

C语言中要改变循环语句的流程可以使用的语句有哪些

C语言中要改变循环语句的流程可以使用的语句有&#xff1a;break&#xff0c;continue和goto。break语句可以终止循环而执行整个循环语句后面的代码&#xff1b;continue语句可以跳过循环体中剩余的语句而强制进入下一次循环。break关键字当 break 关键字用于 while、for 循环时…

apk图标存放位置_安卓系统下安装完apk程序后,具体的文件夹位置在哪里呢?

展开全部 有的程序的文件夹是自动建立在sd卡上的,有的程序是没有文件夹的,程序位于32313133353236313431303231363533e59b9ee7ad9431333365666238date/app文件夹内,而系统的程序位于system/app文件夹内。 软件安装完成后,就会在date/app目录出现一个apk文件。 这个文件相当…

java 线程什么时候出栈_在Java中给出的时间

java 线程什么时候出栈tl; dr&#xff0c;您可以使用标签来阐明给定的测试时间样式。 什么时候给出&#xff1f; 给定的时间&#xff0c;然后是指定系统行为的一种常用样式&#xff0c;其中您的测试分为三个部分。 给定的部分列出了测试的先决条件&#xff0c;即在您开始之前…

java 2_Java(二)

二维数组是由一维数组组成的数组选择排序原理将数组中每一个元素与第一个元素相比较&#xff0c;如果这个元素小于第一个元素&#xff0c;则交换这两个元素循环第一条规则&#xff0c;找出最小元素&#xff0c;放于第一个位置经过n-1轮比较完成排序冒泡排序原理逐一比较数组中相…

continue语句只用于循环语句中,它的作用是什么?

continue语句只用于循环语句中&#xff0c;它的作用是&#xff1a;跳过循环体中剩余的语句而强制进入下一次循环。continue语句只用在while、for循环中&#xff0c;常与if条件语句一起使用&#xff0c;判断条件是否成立。continue语句只用在while、for循环中&#xff0c;它的作…

成为java高手_我如何想成为Java

成为java高手我喜欢Java。 我喜欢用Java编程。 但是在使用Python一段时间后&#xff0c;我希望对其进行一些更改。 它几乎纯粹是语法上的&#xff0c;因此可能有更好的JVM语言&#xff0c;但是我并不真正感兴趣&#xff0c;因为我仍然需要使用普通的Java来工作。 我意识到这些更…

在c语言中引用数组元素时,其数组下标的数据类型允许是什么

在c语言中引用数组元素时&#xff0c;其数组下标的数据类型允许是&#xff1a;整型常量或整型表达式。C语言规定只能逐个引用数组元素而不能一次引用整个数组&#xff0c;数据元素的表示形式为“数组名[下标]”&#xff0c;下标可以是整型常量或整型表达式。数组中只有一维数组…

在c语言中char型数据在内存中的储存形式为什么

在c语言中char型数据在内存中的储存形式为“ASCII码”。在C语言中&#xff0c;将一个字符常量放到一个字符变量中&#xff0c;实际并不是把该字符本身放到内存单元中&#xff0c;而是将与该字符相对应的ASCII码放到存储单元中。c语言 char型字符型数据类型就是字符1、字符数据的…

集合相减算法java_集算器协助java处理结构化文本的集合运算

有两个小文件&#xff1a;f1.txt和f2.txt&#xff0c;第一行是列名&#xff0c;现在需要对文件中的Name字段进行交集运算。部分数据如下&#xff1a;文件f1.txt:文件f2.txt:集算器代码&#xff1a;A1、B1&#xff1a;用import函数将文件读[A1.(Name),B1.(Name)].isect()入内存&…

netbeans插件_如何编写NetBeans插件

netbeans插件是否想在NetBeans IDE中添加功能或自动执行某些操作&#xff1f; 跟随我们编写您的第一个NetBeans插件。 让我们超越简单的工具栏示例 &#xff0c;创建一个可以自动更新的插件。 该代码基于NetBeans的WakaTime插件 。 我们的示例插件将仅打印Hello World语句&…