几种著名的椭圆曲线的方程和对应的实际应用

  1. 魏尔斯特拉斯曲线和基于魏尔斯特拉斯曲线的若干种椭圆曲线公钥算法
    y 2 = x 3 + a x + b y^2 = x^3 + ax +b y2=x3+ax+b
    利用上面的圆锥曲线构造密钥算法。
  2. 蒙哥马利曲线和基于蒙哥马利曲线的Curve25519密钥协商算法
    蒙哥马利曲线: B y 2 = x 3 + A x 2 + x B y^{2} = x^3 + A x ^2 + x By2=x3+Ax2+x, 其中 A , B ∈ K A, B \in K A,BK,且 B ( A 2 − 4 ) ≠ 0 B(A^2 - 4) \neq 0 B(A24)=0
    Curve25519曲线: y 2 = x 3 + 486662 x + b y^2 = x^3 + 486662x +b y2=x3+486662x+b, 由素数 2 255 − 19 2^{255} - 19 225519定义素数域
  3. 爱德华曲线和基于爱德华曲线的Ed25519数字签名算法
    爱德华曲线: x 2 + y 2 = 1 + d x 2 y 2 x^2 + y^2 = 1 + d x^2 y^2 x2+y2=1+dx2y2
    Ed25519曲线: − x 2 + y 2 = 1 − 121665 121666 x 2 y 2 -x^2 + y^2 = 1 - \frac{121665}{121666} x^2 y^2 x2+y2=1121666121665x2y2

Curve25519加密解密

出于安全性的考虑,在原本明文传输的基础上需要对传输内容进行加密,首先,curve25519是一个不对称加密算法,需要前后端相配合,双方一起使用该加密算法,逻辑如下:

  • 前端使用generateKeyPair得到自己的公钥和私钥,用自己前端的公钥去交换后端的公钥

  • 后端使用generateKeyPair得到自己的公钥和私钥,将后端的公钥返回给前端,同时,用自己的私钥和前端的公钥生成shareKey

  • 前端用前端的私钥和后端的公钥生成前端的shareKey

  • 前端用shareKey将请求进行加密,在使用AES进行第二次加密

  • 后端首先使用AES进行解密,再使用生成的shareKey对前端的请求进行第二次解密,格式符合要求则,使用shareKey进行加密,然后AES加密,传输给前端

  • 前端拿到数据,第一步使用AES进行解密,第二步使用shareKey进行解密
    算法样例详解如下:
    在这里插入图片描述
    在这里插入图片描述

算法论文详解

详见参考地址:Curve25519: new Diffie-Hellman speed records
在这里插入图片描述
在这里插入图片描述

Ed25519 数字签名机制

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Curve25519加解密 和 Ed25519加验签的使用

Curve25519

Curve25519 是目前最高水平的 Diffie-Hellman函数,适用于广泛的场景,在密码学中,Curve25519是一个椭圆曲线提供128位安全性,设计用于椭圆曲线Diffie-Hellman(ECDH)密钥协商方案。它是最快的ECC曲线之一,并未被任何已知专利所涵盖。

  • 实例化:

    Curve25519 cipher = Curve25519.getInstance(Curve25519.BEST)
    
  • 生成秘钥对:

    Curve25519KeyPair keyPair = cipher!!.generateKeyPair()
    byte[] privateKey = keyPair.getPrivateKey()
    byte[] publicKey = keyPair.getPublicKey()
    
  • 生成共享秘钥:

    byte[] temp = cipher!!.calculateAgreement(publicKey,privateKey)
    

Ed25519

Ed25519是一个数字签名算法,签名和验证的性能都极高, 一个4核2.4GHz 的 Westmere cpu,每秒可以验证 71000 个签名,安全性极高,等价于RSA约3000-bit。签名过程不依赖随机数生成器,不依赖hash函数的防碰撞性,没有时间通道攻击的问题,并且签名很小,只有64字节,公钥也很小,只有32字节。

  • 实例化:

    KeyPairGenerator edDsaKpg = new KeyPairGenerator()
    
  • 生成秘钥对:

    KeyPair keyPair = edDsaKpg.generateKeyPair()
    PrivateKey privateKey = keyPair.getPrivate()
    PublicKey publicKey = keyPair.getPublic()
    
  • 生成共享秘钥:

    //签名
    byte[] setSign(byte[] data){
        EdDSAEngine edEng  = new EdDSAEngine();
        edEng.initSign(privateKey);
        edEng.setParameter(EdDSAEngine.ONE_SHOT_MODE);
        edEng.update(data);
        byte[] enEdata =  edEng.sign();
        return enEdata;
    }
    
    
  • 验签

    //验证
    Boolean verifySign(String:data,String:signData){
        String mKey = "签名时的秘钥";
        EdDSAEngine edEng  = new EdDSAEngine();
        EdDSANamedCurveSpec spec = EdDSANamedCurveTable.getByName(ED_25519);    
        edEng.initVerify(new EdDSAPublicKey(new    EdDSAPublicKeySpec(base64Dec(mKey), spec)));
        edEng.setParameter(EdDSAEngine.ONE_SHOT_MODE);
        edEng.update(data.getBytes());
        Boolean isSuccess = edEng.verify(base64Dec(signData));
        return isSuccess;
    }
    
    

25519曲线和ECC曲线的联系和区别

  • Curve25519(X25519)是进行蒙哥马利曲线(Montgomery Curve)迪菲赫尔曼秘钥交换的椭圆曲线算法。
  • Ed25519是进行爱德华曲线(Edwards Curve)数字签名的椭圆曲线算法。

25519曲线与SECG(Standards for Efficient Cryptography Group)工作组所指定的魏尔斯特拉斯曲线(Weierstrass Curve)在曲线的公式上有所不同,因此他们不兼容。
蒙哥马利曲线和爱德华曲线的算法,能做到“Time-constant”,也就是说不论他们进行运算的数值是多少,他们所花的时间是相同的,因此“时间旁路”(Time side channel)攻击就对它们无效。

RSA加解密与加验签

基本流程图:
在这里插入图片描述
A机构生成A的密钥对,把公钥给到B;同样的,B把自己的公钥给A。这样A在生成加密报文的时候,会用B的公钥加密明文,然后用A的私钥对明文进行加签。OK,此时只有B的私钥才能解密报文,而私钥只有B才有,即使报文被截获,第三方也无法解密。如果A的公钥是公开的(实际上可能也不公开),那么第三方能解析出报文的HASH结果,也只是Hash结果…无法获得明文。B接受到请求后,用自己的私钥解密报文,然后对报文进行验签,如果不一致,那么也不会响应请求,这样的模式,通信过程的安全性就可以得到保障了。

参考链接:

https://www.jianshu.com/p/5dba044f67b1
https://blog.csdn.net/farley119/article/details/87875201
https://blog.csdn.net/marko_zheng/article/details/100882231
https://master–eager-lamarr-59a89f.netlify.app/2018/12/28/cryptography/ed25519/
https://blog.csdn.net/zhshulin/article/details/71573542

点击阅读全文
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐