Daniel J. Bernstein 是世界著名的密码学家javascript
彻底开放设计,算法各个参数直接了当,明确,很大的几率经过缓存、时间、恶意输入摧毁安全性,而 25519 系列椭圆曲线通过特别设计,尽量的将出错的几率降到了最低,25519 系列曲线是目前最快的椭圆曲线加密算法,一个4核2.4GHz 的 Westmere cpu,每秒能够验证 71000 个签名,吊打同类:椭圆曲线是 NISTjava
公共钥只有32字节,私钥只有64字节node
经过tweetnacl生成原始的Uint8Array密钥对,生成公钥,私钥类型首字母G,S写入Buffer,而后私钥写入Buffer,经过上面Buffer计算校验码再次写入buffer,最后使用base32编码。生成用户常规保存的字符串。git
npm I tweetnacl crc lodash base32.js —save
解释简单解释说明下包的做用
tweetnacl: 最核心的包,是用javascript接口实现的TweetNaci/Naci端口,它实现了密钥加密解密,公钥验证加密,公共签名,hash等。咱们将使用这个库生成,原始的Uint8Array密钥对。也能够本身随机一个64byte私钥,而后解析为keypair。
crc:生成校验码的
lodash:是一个一致性、模块化、高性能的 JavaScript 实用工具库。
base32.js:因为原生方法,只有base64,因此引入base32.js进行编码解码github
//各类引入 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查找算法