ECDH java后端和javaScript前后端互通实现

  • 问题背景
    • ECDH算法
    • Java 实现
    • 前端JavaScript 实现

问题背景

web前端和后端之间的通信不一定可靠,如果不方便使用预共享密钥的方式完成身份的确认,那么可以使用ECDH密钥协商算法在前端和后端进行密钥间的协商。

ECDH算法

Elliptic-curve Diffie-Hellman(ECDH)是一种通过两方达成密钥协商的密钥生成算法,每一方都有一个椭圆双曲线的公私钥对,双方在不安全的通信通道间传递信息达成密钥生成协议。生成的密钥会被直接作为一个密钥或者是生成其他密钥的种子。最终生成的密钥将被对称密码学算法例如AESGCM作为密钥使用。
接下来的例子阐述了共享密钥是如何产生的:
Alice想和Bob建立一个共享密钥,但是唯一能够传递消息的通道被第三方监听。在初始时刻,Alice和Bob共享了些域的参数(p a,b,G,n,h),Alice在整数范围[t,n-1]中随机选择一个私钥d,并通过计算(Q=d·G)具体计算方式,得到了公钥Q,公私钥对为( d A d_A dA​, Q A Q_A QA​)。Bob用同样的计算方式得到了( d B d_B dB​, Q B Q_B QB​)。双方将自己的公钥发送给对方,分别计算:
( x k x_k xk​, y k y_k yk​)= d A d_A dA​· Q B Q_B QB​
( x k x_k xk​, y k y_k yk​)= d B d_B dB​· Q A Q_A QA​
( x k x_k xk​, y k y_k yk​)即为所得的私钥。
Alice仅仅公开了她的公钥信息,任何参与方想要计算出Alice的公钥需要解决椭圆曲线离散对数问题(这很难被计算出来)。因此我们认为Alice和Bob通过这样的方法协商密钥是安全的。除了Alice和Bob,没有谁能计算出他们协商的密钥。
在众多ECDH算法的计算标准中,Curve25519是使用最为广泛的密钥生成算法。

Java 实现

public class EcdhKeyPair{private String privatekey;
private String publicKey;
public String getprivatekey(){return privatekey;
}
public String getPublicKey(){return publickey;
}
public class Ecdhservice{private static final int ECDH_KEY_LEN= 32;private static final int SHARED_KEY_LEN= 16;private byte[] privatekey;private byte[] publicKey;private BigInteger pInteger;private EcdhKeyPair ecdhKeyPair;private static final SecureRandom RANDOM_GENERATOR;
static {try {RANDOM_GENERATOR = SecureRandom.getInstancestrong();} catch(NoSuchAlgorithmException e){log.error("SecureRandom init failed. ECDH encryption would be unavailable.");
EcdhService.");throw new InnerException(INTERNAL_ERROR, "Failed to init ECDHService.");}}private void generatetckeyPair() {privatekey = new byte[ECDH KEY_LEN];publicKey= new byte [ECDH KEY LEN];X25519.generatePrivateKey(RANDOM_GENERATOR, privateKey);X25519.generatePublickey(privatekey, 0, publicKey, 0);}private byte[] establisSharedKey(byte[] clientPublicKey){if (clientPublicKey.length != 32 ) {throw new InnerExecption(INVALID_REQUEST, "Client ECDH public key should be 256 bits/32 bytes");}BigInteger cInteger = new Biginteger(clientpublickey);if (cInteger.equals(BigInteger ZERO) || cInteger.equals(BigInteger.ONE) || cInteger.equals(pInteger)|| cInteger.equals(pInteger.subtract(BigInteges.ONE))){throw new InnerException(INVALID_REQUEST, "Client ECDH public key Cannot be specific value.");}try {byte[] agreement = new byte[ECDH_KEY_LEN];try {X25519.calculateAgreement(getprivatekey(), 0,clientPublickey,0, agreement, 0);}catch (RuntimetException e) {throw new InnerException(INVALID_REQUEST,
"Cannot calculate the agreement with client key, please check the request parameters.");}MessageDigest digester = MessageDigest.getInstance("SHA-256");return Arrays.copy0fRange(digester.digest(agreement),0, SHARED_KEY_LEN);} catch (NoSuchAIgorithmException e) {throw new InnerException(INTERNAL_ERROR,
"Failed to calculate shared key. " + e.getLocalizedMessage());}
}

前端JavaScript 实现

注意: 此处JavaScript代码没有将生成的sharedKey进行SHA256处理。

import { sharedkey, generateKeypair } from "curve25519-js"
* @description 生成公钥秘钥
* @param {Uint8Array} backPublickeyBase64 后端base64加密的的公钥
* @return 共享秘key:Uint&Arnay privatekey 私钥
*
export function generatekey(backPublicKeyBase64: string){// 获取后端的公钥进行base64转成Uint8Array
const backPublickey=base64ToUint8Array(backPublicKeyBase64)
//符合密码学要求的安全的随机值 Uint8Array 32字节 8位无符号整型数组
const randomBytes = window.crypto.getRandomValues(new Uint8Array(32))
// 前端使用generatekeyPair得到自己的公钥和私钥,用自己前端的公钥去交换后端的公钥
const keyPair = generateKeyPair(randomBytes)
//将生成的公钥通过base64 加密发给后台
const publicKey =uint8arrayToBase64(keyPair.public)
// 根据后端的公钥用前端的松铜和后端的公钥生成前端的sharekey
const sharekey = sharedkey(keypair.private, backPublicKey)
return {publicKey,shareKey
}

【ECDH java后端和javaScript前后端互通实现】相关推荐

  1. Web实现前后端分离,前后端解耦

    作者:山河远阔 https://blog.csdn.net/weixin_37539378 一.前言 "前后端分离"已经成为互联网项目开发的业界标杆,通过Tomcat+Ngnix( ...

  2. Web 实现前后端分离,前后端解耦

    作者 | 山河远阔 来源 | blog.csdn.net/weixin_37539378/article/details/79956760 一.前言 "前后端分离"已经成为互联网项 ...

  3. 【转】Web实现前后端分离,前后端解耦

    一.前言 "前后端分离"已经成为互联网项目开发的业界标杆,通过Tomcat+Ngnix(也可以中间有个Node.js),有效地进行解耦.并且前后端分离会为以后的大型分布式架构.弹性 ...

  4. 关于Web实现前后端分离,前后端解耦

    一.前言 "前后端分离"已经成为互联网项目开发的业界标杆,通过Tomcat+Ngnix(也可以中间有个Node.js),有效地进行解耦.并且前后端分离会为以后的大型分布式架构.弹性 ...

  5. 从前后端分离到前后端整合的“退步”(一)项目结构

    系列文章目录 从前后端分离到前后端整合的"退步"(一)项目结构 从前后端分离到前后端整合的"退步"(二)pom.xml文件配置 Spring Boot + Vu ...

  6. 从前后端分离到前后端整合的“退步”(二)pom.xml文件配置

    系列文章目录 从前后端分离到前后端整合的"退步"(一)项目结构 从前后端分离到前后端整合的"退步"(二)pom.xml文件配置 Spring Boot + Vu ...

  7. 前后端分离与前后端不分离的区别

    前后端不分离 在前后端不分离的应用模式中,前端页面看到的效果都是由后端控制,由后端渲染页面或重定向,也就是后端需要控制前端的展示,前端与后端的耦合度很高. 这种应用模式比较适合纯网页应用,但是当后端对 ...

  8. 网站架构模式:前后端分离与前后端不分离

    前后端不分离 在前后端不分离的应用模式中,前端页面看到的效果都是由后端控制,由后端渲染页面或重定向,也就是后端需要控制前端的展示,前端与后端的耦合度很高. 这种模式比较适合纯网页应用,但是当后端对接A ...

  9. java图书管理系统(前后端分离前)

    项目源码Git地址:https://github.com/liuwen766/MyBookManagement.git 项目源码csdn地址:https://download.csdn.net/dow ...

最新文章

  1. 一年参加一次就够,全新升级的AI开发者大会议程出炉!
  2. 一文详解AI模型部署及工业落地方式
  3. python编程基础是什么-编程学习第一步,让你20天搞定Python编程
  4. JavaScript(九)正则表达式
  5. 不同频率数据的处理方法
  6. Laravel 的数据库迁移
  7. mysql查看事件任务内容_MySql事件计划任务
  8. JS 总结之关于 this 应该知道的几个点
  9. 16年10月计算机组成原理,福建师范大学16年8月课程考试《计算机组成原理》作业考核试题.doc...
  10. 微信App支付接入步骤支付中前后端交互流程
  11. _beginThread如何传递多个参数
  12. 仅三行代码的按键扫描程序,绝对够经典(秒杀郭天祥讲解的按键扫描)
  13. 酷安绿色版 免安装无需UWP版
  14. 乐高机器人骨奥_乐高机器人这个大坑,为啥大家都拽着孩子往里跳?
  15. Mac 安装VMware
  16. 改变word自带公式显示的字体的方法
  17. 热门Java开发工具IDEA入门指南——了解并学习IDE
  18. Android集成网易云信IM的2个坑及解决方法
  19. 微信小程序(布局适配与物理逻辑像素)
  20. 什么是MapReduce,MapReduce的工作流程和原理是什么

热门文章

  1. java导出word实现方式一,在jsp中实现
  2. 多渔:阿ken的故事
  3. c语言五子棋游戏心得体会,下五子棋执白子之心得
  4. 树状数组简单易懂的详解
  5. 小米遭虚假评价后索赔 100 万元
  6. jmp指令(0903)
  7. 小程序开发合同_小程序开发公司在哪里找?
  8. HDMI 2.1特性
  9. 安卓角色扮演游戏源码_角色扮演类安卓手游排行榜 热门手游推荐
  10. 实验七 二极管包络检波实验