资讯专栏INFORMATION COLUMN

Ed25519应用,node,js生成常用的密钥对

Yumenokanata / 1663人阅读

摘要:生成用户常规保存的字符串。首先安装依赖包解释简单解释说明下包的作用最核心的包是用接口实现的端口,它实现了密钥加密解密,公钥验证加密,公共签名,等。我们将使用这个库生成,原始的密钥对。生成校验码的是一个一致性模块化高性能的实用工具库。

Ed25519签名算法介绍 Ed25519作者

Daniel J. Bernstein 是世界著名的密码学家

优势

完全开放设计,算法各个参数直接了当,明确,很大的概率通过缓存、时间、恶意输入摧毁安全性,而 25519 系列椭圆曲线经过特别设计,尽可能的将出错的概率降到了最低,25519 系列曲线是目前最快的椭圆曲线加密算法,一个4核2.4GHz 的 Westmere cpu,每秒可以验证 71000 个签名,吊打同类:椭圆曲线是 NIST

基本特点

公共钥只有32字节,私钥只有64字节

实战node,js生成Ed25519密钥对 目标

通过tweetnacl生成原始的Uint8Array密钥对,生成公钥,私钥类型首字母G,S写入Buffer,然后私钥写入Buffer,通过上面Buffer计算校验码再次写入buffer,最后使用base32编码。生成用户常规保存的字符串。

首先安装依赖包

npm I tweetnacl crc lodash base32.js —save
解释简单解释说明下包的作用
tweetnacl: 最核心的包,是用javascript接口实现的TweetNaci/Naci端口,它实现了密钥加密解密,公钥验证加密,公共签名,hash等。我们将使用这个库生成,原始的Uint8Array密钥对。也可以自己随机一个64byte私钥,然后解析为keypair。
crc:生成校验码的
lodash:是一个一致性、模块化、高性能的 JavaScript 实用工具库。
base32.js:由于原生方法,只有base64,所以引入base32.js进行编码解码

具体代码实现
//各种引入  
const nacl = require(“tweetnacl");
const crc = require("crc");
const base32 = require("base32.js")
const isUndefined = require("lodash/isUndefined");
const isNull = require("lodash/isNull");
const isString = require("lodash/isString");
const versionBytes = {
  ed25519PublicKey:  6 << 3, // G
  ed25519SecretSeed: 18 << 3, // S
  preAuthTx:         19 << 3, // T
  sha256Hash:        23 << 3  // X
};

//封装一个类,构造函数中生成keypair,提供静态编码解码公钥私钥方法
class Keypair {
    constructor(){
        this.orikeypair = nacl.sign.keyPair();
        this.publicKey = Buffer.from(this.orikeypair.publicKey);
        console.log(this.orikeypair.publicKey);
        this.privateKey = Buffer.from(this.orikeypair.secretKey);
    }
    static encodeCheck(versionByteName, data) {
        if (isNull(data) || isUndefined(data)) {
            throw new Error("cannot encode null data");
        }
        let versionByte = versionBytes[versionByteName];
        if (isUndefined(versionByte)) {
            throw new Error(`${versionByteName} is not a valid version byte name.  expected one of "ed25519PublicKey", "ed25519SecretSeed", "preAuthTx", "sha256Hash"`);
        }
        data  = Buffer.from(data);
        let versionBuffer = Buffer.from([versionByte]);
        let payload       = Buffer.concat([versionBuffer, data]);
        let checksum      = calculateChecksum(payload);
        let unencoded     = Buffer.concat([payload, checksum]);
        return base32.encode(unencoded);
    }
    static decodeCheck(versionByteName, encoded) {
        if (!isString(encoded)) {
          throw new TypeError("encoded argument must be of type String");
        }
        let decoded     = base32.decode(encoded);
        let versionByte = decoded[0];
        let payload     = decoded.slice(0, -2);
        let data        = payload.slice(1);
        let checksum    = decoded.slice(-2);
        if (encoded != base32.encode(decoded)) {
          throw new Error("invalid encoded string");
        }
        let expectedVersion = versionBytes[versionByteName];
        if (isUndefined(expectedVersion)) {
          throw new Error(`${versionByteName} is not a valid version byte name.  expected one of "accountId" or "seed"`);
        }
        if (versionByte !== expectedVersion) {
          throw new Error(`invalid version byte. expected ${expectedVersion}, got ${versionByte}`);
        }
        let expectedChecksum = calculateChecksum(payload);
        if (!verifyChecksum(expectedChecksum, checksum)) {
          throw new Error(`invalid checksum`);
        }
        return Buffer.from(data);
    } 
}
function calculateChecksum(payload) {
  // This code calculates CRC16-XModem checksum of payload
  // and returns it as Buffer in little-endian order.
  let checksum = Buffer.alloc(2);
  checksum.writeUInt16LE(crc.crc16xmodem(payload), 0);
  return checksum;
}
//测试使用
let newKeypair = new Keypair();
console.log(newKeypair.publicKey);
let newPublic = Keypair.encodeCheck("ed25519PublicKey",newKeypair.publicKey);
let newPrivate = Keypair.encodeCheck("ed25519SecretSeed",newKeypair.privateKey);
let publicBuffer = Keypair.decodeCheck("ed25519PublicKey",newPublic);
console.log(newPublic,newPrivate);
console.log(publicBuffer);
说明

相关包的详细api可以直接复制包名字在github查找

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/24357.html

相关文章

  • 2021年,用更现代方法使用PGP(中)

    摘要:世界上有两种密码一种是防止你的小妹妹偷看你的文件另一种是防止当局阅读你的文件应用密码学上篇链接年,用更现代的方法使用上三安全使用和备份准备为了安全性,建议在一台断网的或者系统上生成你的密钥对。世界上有两种密码:一种是防止你的小妹妹偷看你的文件;另一种是防止当局阅读你的文件.​ ...

    Tecode 评论0 收藏0
  • Linux 系统服务器设置 SSH 通过密钥登录

    摘要:系统服务器的登录方式最常见的有两种通过用户密码登录或者采用密钥对登录。服务器打开密钥登录功能编辑文件,进行如下设置阻止用户通过登录以密钥方式登录下下当你完成全部设置,并以密钥方式登录成功后,再禁用密码登录最后,重启服务Linux 系统服务器的SSH登录方式最常见的有两种:通过用户密码登录或者采用密钥对登录。其中使用用户密码方式登录,容易有密码被暴力破解的问题。为了安全,可以使用 1Passw...

    Tecode 评论0 收藏0
  • 剥开比原看代码10:比原是如何通过/create-key接口创建密钥

    摘要:如果传的是,就会在内部使用默认的随机数生成器生成随机数并生成密钥。使用的是,生成的是一个形如这样的全球唯一的随机数把密钥以文件形式保存在硬盘上。 作者:freewind 比原项目仓库: Github地址:https://github.com/Bytom/bytom Gitee地址:https://gitee.com/BytomBlockc... 在前一篇,我们探讨了从浏览器的dashb...

    ccj659 评论0 收藏0
  • Bytom国密网说明和指南

    摘要:在比原链主网中,在获取交易和区块头等摘要的过程中使用的哈希算法是算法,而在国密测试网中,使用算法替代。启动的是国密测试网。可以说,比原链的项目进展伴随着国密测试网的发布更上一层楼。 比原项目仓库: Github地址:https://github.com/Bytom/bytom Gitee地址:https://gitee.com/BytomBlockc... 国密算法是指国家密码管理局制...

    王岩威 评论0 收藏0
  • 剥开比原看代码04:如何连上一个比原节点

    摘要:总的来说,在比原中有一个类,它用于集中处理节点与外界交互的逻辑,而它的创建和启动,又都是在中进行的。我考虑的是这样一种情况,比如某用户在笔记本上运行比原节点,然后在公开场合上网,使用了黑客提供的。 作者:freewind 比原项目仓库: Github地址:https://github.com/Bytom/bytom Gitee地址:https://gitee.com/BytomBloc...

    BigNerdCoding 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<