首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >创建数字钱包(一)

创建数字钱包(一)

作者头像
lambeta
发布于 2019-01-28 09:03:37
发布于 2019-01-28 09:03:37
1.3K00
代码可运行
举报
文章被收录于专栏:编舟记编舟记
运行总次数:0
代码可运行

椭圆曲线数字签名算法生成私钥

Secp256k1 通过椭圆曲线数字签名算法生成私钥和公钥,其中SEC(Standards for Efficient Cryptography)是专门利用ECDSA或者其可选项Schnorr算法来产生高效的加密方法。 特点是生成密钥很快。

Scep256k1 基本特性

  • secp256k1 ECDSA signing/verification and key generation.
  • Adding/multiplying private/public keys.
  • Serialization/parsing of private keys, public keys, signatures.
  • Constant time, constant memory access signing and pubkey generation.
  • Derandomized DSA (via RFC6979 or with a caller provided function.)
  • Very efficient implementation.

讲解代码

步骤

  1. 生成私钥
  2. 加密私钥
  3. 生成 keyObject 对象
  4. 从keyObject对象中恢复私钥

生成私钥

下面利用 keythereum[1] 产生符合以太坊的密钥,并产生keyObject文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const params = { keyBytes: 32, ivBytes: 16 };
let {privateKey, salt, iv} = keythereum.create(params);

keythereum可以产生私钥,以及后面加密私钥所用的PBKDF2算法需要的salt,和加密aes-128-ctr私钥的iv值。

得到私钥之后,我们可以通过私钥生成公钥。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let privateKeyBuffer = Buffer.from(privateKey, "hex") // or "base64"
let publicKey = secp256k1.publicKeyCreate(privateKeyBuffer, false).slice(1);
let address = "0x" + keccak256(publicKey).slice(-20).toString("hex");

加密私钥

利用KDF算法基于password派生出密钥,然后利用这个密钥加密我们的私钥。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const password = "Hello,Ethereum"
const options = {
    kdf: "pbkdf2",
    cipher: "aes-128-ctr",
    kdfparams: {
        c: 262144,
        dklen: 32,
        prf: "hmac-sha256"
    }
};
const keyObject = keythereum.dump(password, privateKey, salt, iv, options);

这就是产生keyObject基本思路。我们在看看dump函数到底做了什么

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
this.marshal(this.deriveKey(password, salt, options), privateKey, salt, iv, options);

deriveKey(...) 的源码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
this.crypto.pbkdf2Sync(
        password,
        salt,
        options.kdfparams.c || this.constants.pbkdf2.c,
        options.kdfparams.dklen || this.constants.pbkdf2.dklen,
        prf //hmac-sha256
      );

这里基于password生成的derivedKey,这个密钥并不是我们要用的私钥,而是用来加密先前生成的privateKey的,加密的过程在marshal函数中调用的encrypt函数里。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let ciphertext = this.encrypt(privateKey, derivedKey.slice(0, 16), iv, algo).toString("hex");

encrypt函数,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var cipher, ciphertext;
algo = algo || this.constants.cipher;
if (!this.isCipherAvailable(algo)) throw new Error(algo + " is not available");

//加密过程
cipher = this.crypto.createCipheriv(algo, this.str2buf(key), this.str2buf(iv));
ciphertext = cipher.update(this.str2buf(plaintext));

return Buffer.concat([ciphertext, cipher.final()]);

此处的ciphertext代表的是privateKey,而key则是derivedKey

生成 keyObject 对象

得到了加密后的ciphertext之后,开始组装keyObject对象并返回。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
keyObject = {
      address: this.privateKeyToAddress(privateKey).slice(2),
      crypto: {
        cipher: options.cipher || this.constants.cipher,
        ciphertext: ciphertext,
        cipherparams: { iv: iv.toString("hex") },
        mac: this.getMAC(derivedKey, ciphertext)
      },
      id: uuid.v4(), // random 128-bit UUID
      version: 3
    };
keyObject.crypto.kdf = "pbkdf2";
      keyObject.crypto.kdfparams = {
        c: options.kdfparams.c || this.constants.pbkdf2.c,
        dklen: options.kdfparams.dklen || this.constants.pbkdf2.dklen,
        prf: options.kdfparams.prf || this.constants.pbkdf2.prf,
        salt: salt.toString("hex")
      };    

privateKeyToAddress(...)方法里首先通过privateKey产生publicKey,然后使用keccak256哈希publicKey得到地址。

具体实现如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let privateKeyBuffer = Buffer.from(privateKey);
let publicKey = secp256k1.publicKeyCreate(privateKeyBuffer, false).slice(1);
let address = "0x" + keccak256(publicKey).slice(-20).toString("hex");

keccak256(publicKey) 产生了32bytes,截取尾部20bytes转换成十六进制之后就是40字符,加上前导0x之后,就是42个字符的以太坊地址,比如:0x0f645438395206b408e52be4fcf4bc21c330bfa2

从keyObject对象中恢复私钥

有了keyObject和密码就可以恢复原来的私钥

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let privateKey = keythereum.recover(password, keyObject)

可以想到,recover方法中,首先会利用password和keyObject中的salt派生出当初的密钥derivedKey,然后把加密过的私钥ciphertext和derivedKey, iv作为原来加密算法aes-128-ctr的输入参数,成功解密后返回明文的私钥。

具体代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
verifyAndDecrypt(this.deriveKey(password, salt, keyObjectCrypto), salt, iv, ciphertext, algo)

这里首先得到了derivedKey,然后验证并解密kyeObject中的ciphertext,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function verifyAndDecrypt(derivedKey, salt, iv, ciphertext, algo) {
  var key;
  if (self.getMAC(derivedKey, ciphertext) !== keyObjectCrypto.mac) {
    throw new Error("message authentication code mismatch");
  }
  if (keyObject.version === "1") {
    key = keccak256(derivedKey.slice(0, 16)).slice(0, 16);
  } else {
    key = derivedKey.slice(0, 16);
  }
  return self.decrypt(ciphertext, key, iv, algo);
}

注意这里的mac值比较,确保了ciphertext没有被人篡改才有解密的必要。

参考实现

  1. NodeJS
  2. Bitcoin-core

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

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

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
科普|以太坊私钥存储文件
以太坊的私钥文件存储于数据目录(datadir指向或默认目录)下,对应的目录为keystore。所有的私钥文件都经过加密之后存储于此目录下。
程序新视界
2022/05/06
1.4K0
科普|以太坊私钥存储文件
用bc做国密sm2加解密、SM3withSM2签名验签等
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
全栈程序员站长
2022/09/30
2.7K0
以太坊钱包开发系列2 - 账号Keystore文件导入导出
以太坊去中心化网页钱包开发系列,点链接观看视频课程,将从零开始开发出一个可以实际使用的钱包,本系列文章是理论与实战相结合,一共有四篇:创建钱包账号、账号Keystore文件导入导出、展示钱包信息及发起签名交易、发送Token(代币),这是第二篇,主要介绍钱包账号导出与导入,将对Keystore文件的生成的原理进行介绍。
Tiny熊
2018/12/25
2.6K0
以太坊钱包开发系列2 - 账号Keystore文件导入导出
创建数字钱包(二)HD Wallet
BIP 全称是 Bitcoin Improvement Proposals,相当于互联网中RFC (Request for Comments),它是用来记录草案或者标准的。
lambeta
2019/01/28
2.3K0
区块链核心技术-密码学
大家好,首先感谢腾讯云提供云社区这样一个让技术人员沟通交流的平台,其次很高兴入驻到云+社区认识到大家,我是腾讯云TVP一员,专注于云计算、区块链、Web架构方向,myPagination作者,Github也开源了很多区块链的项目:https://github.com/linapex,有需要的朋友可以下载学习,本文是区块链技术实战系列的第二篇(不定期更新):
linapex
2019/03/22
12K0
区块链核心技术-密码学
知识分享之Golang——用于在Golang中的加解密工具类,包含MD5、RSA超长字符串、CBC、ECB等算法
知识分享之Golang篇是我在日常使用Golang时学习到的各种各样的知识的记录,将其整理出来以文章的形式分享给大家,来进行共同学习。欢迎大家进行持续关注。
cn華少
2022/05/13
1.2K0
ethereum-geth常用操作
--datadir: 数据存放目录,不指定默认:/home/$user/.ethereum
潇洒
2023/10/20
6380
以太坊交互工具
以太坊提供了Geth客户端用于管理API,我们可以在终端输入geth help查看其具体使用方法:
Al1ex
2021/07/21
2K0
以太坊交互工具
从零开发区块链应用(十一)--以太坊地址生成
PBKDF2(Password-Based Key Derivation Function)
Tiny熊
2022/02/22
1.5K0
金钱难寐,大盗独行——以太坊 JSON-RPC 接口多种盗币手法大揭秘
2010年,Laszlo 使用 10000 个比特币购买了两张价值25美元的披萨被认为是比特币在现实世界中的第一笔交易。
Seebug漏洞平台
2018/08/16
1.4K0
金钱难寐,大盗独行——以太坊 JSON-RPC 接口多种盗币手法大揭秘
C++ CryptoPP使用RSA加解密
Crypto++ (CryptoPP) 是一个用于密码学和加密的 C++ 库。它是一个开源项目,提供了大量的密码学算法和功能,包括对称加密、非对称加密、哈希函数、消息认证码 (MAC)、数字签名等。Crypto++ 的目标是提供高性能和可靠的密码学工具,以满足软件开发中对安全性的需求。RSA(Rivest-Shamir-Adleman)是一种非对称加密算法,由三位密码学家Ron Rivest、Adi Shamir和Leonard Adleman于1977年共同提出。RSA算法被广泛应用于信息安全领域,特别是在数字签名和密钥交换等场景中。
王 瑞
2023/12/01
1.8K0
C++ CryptoPP使用RSA加解密
攻防|浏览器凭据获取 -- Cookies && Password
简介:近几年流行多因素认证(MFA),个人认为也是以后的趋势;进入某些网站只拿到账号密码是不行的,这时就体现出cookie的重要性了,利用cookie绕过多因素认证在以后会经常用到,所以本文来简单的分析一下cookie获取和利用的思路;
亿人安全
2024/04/12
1.2K0
攻防|浏览器凭据获取 -- Cookies && Password
NodeJS模块研究 - crypto
这次研究下 nodejs 的 crypto 模块,它提供了各种各样加密算法的 API。这篇文章记录了常用加密算法的种类、特点、用途和代码实现。其中涉及算法较多,应用面较广,每类算法都有自己适用的场景。为了使行文流畅,列出了本文记录的几类常用算法:
心谭博客
2020/04/21
2.5K0
java之jce「建议收藏」
Java Cryptography Extension(JCE)是一组包,它们提供用于加密、密钥生成和协商以及 Message Authentication Code(MAC)算法的框架和实现。它提供对对称、不对称、块和流密码的加密支持,它还支持安全流和密封的对象。它不对外出口,用它开发完成封装后将无法调用。
全栈程序员站长
2022/07/05
2.6K0
【Android】Android加密和解密方式
不可逆加密算法的特征是加密过程中不需要使用密钥,输入明文后由系统直接经过加密算法处理成密文,这种加密后的数据是无法被解密的,只有重新输入明文,并再次经过同样不可逆的加密算法处理,得到相同的加密密文并被系统重新识别后,才能真正解密。 如信息摘要(Message Digest)和安全散列(Secure Hash)算法属于此类,常见的算法包括 MD5、SHA1、PBKDF2、bcrypt 等。 特点: 使用MD5和SHA进行加解密:
全栈程序员站长
2022/08/30
7430
Java中的加密与安全,你了解多少
  什么是数据安全?假如Bob要给Alice发送一封邮件,在发送邮件的过程中,黑客可能会窃取到邮件的内容,所以我们需要防窃听;黑客也有可能会篡改邮件的内容,所以Alice必须要有能有去识别邮件是否被篡改;最后,黑客也可能假冒Bob给Alice发送邮件,所以Alice还必须有能力识别出伪造的邮件。所以数据安全的几个要点就是:防窃听、防篡改和防伪造。 古代的加密方式:
程序员波特
2024/01/19
3050
Java中的加密与安全,你了解多少
NodeJS之加解密Crypto
就算原文件是纯英文内容,编码后内容也和原文完全不一样,普通人难以阅读但由于只有16个字符,听说一些程序员大牛能够记下他们的映射关系,从而达到读hex编码和读原文一样的效果。另外,数据在经过hex编码后,空间占用变成了原来的2倍。
前端LeBron
2021/12/27
1.9K0
NodeJS之加解密Crypto
HarmonyOS 开发实践——基于@ohos/crypto-js实现加解密工具箱
@ohos/crypto-js是一个根据crypto-js库移植的 鸿蒙 三方库,适配源库4.2.0版本,提供了一系列加密算法和安全工具,主要用于执行各种消息摘要计算和对称加解密操作。
小帅聊鸿蒙
2024/11/22
4090
加解密算法分析与应用场景
在日常开发中,无论是使用何种编程语言,我们都会遇到加解密的需求。例如,为了保护接口数据安全,我们需要对数据进行加密传输;在HTTPS协议中,通过非对称加密传输客户端私钥,然后双方使用该私钥进行对称加密通信;使用MD5算法进行文件一致性校验等。然而,面对众多的加解密方案,我们往往不清楚何时使用哪种方法。本文将为您梳理当前主流的加解密技术,并对算法进行科普性说明,但不涉及具体算法分析。根据日常应用场景,加解密技术大致可分为以下四类:
不惑
2024/05/13
7140
加解密算法分析与应用场景
Geth账户管理操作
以太坊是一个基于区块链技术的智能合约平台,它允许开发者构建去中心化应用程序(DApps)和智能合约,Geth是以太坊的一种节点软件,是以太坊网络的核心组件之一。在Geth中账户管理是非常重要的一个功能,它允许用户创建、导入、备份和管理自己的以太坊账户,本文将详细介绍如何在Geth中进行账户管理操作,包括创建新账户、导入已有账户、备份账户和查看账户余额等,如果你是以太坊开发者或者想要了解以太坊账户管理的相关知识,本文将为你提供有用的参考
Al1ex
2023/09/07
8220
Geth账户管理操作
相关推荐
科普|以太坊私钥存储文件
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档