「ecdsa算法java」ecb算法

博主:adminadmin 2022-11-26 16:35:06 83

本篇文章给大家谈谈ecdsa算法java,以及ecb算法对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

ECDSA的最简理解

y^2 = (x^3 + a * x + b) mod p

上述的曲线是在整数,一定bit数量(假设是160bit)内可以表达的,p是 160bits内可以表示的大整数。

为什么是这种曲线定义呢,我个人觉得有3个原因:

在椭圆曲线上随意取两个点 A,B,连接A,B两个点的直线与曲线的新的交点称为C,C关于X对称的-C点表示为 A+B。

乘法可以用加法表示,但是算法复杂堵是 log(n)。

其实为什么选择上述的椭圆曲线实际上是由这个加法规则选出来的,总是要求解这个新的交点更加简单。

R=k*P 的性质,已知R与P的值,无法推出k的值, 而知道k值于P值是很容易计算R值(log(n))。这是ECDSA签名算法的理论基础。

如何利用这个门限函数来做一个签名算法呢?

一个顺理成章的想法是: 给验证人一个 R和P,那只有签名人才能提供K,那K是不是可以作为一个签名指纹呢?

ok,咱先生成一个公私钥对, Qa = dA * G , Qa 就是公钥, dA 是一个随机数,就当是一个私钥吧,当然这个椭圆曲线的 a , b , p , G 值都是要公开的。这个 G 就是椭圆曲线上随机挑选的一个节点,我们叫原点,也是要公开的。

每次对一个数据做签名,都随机生成一个随机数 K 吧, P = K * G 。咱们把 P的x轴坐标R作为签名的一部分。另一部分签名数据叫 S 。

显然这个 S 既要和 dA 相关,也要和被签名的信息 z 相关。我们就假定:

S = Sig(dA, G, z, R, K) , 那这个函数就是签名函数。

而验证函数应该只有 S,R ,而不会有 K,dA

P = h(S, G, z, R) , h 就是签名函数。

密码学专家想到了一个实现:

S = k^-1 (z + dA * R) mod p

k^-1 表示的是关于p的模逆元。( k^-1 * k mod p = 1)。

可以推倒初验证函数:

== k = S^-1 (z + dA * R) mod p

== k*G = S^-1 (z + dA * R) *G

== P = S^-1*z*G + S^-1*dA*R*G

== P = S^-1*z*G + S^-1*R*Qa

对于验证者来说,需要计算: S^-1*z*G + S^-1*R*Qa 的x坐标是否就是 R 。

go的椭圆曲线 a 为固定的-3, 而 b 可以自由的选择,而p224, p256曲线的其实指的是 曲线的bit位数是224和256。

算法实现着为了更加快速地执行曲线上的加法和乘法,对笛卡尔坐标做了投射成(x,y,z)的雅各布坐标,投射关系:

可以加速在雅各布坐标系上的运算,在需要最终结果的时候再投射回笛卡尔坐标系。

一个曲线的表示:

公私钥对的表示:

可以看出曲线,公钥,私钥拥有的信息越来越全。

公钥是 曲线信息+ dA*G的信息。

私钥是 公钥信息 + dA信息。

美国国安局发布的曲线其实是 secp256k1 , 对于其参数其实没有很好的解释,大家猜测是国安局找到了这是一条弱化的椭圆曲线,因此BTC在设计之初也没有采用这个曲线,而是用了 Koblitz Curve , b 是7, a 是0,btcsuit的package中,对 KoblitzCurve 是golang的 curvparam 的一层封装(主要是为了加速),但是有更多的参数, 是因为a和b等参数都是预先设定的,增加更多的参数来加速计算。至于公私方法和golang基本一样。

Ed25519 从某种意义上来说也属于椭圆曲线密码学,不同的是它采用扭曲爱德华兹曲线作为椭圆曲线,同时采用的签名机制也不同于 ECDSA 算法。EdDSA 的重要实现 ED25519 是 Daniel J. Bernstein 等人设计的 EdDSA 算法,采用的曲线参数完全公开,并说明了参数选取的意义,保证曲线中并未内置后门。

曲线:

y^2 = (x^3 + x^2 + {一个很大的随机数}x ) mod p

他生成公私钥的流程有一些区别,seed作为私钥,seed计算出的hash值去和G相乘得到公钥,为了防止多次计算,把这部分公钥扩展到私钥的后面作为一个完整的私钥。计算签名的时候,普通ecdsa会生成一个随机数K,而ec25519为了避免伪随机数被猜测到,因此是私钥和msg的hash值作为这个随机数。

带密钥的消息摘要算法——数据签名算法

数字签名算法可以看做是一种带有密钥(公钥+私钥)的消息摘要算法,也就是说,数据签名算法是非对称加密算法和消息摘要算法的结合体。该算法包含签名和验证两项操作,遵循 “私钥签名,公钥验证” 的签名/验证方式。

1、甲方构建密钥对,并能公布公钥给乙方。

2、甲方想乙方发送数据需要附加签名。

3、乙方使用公钥和签名验证数据。

RSA数字签名算法主要可以分为:MD、SHA两类。该算法公钥通常要比私钥短。

RSA数字签名示例:

在实现层面上,可以认为DSA算法实现就是RSA算法实现的精简版。DSA算法仅支持SHA系列消息摘要算法。

DSA数字签名示例:

ECDSA算法相对于传统签名算法具有速度快、强度高、签名短等优点。微软操作系统及办公软件的序列号验证就使用了该算法。

ECDSA算法示例:

求ECDSA的Java代码

【方案1】

package ECDSA;

import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin;

import java.security.*;

import java.security.interfaces.ECPrivateKey;

import java.security.interfaces.ECPublicKey;

import java.security.spec.PKCS8EncodedKeySpec;

import java.security.spec.X509EncodedKeySpec;

public class Ecdsa {

  private static String src = "hello berber" ;

  public static void main(String []args){

      jdkECDSA();

  }

  public static void jdkECDSA(){

      // 1.初始化密钥

      try{

          KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC");

          keyPairGenerator.initialize(256);

          KeyPair keyPair = keyPairGenerator.generateKeyPair() ;

          ECPublicKey ecPublicKey = (ECPublicKey)keyPair.getPublic() ;

          ECPrivateKey ecPrivateKey = (ECPrivateKey)keyPair.getPrivate() ;

          // 执行签名

          PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(ecPrivateKey.getEncoded());

          KeyFactory keyFactory = KeyFactory.getInstance("EC") ;

          PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec) ;

          Signature signature = Signature.getInstance("SHA1withECDSA");

          signature.initSign(privateKey);

          signature.update(src.getBytes());

          byte []arr = signature.sign();

          System.out.println("jdk ecdsa sign :"+ HexBin.encode(arr));

          // 验证签名

          X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(ecPublicKey.getEncoded());

          keyFactory = KeyFactory.getInstance("EC");

          PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);

          signature = Signature.getInstance("SHA1withECDSA");

          signature.initVerify(publicKey);

          signature.update(src.getBytes());

          boolean bool = signature.verify(arr);

          System.out.println("jdk ecdsa verify:"+bool);

      }catch(Exception e){

      }

  }

}

Java数字签名——ECDSA算法

【方案2】

public class MyTest {

/**

* @param args

*/

public static void main(String[] args) {

new MyTest().getSign();

}

void getSign() {

// Get the instance of the Key Generator with "EC" algorithm

try {

KeyPairGenerator g = KeyPairGenerator.getInstance("EC");

ECGenParameterSpec kpgparams = new ECGenParameterSpec("secp256r1");

g.initialize(kpgparams);

KeyPair pair = g.generateKeyPair();

// Instance of signature class with SHA256withECDSA algorithm

Signature ecdsaSign = Signature.getInstance("SHA256withECDSA");

ecdsaSign.initSign(pair.getPrivate());

System.out.println("Private Keys is::" + pair.getPrivate());

System.out.println("Public Keys is::" + pair.getPublic());

String msg = "text ecdsa with sha256";//getSHA256(msg)

ecdsaSign.update((msg + pair.getPrivate().toString())

.getBytes("UTF-8"));

byte[] signature = ecdsaSign.sign();

System.out.println("Signature is::"

+ new BigInteger(1, signature).toString(16));

// Validation

ecdsaSign.initVerify(pair.getPublic());

ecdsaSign.update(signature);

if (ecdsaSign.verify(signature))

System.out.println("valid");

else

System.out.println("invalid!!!!");

} catch (Exception e) {

// TODO: handle exception

e.printStackTrace();

}

}}

java – 使用secp256r1曲线和SHA256算法生

怎么验证生成的Ecdsa签名是正确的呢,可以看下这篇文章:RSA,ECC,Ecdsa,国密SM2的签名,验签,加密

ECDSA(椭圆曲线数字签名算法)

ECDSA(Elliptic Curve Digital Signature Algorithm)

在现实工作和生活中,我们使用签名的方式表达对一份文件的认可,其他人可以识别出你的签名并且无法伪造你的签名。数字签名就是对显示签名的一种电子实现,它不仅可以完全达到现实签名的特点,甚至能够做的更好。

常用的数字签名算法有RSA(Rivest-Shamir-Adleman Scheme)、DSS(Digital Signature Standard)等。 比特币使用ECDSA来生成账户的公私钥以及对交易和区块进行验证。

1.Alice(密码学中常用A到Z开头的人名代替甲乙丙丁等,字母越靠后出现频率越低)生成一对密钥,一个是sk(signing key),是非公开的;另一个是vk(verification key),是公开的。

这一对密钥同时生成,并且在数学上是相互关联的,同时,根据vk无法推测出关于sk的任何信息。

2.数字签名算法接收两个输出:信息M和sk,生成一个数字签名Sm

3.验证函数接收信息M、Sm以及vk作为输入,,返回结果是yes或者no。这一步的目的是为了验证你看到的针对信息M的数字签名确实是由Alice的sk来签发的,用于确认信息与签名是否相符。

与手写签名不同,手写签名基本都是相似的,但是数字签名却受输入影响很大。对输入轻微的改变都会产生一个完全不同的数字签名。一般不会对信息直接进行数字签名,而是对信息的哈希值进行签名。由加密哈希函数的无碰撞性可知,这样和对原信息进行签名一样安全。

在数学上,任何满足以下方程的点所形成的曲线称为随机椭圆曲线: 并且 ,a和b可以为任意值。下面展示几个随机椭圆函数的示例:

在了解如何通过基于secp256k1椭圆曲线的ECDSA算法生成公私钥之前,我们需要了解在随机椭圆曲线里,点的加法是如何实现的。

首先定义椭圆曲线上点的加法。设椭圆曲线上有两点,A和B点,那么作过这两点的直线与该曲线相交于第三点(C点),然后关于X轴对称得到D点,则D为这两个点的和,记作D=A+BD=A+BD=A+B。很明显,D点也在该曲线上。所以椭圆曲线上两点之和也是曲线上的点。

特例:

1.如果两点重合,则做该点的切线,与曲线相交点的对称点为和,即A+A=C

如图:

有了加法以后,乘法实现是不过是进行多次加法运算。有了一个基准点P以后,我们可以对其进行乘法运算,最后可以得到曲线上的另外一个点。

设PPP是椭圆曲线上的一个点,那么正整数kkk乘以点PPP的结果由下面的式子定义,注意式子中的加法是上面提到的椭圆曲线上点的加法:

点的运算满足结合律:

很显然,通过累加 的方式计算 是一种很笨的办法,其时间复杂度是线性的。上面我们提到过,椭圆曲线上点的加法是满足结合律的,即 ,扩展一下,就有

于是就有这么一种骚操作,比如计算 ,我们可以先计算 ;然后计算 ;再计算 ;最后计算 。这里我们把15次加法减少到了4次。

当然,k的值不可能总是2的幂。实际上上面的操作可以推广到k为任意正整数的情况。比如计算23P,首先计算 ,然后

因为 ,所以 。总共只需要7次加法。

分析一下,对于任意正整数k,我们都可以利用这个方法将计算k∗P所需的加法计算次数降低到

也就是说,从时间复杂度的角度来看,这个算法是一个 的算法。

这个方法被称为快速幂算法,原本常用于快速计算某个数的k次幂,这里将其推广到椭圆曲线点乘的快速计算中。

为什么要在介绍了椭圆曲线上点的乘法后突然冒出一个快速幂算法?快速幂算法对于椭圆曲线加密有什么意义?因为数学家/密码学家发现,利用快速幂算法计算 的时间复杂度是对数级的,但是要在知道 和 的前提下,倒推出 的值,没有比挨个尝试 的值快太多的算法。于是椭圆曲线加密依赖的数学难题就这么诞生了。

如果我们改一种记法,把椭圆曲线上点的加法记作乘法,原来的乘法就变成了幂运算,那么上述难题的形式跟离散对数问题应该是一致的。即:

所以这个难题叫椭圆曲线上的离散对数问题。

尽管两者形式一致,但是他们并不等价。实际上这个问题比大整数质因子分解(RSA)和离散对数(DH)难题都要难得多,目前还没有出现亚指数级时间复杂度的算法(大整数质因子分解和离散对数问题都有),以致于同样的安全强度下,椭圆曲线加密的密钥比RSA和DH的短不少,这是椭圆曲线加密的一大优势。

假设随机取一个 ~ 位之间的值x,计算 ,最后的结果一定会落在曲线上的一点。假设该点为 ,在公开 以及具体曲线的方程的情况下,能否反推出最初的随机值 ?

证:寻找 的过程只能通过暴力计算, 的可能值为 ~ 中的一个,平均来说需要计算 次能够找到一次 值。那么问题来了,运行一次 的计算需要多长的时间呢?

假设我们使用的是超级计算机,主频为 (一秒钟可以进行一万亿次运算),从宇宙诞生的那一刻开始计算,到现在也就进行了 次。找到 值的概率为 。这个概率和下一秒地球被巨型陨石撞击而毁灭的概率接近,既然我们读到了这里,那么说明这件事没有发生。

在上面的案例中, 是 ~ 位的一个随机数,可以作为私钥。 是随机椭圆曲线上的一个点,也就是由私钥生成的公钥,因此优点可以1得证。

但是密码学中,并不能使用上面介绍的实数域上的椭圆曲线。因为

所以我们需要引入有限域上的椭圆曲线。

要证明优点2,还需要将随机椭圆曲线做一些改动:为了保证最后计算出来的点的坐标值相加是512位,secp256k1引入了一个对质数取模的机制。具体来说,随机椭圆曲线从

变为了 其中 ,是小于 的最大质数。

此时的随机椭圆曲线函数图如下:

具体来说,就是向别人证明我知道 ,但不暴露 的任何信息。(有些类似于零知识证明)

证:前面介绍过结合律: 添加一个hash函数,简单修改可以得出: 使 ,那么可知 为 。此时方程为: 为了简单起见,我们记 和 。此时方程化简为: 上面这个方程是什么意思呢?

可以这样假设:在已知 的情况下,如果能够提供一个 和 满足上面的方程,就可以证明一个人拥有 。这个假设有一个前提,如果一个人不知道x,那么他就无法提供 和 满足上面的等式。

详细探讨这个前提:如果一个人不知道x,又想计算出 和 ,能够办到吗?结论是不能,首先我们无法从 计算出 (在有限时间内)。

还有一个问题:在已知 和 的情况下,能否计算出关于 的任何信息?

根据公式: 只要解出 就可以了。

要想计算出x,就需要知道r,但是在r没有公开的情况下,有什么办法可以计算r吗?我们知道R=r*P;但是根据这个公式无法倒推出r(刚才介绍的那个数学难题),所以x也是安全的。

至此,可以证明算法的第二个优点。

关于ecdsa算法java和ecb算法的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。

The End

发布于:2022-11-26,除非注明,否则均为首码项目网原创文章,转载请注明出处。