Windows下以太坊公钥加密功能python实现

2023-05-16

文章目录

      • 一、什么是公钥、私钥、地址
      • 二、实现过程
        • 1、从keystore文件中解出私钥以及私钥->公钥->地址
        • 2、利用公钥进行消息加密/解密

一、什么是公钥、私钥、地址

  • 私钥:32字节(256位),私钥需要保管和隐蔽(非公开)(截取《以太坊技术详解与实战》)
  • 公钥:(由私钥生成)64字节(512位),公钥是公开的,不需要保密(截取《以太坊技术详解与实战》)
  • 地址:20字节(160位),要注意,我们使用最多的地址并不等同于公钥

地址的生成过程:

从私钥得到一个512位(64字节)的公钥之后,将公钥进行sha3加密,然后将加密后的前44字节去掉,保留剩下的160位二进制数(20字节)
将该20字节编译成长度为40的十六进制字符串,即地址。

具体如下:
在这里插入图片描述

二、实现过程

从上面地址的生成过程中可以看到,使用到的两个加密函数主要是secp256k1和sha3(也就是上面的keccak-256),那么要找python中实现这两个函数的模块。

web3.py中已经有keccak-256的实现,故不需要再另寻。
而实现secp256k1的模块是:eth_keys->安装pip install eth_keys
另外,进行公钥加密可以使用模块:eciespy->安装pip install eciespy

所以模块准备
web3.py
pip install eth_keys
pip install eciespy

1、从keystore文件中解出私钥以及私钥->公钥->地址

(1) keystore文件夹在我们创建创世区块的文件中"./data"下
在这里插入图片描述
keystore文件夹存放的文件是与账户私钥相关的加密信息,文件由personal.newAccount()函数执行后创建。

先读取文件信息:

with open(
    r"E:\PycharmProjects\btc\data\keystore\UTC--2021-03-23T07-27-44.500405400Z--a46c666d76e5c044cd8d6b21d3cdf76d5571f48e",
    "r") as f:
self.encrypted_key = f.read()

(2) 从self.encrypted_key中解出私钥:

# 这里需要引入web3.py中管理账户的模块
from web3 import Account
# 从keystore中获取私钥privatekey,需要输入密码(注意这里的密码并不是私钥)
self.privatekey = Account.decrypt(self.encrypted_key,"123")
print(self.privatekey)

(3) 引入eth_keys模块中的keys,从私钥中解出公钥

from eth_keys import keys
# 先创建keys模块下的私钥对象
priv_key = keys.PrivateKey(self.privatekey)
print("priv_key:",priv_key)
# 再解出公钥
self.public_key = priv_key.public_key
print("公钥:",self.public_key)
# 这里的公钥是64字节,是压缩的
print("公钥长度:",len(str(self.public_key)))

(4) 使用web3.py自带的keccak实现从公钥中得出地址

# 对公钥使用SHA3加密算法
sha3_pub_key = Web3.keccak(hexstr=str(self.public_key))
print("sha3_pub_key",sha3_pub_key)
# 取后20个字节
print('从公钥生成地址:',Web3.toHex(sha3_pub_key[-20:]))

完整代码如下:

import json
from web3 import Web3, Account, HTTPProvider
# 用于解密
from functools import wraps
from eth_account.messages import encode_defunct

from eth_keys import keys
from eth_utils import decode_hex
# 用于数字加密
import ecies


class ethereumHandler_OP():
    # 类级变量
    myPrivateKey = None
    myPublicAddr = None
    iflogin = None

    """初始化连接以太坊私链"""

    def __init__(self):
        self.web3 = Web3(HTTPProvider("http://localhost:8545"))
        # 检查是否连接成功
        if self.web3.eth.getBlock(0) is None:
            print("Failed to connect!")
        elif self.web3.isConnected():
            print("Successfully connected")

    def PrivateKey_PublicKey_Address(self):
        # 读取keystore文件
        with open(
                r"E:\PycharmProjects\btc\data\keystore\UTC--2021-03-23T07-27-44.500405400Z--a46c666d76e5c044cd8d6b21d3cdf76d5571f48e",
                "r") as f:
            self.encrypted_key = f.read()
        # 可以看到keystore中存储的是json格式的数据
        print("读取到的keystore文件中的信息:", self.encrypted_key)
        # 从keystore中获取私钥privatekey,需要输入密码(注意这里的密码并不是私钥)
        self.privatekey = Account.decrypt(self.encrypted_key, "123")
        print("私钥:", self.privatekey)
        # 先创建keys模块下的私钥对象
        priv_key = keys.PrivateKey(self.privatekey)
        print("priv_key:", priv_key)
        # 再解出公钥
        self.public_key = priv_key.public_key

        print("公钥:", self.public_key)
        # 这里的公钥是64字节,是压缩的
        print("公钥长度:", len(str(self.public_key)))
        # 对公钥使用SHA3加密算法
        sha3_pub_key = Web3.keccak(hexstr=str(self.public_key))
        print("sha3_pub_key", sha3_pub_key)
        # 取后20个字节
        print('从公钥生成地址:', Web3.toHex(sha3_pub_key[-20:]))


if __name__ == "__main__":
    eth = ethereumHandler_OP()
    eth.PrivateKey_PublicKey_Address()
    # encrypted_msg = eth.encryptMsg("Hello,world!11")
    # print(eth.decryptMsg(encrypted_msg))
    # eth.test()

在这里插入图片描述

D:\Python\Python38\python.exe E:/PycharmProjects/区块链项目/testkey.py
Successfully connected
读取到的keystore文件中的信息: {"address":"a46c666d76e5c044cd8d6b21d3cdf76d5571f48e","crypto":{"cipher":"aes-128-ctr","ciphertext":"55551ee6575f4e77e387b6c6eff10a6fc6da013898dcaa93dd1d70901437d14b","cipherparams":{"iv":"5807c666aa3bc267aa4504f42f09ced6"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"353b7a1d3ba4079493b222762b58e4b2c06cdb41ba770ab32441b063784e8858"},"mac":"bfcbaca3dbd199224251e97a77319d919b7ecace290dde1bec49ba275244e01c"},"id":"73f1b676-62e9-4e34-8e0d-5d9639d8e8b9","version":3}
私钥: b'\xa1\xd0\xf3\xdd\xbb\xfc\xc2W\xc0j\xdf\xb5\xc0\xcf\x96pL\xb7\xfd\xab\xa6 \xbc\x89%\x14\x9c%\xfd\x8b\x85i'
priv_key: 0xa1d0f3ddbbfcc257c06adfb5c0cf96704cb7fdaba620bc8925149c25fd8b8569
公钥: 0xc46d2b24d58ac4f1c8e50246cfbcb32fac785dba1376d13ffb712b022135e513020df7fa655b75197c24687b268d2f14cea382ca9f52ef392ab2e0f1734094da
公钥长度: 130
sha3_pub_key b'\x97x\xf2\x01c\x12\x8e%\xe0Z9\x84\xa4lfmv\xe5\xc0D\xcd\x8dk!\xd3\xcd\xf7mUq\xf4\x8e'
从公钥生成地址: 0xa46c666d76e5c044cd8d6b21d3cdf76d5571f48e

Process finished with exit code 0

2、利用公钥进行消息加密/解密

使用eciespy模块,在上面class ethereumHandler_OP类中加入函数:

import ecies
class ethereumHandler_OP():
	#...此处省略上面所有函数
	def encryptMsg(self,_msg):
        '''
        params:_msg必须是字节bytes类型,由b''定义的字符串
        '''
        encrypted_msg = ecies.encrypt(self.public_key.to_hex(),bytes(_msg,encoding='utf8'))
        return encrypted_msg

    def decryptMsg(self,_encryptedmsg):
        #private_hex = Web3.toHex(self.privatekey)
        recovered_msg = ecies.decrypt(self.privatekey,_encryptedmsg)
        return recovered_msg

(1)试着对“Hello World!11进行加密”

if __name__ == "__main__":
    eth = ethereumHandler_OP()
    eth.PrivateKey_PublicKey_Address()
    # 调用加密解密函数
    encrypted_msg = eth.encryptMsg("Hello,world!11")

在这里插入图片描述
(2)然后就是解密:

if __name__ == "__main__":
    eth = ethereumHandler_OP()
    eth.PrivateKey_PublicKey_Address()
    # 调用加密解密函数
    encrypted_msg = eth.encryptMsg("Hello,world!11")
    print("加密信息如下:",encrypted_msg)
    print("解密信息:",eth.decryptMsg(encrypted_msg))
    #eth.test()

在这里插入图片描述
以上是以太坊实现公钥加密的过程。

完整代码如下:

import json
from web3 import Web3, Account, HTTPProvider

# 用于解密
from functools import wraps
from eth_account.messages import encode_defunct

from eth_keys import keys
from eth_utils import decode_hex

# 用于数字加密
import ecies


class ethereumHandler_OP():
    # 类级变量
    myPrivateKey = None
    myPublicAddr = None
    iflogin = None

    """初始化连接以太坊私链"""

    def __init__(self):
        self.web3 = Web3(HTTPProvider("http://localhost:8545"))
        # 检查是否连接成功
        if self.web3.eth.getBlock(0) is None:
            print("Failed to connect!")
        elif self.web3.isConnected():
            print("Successfully connected")

    def PrivateKey_PublicKey_Address(self):
        # 读取keystore文件
        with open(
                r"E:\PycharmProjects\btc\data\keystore\UTC--2021-03-23T07-27-44.500405400Z--a46c666d76e5c044cd8d6b21d3cdf76d5571f48e",
                "r") as f:
            self.encrypted_key = f.read()
        # 可以看到keystore中存储的是json格式的数据
        print("读取到的keystore文件中的信息:", self.encrypted_key)
        # 从keystore中获取私钥privatekey,需要输入密码(注意这里的密码并不是私钥)
        self.privatekey = Account.decrypt(self.encrypted_key, "123")
        print("私钥:", self.privatekey)
        # 先创建keys模块下的私钥对象
        priv_key = keys.PrivateKey(self.privatekey)
        print("priv_key:", priv_key)
        # 再解出公钥
        self.public_key = priv_key.public_key

        print("公钥:", self.public_key)
        # 这里的公钥是64字节,是压缩的
        print("公钥长度:", len(str(self.public_key)))
        # 对公钥使用SHA3加密算法
        sha3_pub_key = Web3.keccak(hexstr=str(self.public_key))
        print("sha3_pub_key", sha3_pub_key)
        # 取后20个字节
        print('从公钥生成地址:', Web3.toHex(sha3_pub_key[-20:]))

    def encryptMsg(self, _msg):
        '''
        params:_msg必须是字节bytes类型,由b''定义的字符串
        '''
        encrypted_msg = ecies.encrypt(self.public_key.to_hex(), bytes(_msg, encoding='utf8'))
        return encrypted_msg

    def decryptMsg(self, _encryptedmsg):
        # private_hex = Web3.toHex(self.privatekey)
        recovered_msg = ecies.decrypt(self.privatekey, _encryptedmsg)
        return recovered_msg

    def signtMsg(self, _msg):
        print("original msg:", _msg)
        # 构造加密前的数据体
        premsg = encode_defunct(text=_msg)
        print("预准备的数据体:", premsg)
        signedmsg = Account.sign_message(premsg, self.privatekey)
        print("签名后的信息:", signedmsg)

    def vertifyMsg(self, _signedmsg):
        print(Account.recover_message("Hello,world!", ))

    def test(self):
        private_1 = '0xa1d0f3ddbbfcc257c06adfb5c0cf96704cb7fdaba620bc8925149c25fd8b8569'
        public_1 = '0xc46d2b24d58ac4f1c8e50246cfbcb32fac785dba1376d13ffb712b022135e513020df7fa655b75197c24687b268d2f14cea382ca9f52ef392ab2e0f1734094da'
        print(len(public_1))
        address_1 = '0xa46c666d76e5c044cd8d6b21d3cdf76d5571f48e'
        encryptmsg = ecies.encrypt(public_1, b'hello,world!')
        print("加密的信息:", encryptmsg)
        decryptmsg = ecies.decrypt(private_1, encryptmsg)
        print("解密的信息:", decryptmsg)


if __name__ == "__main__":
    eth = ethereumHandler_OP()
    eth.PrivateKey_PublicKey_Address()
    # 调用加密解密函数
    encrypted_msg = eth.encryptMsg("Hello,world!11")
    print("加密信息如下:",encrypted_msg)
    print("解密信息:",eth.decryptMsg(encrypted_msg))

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Windows下以太坊公钥加密功能python实现 的相关文章

随机推荐

  • 在Python中使用print输出时,出现UnicodeEncodeError错误,错误提示为“‘gbk‘ codec can‘t encode character ‘\u2022‘ in posit

    利用chatgpt一步步解决了这个问题 xff0c 感觉ChatGPT还是太强大了 问题描述 xff1a 在Python中使用print输出时 xff0c 出现UnicodeEncodeError错误 xff0c 错误提示为 39 gbk
  • openstack一些特性资料

    Keystone RBAC nova compute Cells Bare Metal Compute 是什么东西 xff1f http wiki openstack org blueprint nova compute cells htt
  • 【神经网络和深度学习-开发案例】 第二章 神经网络结构

    神经网络和深度学习 第二章 神经网络结构 案例 xff1a 使用神经网络识别手写数字 我将介绍一个神经网络 xff0c 它可以很好地对手写的数字进行分类 为了准备这一点 xff0c 它有助于解释一些术语 xff0c 让我们可以命名一个网络的
  • 2000页kubernetes操作手册,内容详细代码清晰,小白也能看懂

    现如今 xff0c Kubernetes业务已成长为新时代的IT基础设施 xff0c 并成为高级运维工程师 架构师 后端开发工程师的必修技术栈 毫无疑问 xff0c Kubernetes是云计算发展演进的一次彻底革命性的突破 xff0c 只
  • FreeRTOS代码阅读笔记:heap_4.c

    FreeRTOS中对于内存的管理当前一共有5种实现方式 xff08 作者当前的版本是10 1 1 xff09 xff0c 均在 Source portable MemMang 下面 xff0c 这里笔记下 heap 4 c和第二种方式比较相
  • (1)touchgfx 添加时钟控件

    第一步 xff1a 新建空白模版 添加图片 xff1a 放入 链接 xff1a https pan baidu com s 1NI6LUYrTUs64Z2jZE6AAQQ 提取码 xff1a 2odw 添加控件 xff1a 位置部件属性1T
  • 【基于51】红外寻迹智能小车 - 代码篇

    文章目录 前言一 准备工作二 使用步骤1 模块化编程2 电机模块3 小车动作模块4 PWM 和定时器 中断系统5 寻迹逻辑 总结 前言 关于硬件部分可以看我上次写的帖子https blog csdn net ZER00000001 arti
  • C++关键字override

    一 什么是override override的翻译是覆盖 实际上它在C 43 43 中可以检测哪些虚函数没有被重写并报错 注 xff1a 在派生类的成员函数中使用override时 xff0c 如果基类中无此函数 xff0c 或基类中的函数
  • 邻接矩阵和邻接表

    图的概述和存储结构 xff08 一 xff09 文章目录 前言一 图的概述1 xff09 图的分类2 xff09 图的要素 二 图的存储结构三 邻接矩阵四 邻接表 前言 有一种说法是程序是由数据结构和算法组成的 xff0c 这很能体现出数据
  • 图解迪杰斯特拉(Dijkstra)最短路径算法

    往期文章目录 干货满满 xff01 最小生成树 Prim算法 最小生成树 Kruskal算法 目录 前言 一 最短路径的概念及应用 二 Dijkstra迪杰斯特拉 1 什么是Dijkstra 2 逻辑实现 总结 前言 无论是什么程序都要和数
  • Vscode配置Git+快速入门,一篇学会80%的Git操作

    前言 团队开发中经常会用到Git xff0c 能极大简化开发的流程 xff0c 而个人开发也可以利用Git管理自己的代码 同样作为一个初学者 xff0c 我在学完Git之后写下这篇文章总结个人走过的坑 xff0c 大家一起进步 Git下载和
  • 【C++11】三大神器之——智能指针

    文章目录 前言 一 智能指针的原理1 RAII机制2 简单的实现 二 智能指针的用法1 智能指针的分类2 unique ptr基本语法 3 shared ptr基本语法 4 删除器5 weak ptr 前言 一 智能指针的原理 1 RAII
  • 【C++11】三大神器之——右值、移动语义、完美转发

    前言 如果你还不知道C 43 43 11引入的右值 移动语义 完美转发是什么 xff0c 可以阅读这篇文章 xff1b 如果你已经对这些知识了如指掌 xff0c 也可以看看有什么可以补充 x1f60f 一 右值 值类别vs变量类型 在正式认
  • 【C++11】三大神器之——包装器和绑定器

    前言 如果你还不知道 C 43 43 11 引入的包装器和绑定器是什么 xff0c 可以读读这篇文章 xff0c 看看有什么 启发 xff1b 如果你已经对包装器和绑定器了如指掌 xff0c 也可以读读这篇文章 xff0c 看看有什么 补充
  • 【神经网络和深度学习-开发案例】第四章 神经网络如何对数字进行分类

    神经网络和深度学习 第四章 神经网络如何对数字进行分类 案例 xff1a 使用神经网络识别手写数字 好了 xff0c 让我们来写一个程序 xff0c 学习如何识别手写的数字 xff0c 使用随机梯度下降和MNIST的训练数据 我们将用一个简
  • Win7下安装Ubuntu(双硬盘)的简要步骤

    0 硬件准备 一个至少4G大小的U盘 xff0c 用于刻录Ubuntu系统并安装 1 下载Ubuntu镜像及刻录 Ubuntu镜像 Ubuntu镜像可从官网下载 xff08 外网 xff0c 速度太慢 xff09 xff0c 或使用国内镜像
  • C++ Primer Plus拾遗

    本博文整理了C 43 43 Primer Plus前六章中的部分知识点 xff0c 一般为不常用的小技巧或基础概念性的内容 C与C 43 43 的语言特性 C语言特性 结构化编程 xff08 Structured Programming x
  • 时隔一年,对全国大学生智能车竞赛做段总结(五)

    早期粗糙的赛道元素处理 说这个没有别的意思 xff0c 就是觉得 xff0c 遇到实际应用上的问题 xff0c 虽然脑海里的知识技巧并不能让我们有多高明的手法去解决这个问题 xff0c 但也要努力去尝试 元素判断 这里的元素判断也是粗糙的
  • Windows7 VMware USB Arbitration Service启动失败解决

    转自 http huxiaodan666 blog 163 com blog static 162090542201091014749373 前几日安装了Windows7 xff0c 不过vmware虚拟机安装之后却无法使用usb 软件是官
  • Windows下以太坊公钥加密功能python实现

    文章目录 一 什么是公钥 私钥 地址二 实现过程1 从keystore文件中解出私钥以及私钥 gt 公钥 gt 地址2 利用公钥进行消息加密 解密 一 什么是公钥 私钥 地址 私钥 xff1a 32字节 xff08 256位 xff09 x