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…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战
说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...