ECDH secp256k1 集成
在Android 原生api是不支持secp256k1算法的,所以要先集成以下库:
implementation 'com.madgag.spongycastle:core:1.58.0.0'compile 'com.madgag.spongycastle:prov:1.54.0.0'compile 'com.madgag.spongycastle:pkix:1.54.0.0'compile 'com.madgag.spongycastle:pg:1.54.0.0'
然后在使用前需要添加一行代码
static {Security.insertProviderAt(new org.spongycastle.jce.provider.BouncyCastleProvider(), 1);}
1 获取公钥与私钥 :
private void nnnn() {X9ECParameters ecp = SECNamedCurves.getByName("secp256k1");ECDomainParameters domainParams = new ECDomainParameters(ecp.getCurve(),ecp.getG(),ecp.getN(),ecp.getH(),ecp.getSeed());// Generate a private key and a public keyAsymmetricCipherKeyPair keyPair;ECKeyGenerationParameters keyGenParams = new ECKeyGenerationParameters(domainParams, new SecureRandom());ECKeyPairGenerator generator = new ECKeyPairGenerator();generator.init(keyGenParams);keyPair = generator.generateKeyPair();ECPrivateKeyParameters privateKey = (ECPrivateKeyParameters) keyPair.getPrivate();ECPublicKeyParameters publicKey = (ECPublicKeyParameters) keyPair.getPublic();byte[] privateKeyBytes = privateKey.getD().toByteArray();// First print our generated private key and public keyLog.e("mlt",".......Private key:..........."+ECDH.toHex(privateKeyBytes));Log.e("mlt","........Public key:..........."+ECDH.toHex(publicKey.getQ().getEncoded(true)));
// Then calculate the public key only using domainParams.getG() and private keyECPoint Q = domainParams.getG().multiply(new BigInteger(privateKeyBytes));Log.e("mlt",".......Calculated public key:...." +"......."+ECDH.toHex(Q.getEncoded(true)));// The calculated public key and generated public key should always matchif (!ECDH.toHex(publicKey.getQ().getEncoded(true)).equals(ECDH.toHex(Q.getEncoded(true)))) {Log.e("mlt",".......ERROR: Public keys do not match!:...........");} else {Log.e("mlt",".......Congratulations, public keys match:...........");}}
字符转byte[]
public static String toHex(byte[] data) {StringBuilder sb = new StringBuilder();for (byte b: data) {sb.append(String.format("%02x", b&0xff));}return sb.toString();}
先看下密钥对:
//56477ec67d3e3426db2646a9f873cb6c90753bcfc51ea1fc8b0b982dffcd8791 Private key
//0384bb60ab084f42a6093839eec228d9b3f4641ff80b6fe96a1ad55ec12ade9a8f Public key
3 生成共享密钥
public static String generateAgreedKey(PrivateKey privateKey, PublicKey publicKey) throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException {KeyAgreement keyAgreement = KeyAgreement.getInstance("ECDH", "SC");keyAgreement.init(privateKey);keyAgreement.doPhase(publicKey, true);byte[] sharedKeyBytes = keyAgreement.generateSecret();
// return Base64.encodeToString(sharedKeyBytes, Base64.DEFAULT).replaceAll("\n", "");return toHex(sharedKeyBytes);}
4 因为生成对是16进制 key需要转publickey 和privatekey 还需另外方法
public static ECPublicKey keyToPublick(String key) throws NoSuchAlgorithmException, InvalidKeySpecException {// transform from hex to ECPublicKeybyte[] ecRawExternalPublicKey = hexStringToByteArray(key);ECPublicKey ecExternalPublicKey = null;KeyFactory externalKeyFactor = null;ECNamedCurveParameterSpec ecExternalNamedCurveParameterSpec = ECNamedCurveTable.getParameterSpec("secp256k1");ECCurve curve = ecExternalNamedCurveParameterSpec.getCurve();EllipticCurve ellipticCurve = EC5Util.convertCurve(curve, ecExternalNamedCurveParameterSpec.getSeed());java.security.spec.ECPoint ecPoint = ECPointUtil.decodePoint(ellipticCurve, ecRawExternalPublicKey);java.security.spec.ECParameterSpec ecParameterSpec = EC5Util.convertSpec(ellipticCurve, ecExternalNamedCurveParameterSpec);java.security.spec.ECPublicKeySpec externalPublicKeySpec = new java.security.spec.ECPublicKeySpec(ecPoint, ecParameterSpec);externalKeyFactor = java.security.KeyFactory.getInstance("EC");// this is externalPubicKeyecExternalPublicKey = (ECPublicKey) externalKeyFactor.generatePublic(externalPublicKeySpec);return ecExternalPublicKey;}public static ECPrivateKey keyToPrivate(String key) throws NoSuchAlgorithmException, InvalidKeySpecException {// transform from hex to ECPublicKeybyte[] ecRawExternalPublicKey = hexStringToByteArray(key);ECPrivateKey ecPrivateKey = null;KeyFactory externalKeyFactor = null;ECNamedCurveParameterSpec ecExternalNamedCurveParameterSpec = ECNamedCurveTable.getParameterSpec("secp256k1");ECCurve curve = ecExternalNamedCurveParameterSpec.getCurve();EllipticCurve ellipticCurve = EC5Util.convertCurve(curve, ecExternalNamedCurveParameterSpec.getSeed());java.security.spec.ECParameterSpec ecParameterSpec = EC5Util.convertSpec(ellipticCurve, ecExternalNamedCurveParameterSpec);java.security.spec.ECPrivateKeySpec externalPublicKeySpec = new java.security.spec.ECPrivateKeySpec(new BigInteger(ecRawExternalPublicKey), ecParameterSpec);externalKeyFactor = java.security.KeyFactory.getInstance("EC");// this is externalPubicKeyecPrivateKey = (ECPrivateKey) externalKeyFactor.generatePrivate(externalPublicKeySpec);return ecPrivateKey;}
string key 转 byte[]
public static byte[] hexStringToByteArray(String s) {int len = s.length();byte[] data = new byte[len / 2];for (int i = 0; i < len; i += 2) {data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)+ Character.digit(s.charAt(i + 1), 16));}return data;}
5 调用方法生成共享密钥
Log.e("mlt","...........aaa....."+ECDH.generateAgreedKey(globalData.getPrivateKey(), ECDH.keyToPublick(ss)));//随时生成私钥可以用这个
Log.e("mlt","...........aaa....."+ECDH.generateAgreedKey(ECDH.keyToPrivate(prsss), ECDH.keyToPublick(ss)));//把本地私钥保存本地
public static String generateAgreedKey(PrivateKey privateKey, PublicKey publicKey) throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException {KeyAgreement keyAgreement = KeyAgreement.getInstance("ECDH", "SC");keyAgreement.init(privateKey);keyAgreement.doPhase(publicKey, true);byte[] sharedKeyBytes = keyAgreement.generateSecret();
// return Base64.encodeToString(sharedKeyBytes, Base64.DEFAULT).replaceAll("\n", "");return toHex(sharedKeyBytes);}
基本就可以了,下面说几个问题,本来stringkey是用下面这两个方法,结果会出现问题
public static PublicKey stringToPublicKey(String key) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException {byte[] keyBytes = Base64.decode(key.getBytes("utf-8"), Base64.DEFAULT);X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance("ECDH", "SC");return keyFactory.generatePublic(spec);}
public static PrivateKey stringToPrivateKey(String key) throws UnsupportedEncodingException, NoSuchProviderException, NoSuchAlgorithmException, InvalidKeySpecException {byte[] keyBytes = Base64.decode(key.getBytes("utf-8"), Base64.DEFAULT);PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance("ECDH", "SC");return keyFactory.generatePrivate(spec);}
这个两个不成功所以采用上面的方法实现
参考代码:
// arrive a string like this 04456cb4ba8ee9263311485baa8562c27991f7ff22d59f3d8245b9a05661d159911b632a6f8a7a080d82f4ca77e4d12bb201b89c8ec93f61d5b4dd22df42e1b482
Map<String, Object> result = new HashMap<>();try {// set providerSecurity.addProvider(new BouncyCastleProvider());// transform from hex to ECPublicKeybyte[] ecRawExternalPublicKey = this.toByte(externalRawPublicKey);ECPublicKey ecExternalPublicKey = null;KeyFactory externalKeyFactor = null;ECNamedCurveParameterSpec ecExternalNamedCurveParameterSpec = ECNamedCurveTable.getParameterSpec("secp256r1");ECCurve curve = ecExternalNamedCurveParameterSpec.getCurve();EllipticCurve ellipticCurve = EC5Util.convertCurve(curve, ecExternalNamedCurveParameterSpec.getSeed());java.security.spec.ECPoint ecPoint = ECPointUtil.decodePoint(ellipticCurve, ecRawExternalPublicKey);java.security.spec.ECParameterSpec ecParameterSpec = EC5Util.convertSpec(ellipticCurve, ecExternalNamedCurveParameterSpec);java.security.spec.ECPublicKeySpec externalPublicKeySpec = new java.security.spec.ECPublicKeySpec(ecPoint, ecParameterSpec);externalKeyFactor = java.security.KeyFactory.getInstance("EC");// this is externalPubicKeyecExternalPublicKey = (ECPublicKey) externalKeyFactor.generatePublic(externalPublicKeySpec);KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ECDH","BC");keyGen.initialize(new ECGenParameterSpec("secp256r1"), new SecureRandom());KeyPair pair = keyGen.generateKeyPair();ECPublicKey pub = (ECPublicKey)pair.getPublic();ECPrivateKey pvt = (ECPrivateKey)pair.getPrivate();byte[] pubEncoded = pub.getEncoded();byte[] pvtEncoded = pvt.getEncoded();KeyAgreement keyAgree = KeyAgreement.getInstance("ECDH");keyAgree.init(pvt);keyAgree.doPhase(ecExternalPublicKey, true);System.out.println("sharedKey:"+ this.bytesToHex( keyAgree.generateSecret() ));// internal public keyreturn"04"+ pub.getW().getAffineX().toString(16) + pub.getW().getAffineY().toString(16)}catch (Exception e ){e.printStackTrace();return null;}
https://www.codenong.com/51861056/
https://www.lmlphp.com/user/151226/article/item/3360735/
https://cloud.tencent.com/developer/ask/sof/275206
http://www.17bigdata.com/study/programming/bcalg/bcalg-secp256k1.html
https://blog.csdn.net/weixin_29192211/article/details/114853972
// generate bogus keypair(!) with named-curve paramsKeyPairGenerator kpg = KeyPairGenerator.getInstance("EC");ECGenParameterSpec gps = new ECGenParameterSpec ("secp256r1"); // NIST P-256kpg.initialize(gps);KeyPair apair = kpg.generateKeyPair();ECPublicKey apub = (ECPublicKey)apair.getPublic();ECParameterSpec aspec = apub.getParams();// could serialize aspec for later use (in compatible JRE)//// for test only reuse bogus pubkey, for real substitute valuesECPoint apoint = apub.getW();BigInteger x = apoint.getAffineX(), y = apoint.getAffineY();// construct point plus params to pubkeyECPoint bpoint = new ECPoint (x,y);ECPublicKeySpec bpubs = new ECPublicKeySpec (bpoint, aspec);KeyFactory kfa = KeyFactory.getInstance ("EC");ECPublicKey bpub = (ECPublicKey) kfa.generatePublic(bpubs);//// for test sign with original key, verify with reconstructed keySignature sig = Signature.getInstance ("SHA256withECDSA");byte [] data = "test".getBytes();sig.initSign(apair.getPrivate());sig.update (data);byte[] dsig = sig.sign();sig.initVerify(bpub);sig.update(data);System.out.println (sig.verify(dsig));
https://blog.csdn.net/weixin_39583751/article/details/116008623
相关文章:

ECDH secp256k1 集成
在Android 原生api是不支持secp256k1算法的,所以要先集成以下库:implementation com.madgag.spongycastle:core:1.58.0.0compile com.madgag.spongycastle:prov:1.54.0.0compile com.madgag.spongycastle:pkix:1.54.0.0compile com.madgag.spongycastle:…...

工单模型的理解与应用
工单(任务单)模型的定义 工单模型是一种分派任务的方法,可以用来跟踪、评估和报告任务的完成情况。它通常用于针对特定目标的重复性任务或项目,以确保任务能够按时完成并符合期望的标准。 工单模型的基本流程为:提…...

Python年利率计算器【N日年化收益率】
现在有闲钱的人,按照聪明等级从低到高排序应该是钱买股票,一年利率约为-20%钱放银行活期,年利率约为0.3%钱放银行定期,一年利率约为1.5%钱放余额宝(支付宝)或零钱通(微信)࿰…...

3年测试拿8K,被校招来的实习生反超薪资,其实你在假装努力
最近朋友给我分享了一个他公司发生的事 大概的内容呢:公司一位工作3年的测试工资还没有新人高,对此怨气不小,她来公司辛辛苦苦三年,三年内迟到次数都不超过5次,每天都是按时上下班,工作也按量完成…...

因子分析计算权重
因子分析两类权重计算方法总结 案例背景 疫情爆发以来,越来越多的人为了避免线下与人接触,选择了线上购买生活必需品。网购虽然方便快捷,但是随着订单压力的增加,物流问题也随之出现,近期有很多卖家收到物流投诉的问题…...

国家调控油价预测案例+源码
项目git地址:https://github.com/Boris-2021/Oil-price-control-forecast 使用已知的历史数据:日期、汇率、布伦特、WTI、阿曼原油价格,预测下一个调价周期中的汽油、柴油零售限价的调价价格。 一. 需求 1.1 需求说明 使用已知的历史数据&a…...

Gephi快速入门
Gephi快速入门1. 导入文件(Import file)2. 布局(Layout)3. 排序(Ranking)4. 指标(Metrics)5. 标签(Label)6. 社区发现(Community detection&#…...

GitHub
什么是 Github?GitHub是一个面向开源及私有软件项目的托管平台,因为只支持Git作为唯一的版本库格式进行托管,故名GitHub。一、常用词Watch:观察。如果watch了一个项目,之后这个项目有更新,你会在第一时间收到该项目更…...

QT基础入门【调试篇】QT远程部署与调试嵌入式ARM开发板
目录 一、环境配置 1、根据开发板完成交叉编译链以及GDB的配置(因开发板而异)...

可观测性最佳实践|阿里云事件总线 EventBridge 最佳实践
本文介绍如何把阿里云事件总线 EventBridge 的内容接入观测云平台,通过观测云强大的统一汇聚能力轻松获取阿里云事件,实时追踪最新的数据信息。 背景信息 事件总线 EventBridge 是阿里云提供的一款无服务器事件总线服务,支持阿里云服务、自定…...

设计模式-行为型
设计模式-行为型 行为型设计模式主要用于软件运行时复杂的流程控制。包含:模板方法模式、策略模式、命令模式、职责链模式、状态模式、观察者模式、中介者模式、迭代器模式、访问者模式、备忘录模式和解释器模式 模板方法模式 在软件设计时,很多时候系…...

Salesforce大揭秘!SaaS鼻祖不为人知的那些事!
Salesforce的世界无疑是广阔的。自从创始人Marc Benioff于1999年创立公司以来,Salesforce一直在打破CRM领域的界限,改变销售、营销和技术的格局。 作为全球领先的B2B科技公司之一,Salesforce和硅谷里的其他企业一样,缔造着一个关…...

Oracle——物化视图
文章目录含义物化视图的语法物化视图的创建1、自动刷新的物化事务 ON COMMIT2、非自动刷新的物化视图 ON demand关于手动刷新物化视图的删除资料参考含义 什么是物化视图? 物化视图,通俗点说就是物理化的视图。 什么叫物理化? 将视图以表结构…...

ur3+robotiq 2f 140配置moveit
ur3robotiq 2f 140配置moveit 参考链接1 参考链接2 官方配置movit教程 搭建环境: ubuntu: 20.04 ros: Nonetic sensor: robotiq_ft300 gripper: robotiq_2f_140_gripper UR: UR3 reasense: D435i 通过下面几篇博客配置好了ur3、力传感器、robotiq夹爪…...

LDO 芯片烫手,问题出在哪里?
设计失误的一个电路,该电路是数字电路的电源,为图方便对12V直接通过线性电源芯片降压到5V: 图1:线性电源降压12V转5V 几块电路板打样好后,测试均发现AMS1117-5.0芯片烫手,负载电流100mA多,也满…...

零日漏洞发展格局及防御策略
在过去的一年半中, 在野利用的零日漏洞数量持续飙升 ,这些软件制造商尚不知晓的漏洞正在被国家行为体黑客组织和勒索软件团伙滥用。 今年上半年,Google Project Zero统计了近20个零日漏洞,其中 大部分针对微软、苹果和谷歌构建的…...

RabbitMQ 可用磁盘空间报警
概要当磁盘可用空间低于设定的值(默认50M),将触发警报,并阻塞所有生产者。这目标是为了避免填满整个磁盘,这将导致所有节点上的写入操作失败,并可能导致RabbitMQ停止服务。如何工作为了减少磁盘被填满的风险…...

Web前端学习:二
二一:文字font-size样式 font-size:**px 控制文字大小,可精准控制大小 默认样式medium,中等的 large,大一号 x-large,再大一号 xx-large,再大一号 small,小一号 <!DOCTYPE html…...

【第一章 计算机网络体系结构,标准化工作相关组织,性能指标,分层结构,OSI参考模型】
第一章 计算机网络体系结构,标准化工作相关组织,性能指标,分层结构,OSI参考模型 1.计算机网络: (1)概念: ①计算机网络是将一个分散的、具有独立功能的计算机系统,通过通…...

SpringIOC源码解析
Spring深度学习(一)——IOC的设计理念Spring的核心思想——IOCSpring流程图DEMO编写Spring IoC容器的加载过程实例化化容器:AnnotationConfigApplicationContext实例化建BeanDefinition读取器: AnnotatedBeanDefinitionReaderBean…...

【Jupyter Notebook的简单入门使用】
【Jupyter Notebook的简单入门使用】简单介绍安装与配置简单使用Markdown关闭简单介绍 Jupyter官网 Jupyter Notebook 介绍 简单来讲,它是一个网页应用,可以进行文档编写,甚至运行 py 代码等功能 安装与配置 下载合适版本的 python &#…...

@Component@Import@Bean加载顺序解析
【前言】 我们在使用Spring注入Bean对象时,会使用不同注解,比如Component Service Controller Import Bean等。由于Service Controller 等都可以归为Component,那么Component 和Import 、Bean是何时被加载的,以及他们之间的顺序呢…...

二极管温度补偿电路工作原理分析
众所周知,PN结导通后有一个约为0.6V(指硅材料PN结)的压降,同时PN结还有一个与温度相关的特性:PN结导通后的压降基本不变,但不是不变,PN结两端的压降随温度升高而略有下降,温度愈高其…...

【C语言】多线程之条件竞争
多线程(三)条件竞争并发程序引起的共享内存的问题死锁互斥锁机制生产者消费者模型信号量机制解决:条件竞争 #include<stdio.h> #include<stdlib.h> #include<pthread.h> void* Print(char* str){printf("%s ",s…...

UE NavigationSystem的相关实现
导航数据的构建流程导航数据的收集导航系统中绑定了Actor、Component注册完成以及取消时的委托,通过这些委托把数据及时更新到导航系统的八叉树结构中导航系统的辅助结构DefaultOctreeController、DefaultDirtyAreasController分别承担了空间数据查询和置脏区域重新…...

Java 继承
文章目录1. 继承概述2. 变量的访问特点3. super 关键字4. 构造方法的访问特点5. 成员方法的访问特点6. 方法重写7. 继承案例1. 继承概述 继承是面向对象三大特征之一。可以使得子类具有父类的属性和方法,还可以在子类中重新定义,追加属性和方法。 publ…...

Python学习笔记8:异常
异常 一些内置的异常类 类名描述Exception几乎所有的异常类都是从它派生而来的AttributeError引用属性或给它赋值失败时引发OSError操作系统不能执行指定的任务(如打开文件)时引发,有多个子类IndexError使用序列中不存在的索引时引发&#…...

python保留小数函数总结
python保留小数——‘%f’‘%.nf’% x(定义的变量) 例子:a 82.16332 print(%.1f% a) print(%.2f% a) print(%.3f% a) print(%.4f% a) print(%.10f% a)输出结果python保留小数——format()函数Python2.6 开始ÿ…...

狐狸优化算法(Matlab代码实现)
👨🎓个人主页:研学社的博客💥💥💞💞欢迎来到本博客❤️❤️💥💥🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密…...

浏览器自动化框架沦为攻击者的工具
5月27日消息,安全公司Team Cymru的研究人员表示,越来越多的威胁参与者正在使用免费的浏览器自动化框架作为其攻击活动的一部分。 研究人员表示,该框架的技术准入门槛故意保持在较低水平,以创建一个由内容开发者和贡献者组成的活跃…...