前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >tron ECC使用及项目中的应用

tron ECC使用及项目中的应用

作者头像
潇洒
发布2023-10-23 14:40:24
2320
发布2023-10-23 14:40:24
举报
文章被收录于专栏:石头岛

简述

ECC(Elliptic Curves Cryptography,椭圆曲线密码编码学)是一种公开密钥算法。基于椭圆曲线数学的公开密钥加密算法,其本质是利用离散对数问题实现加密。 ECC的主要优势,是在使用更小的密钥的同时,提供更快的性能和更高等级的安全。 网上的理论大都讲的非常透彻,我也是看了很多,但是实际能力有限,对数论层面的只停留在浅薄的理解上,不敢乱讲。但是可以简单的说明其原理。

还有一点,加密算法包括RSAECC并不是不可以被破解,只是以当下现代计算机的计算性能算起来比较费劲,理论上破解ECC需要最少250万年,其破解的代价很高,以此来达到不可破解目的。 用量子计算?不说现在有量子技术可不可么,假设量子计算可是可行的,那为什么不升级到量子加密?

ECC: 基于椭圆曲线和离散对数

其原理是数论理论中的单向运算函数,这种函数有一个特点:正方向计算容易,反方向计算却十分困难。 啥意思?就是计算:

1234 * 4567 = ?

计算这个简单,结果是:5635678。 那么,返过来计算:

5635678 = x * y

这样就不好计算了,而且结果有很多种有可能是:

5635678 = 1 * 5635678 5635678 = 2 * 2817839 5635678 = 3 * 1408919.5

都有可能。

应用

在编程领域最难的是0到1的过程,而复用前人的技术和经验上就比较轻松。 在对ECC的使用上,已经将这一算法简化到接口层面,通过调用接口来获提需要的安全性。

BouncyCastle 加密工具包

BouncyCastle(轻量级密码术包)是一种用于 Java 平台的开放源码的轻量级密码术包;Bouncycstle 包含了大量的密码算法,其支持椭圆曲线密码算法,并提供JCE 1.2.1的实现。它提供了Java标准库没有的一些算法,例如,RipeMD160哈希算法。

TRON 中也是使用的这个算法工具包。 官网:https://www.bouncycastle.org/

ECKey 类

ECC 类是对加密工具的一个抽象,从类的Copyright上可以看到,这个类实际上是从ethereumJ拿过来的。好的设计都是相通的。

ECC在TRON中,创建账号的时候的用法:

1.获取一个ECKey 对象 2.获得私钥 3.获得公钥

通过 TRON 中生成账户这个接口来,非常典型

代码语言:javascript
复制
@Component
@Slf4j(topic = "API")
public class GenerateAddressServlet extends RateLimiterServlet {

  protected void doGet(HttpServletRequest request, HttpServletResponse response) {
    try {
      // 获得一个Sign 接口用来获得私钥
      SignInterface sign = SignUtils.getGeneratedRandomSign(Utils.getRandom(),
          Args.getInstance().isECKeyCryptoEngine());
      // 获得私钥
      byte[] priKey = sign.getPrivateKey();
      // base58check 地址,我在之前的文章的专门讲过这个格式
      byte[] address = sign.getAddress();
      // 转成 十六进制字符串,这个也就是通常意义是的私钥,不能丢
      String priKeyStr = Hex.encodeHexString(priKey);
      // 推出 base58check 地址
      String base58check = StringUtil.encode58Check(address);
      String hexString = ByteArray.toHexString(address);
      JSONObject jsonAddress = new JSONObject();
      jsonAddress.put("address", base58check);
      jsonAddress.put("hexAddress", hexString);
      jsonAddress.put("privateKey", priKeyStr);
      // 回写给前端,可以是页面、postman
      response.getWriter().println(jsonAddress.toJSONString());
    } catch (Exception e) {
      Util.processError(e, response);
    }
  }

  protected void doPost(HttpServletRequest request, HttpServletResponse response) {
    doGet(request, response);
  }
}

调一下试试,反复多调几次可以生成不同的私钥

curl -X GET http://127.0.0.1:8090/wallet/generateaddress

结果关键是拿到私钥,然后通过私钥获得公钥、base58check:

address: TNV7s8K96ZgEiFDuecSXvzKKJgkXwtjkWi hexAddress: 418949b347588b1901fdf3b6e6dc80dffcd385c4de privateKey: f7252a484bc631e57910cf65481b12c32b2906fa05742c72f27669b9ddc5d871

使用就是这么简单,可以本地起一个FullNode自行调用接口,产生新的私钥,并没有中心化节点的之间的通信,也可以调用官方节点的接口,都是一样的。可以反复生成私钥,用来测试。

看下SignUtils.getGeneratedRandomSign是怎么处理

代码语言:javascript
复制
public static SignInterface getGeneratedRandomSign(
    SecureRandom secureRandom, boolean isECKeyCryptoEngine) {
  //安全的随机数,在java中Random是伪随机数,并不安全,SecureRandom 是安全的随机数
  // isECKeyCryptoEngine = true
  if (isECKeyCryptoEngine) {
    return new ECKey(secureRandom);
  }
  return new SM2(secureRandom);
}

完整示例

使用一个完整的例子来看看怎么用。

代码语言:javascript
复制
public static void test() {
  // 生成一个 ECKey 对象
  ECKey ecKey = new ECKey(Utils.getRandom());
  String privateKey = ByteArray.toHexString(ecKey.getPrivKeyBytes());
  String publicKey = Hex.toHexString(ecKey.getPubKey());
  byte[] hexAddress = ecKey.getAddress();
  String base58check1 = PublicMethed.getAddressString(privateKey);
  String base58check2 = StringUtil.encode58Check(hexAddress);
  String bash58check3 = Base58.encode58Check(hexAddress);

  System.out.println("private key: " + privateKey);
  System.out.println("public key" +  publicKey);
  System.out.println("hex address1: " + ByteArray.toHexString(hexAddress));
  System.out.println("base58check1: " + base58check1);
  System.out.println("base58check2: " + base58check2);
  System.out.prntln("bash58check3: " + bash58check3);
  ByteString bytes = ByteString.copyFrom(Commons.decodeFromBase58Check(base58check1));
  System.out.println("hex address2: " + ByteArray.toHexString(bytes.toByteArray()));
}

base58check 地址

base58check是一种特殊的格式,我在之前的文章中讲过个格式。看看它是怎么实现的。 TRON 中有两处需要使用到base58check格式:

  1. 私钥address
  2. 账户address

基本上账户的address用的多,在转账交易中base58check地址用的是最多的。 base58check就是给人看的,实际数据存到数据库中就是byte[]。

看下 base58check 的工作原理:将输入数据进行两次hash后,截取部分数据进行base58编码。

代码语言:javascript
复制
public static String encode58Check(byte[] input) {
  byte[] hash0 = Sha256Hash.hash(CommonParameter.getInstance().isECKeyCryptoEngine(), input);
  byte[] hash1 = Sha256Hash.hash(CommonParameter.getInstance().isECKeyCryptoEngine(), hash0);
  byte[] inputCheck = new byte[input.length + 4];
  System.arraycopy(input, 0, inputCheck, 0, input.length);
  System.arraycopy(hash1, 0, inputCheck, input.length, 4);
  return Base58.encode(inputCheck);
}

总结

分享了一下ECC的用法,使用场景上不同链的用法也都是大同小异,明白几个概念,在关键处不至于被卡住。 学习方法我不断强调先熟练使用,再谈理解。 总是会有朋友跟我谈如何学习、理解这个问题,总觉得自己不聪明、理解不了。排除每个各人的理解能力,只谈投入时间,如果没有达到称的上努力的程度,请先不要谈悟性,如果你做不到看一眼一分钟内就理解,那么每天最少一小时的时间成本投入都没有,那先不要谈悟性。 时间也是成本,不要吝啬在重要的事情上投入时间

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-06-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简述
    • ECC: 基于椭圆曲线和离散对数
    • 应用
      • BouncyCastle 加密工具包
        • ECKey 类
        • 完整示例
          • base58check 地址
          • 总结
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档