简介
本文主要参考了github上的这个项目。本文仅仅对字符串的情况进行了处理,因为发送的时候,公钥是公开的,而且以字符创的形式放入json的,广播到区块链的P2P网络上。
需要安装python的ecdsa库,终端输入命令:pip install ecdsa
即可。本文的基于python3.6
基本流程
寻找加密算法的过程竟然耗费了我一下午+一晚上,从寻找有关的库到具体实践,实在惭愧………不过好在终于明白了,也算是小有收获吧。
下图表示了整个流程。
符号说明:
- 矩形表示一个对象
- 圆角矩形表示对象的一个方法
- 没有箭头的实线表示一种对象与方法之间的联系
- 带有箭头的实线表示结果输出
- 带有箭头的虚线表示对象作为方法的参数输入
- 最后椭圆表示结果的真假
- SK表示私钥,VK表示公钥,message表示需要加密的信息,signature表示经过签名后的信息
从图中可以这么理解:SK是最核心的信息,也是必须要保密的信息。VK由SK经过椭圆加密算法产生,SK对消息进行签名处理,生成一个唯一的signature签名。VK的verify方法把signature和message作为参数输入,验证是否是SK加密的消息
代码
代码中注意下,所有的字符串进行加密或者验证的哈希计算时,都需要统一成UTF-8的编码格式,当然可以选择别的编码,但是必须要统一,否则会验证失败。产生的签名字符串是16进制的,可以自己转化。在发送交易信息的时候,我们仅仅需要发送vk的字符串和消息的字符串即可。加密算法的曲线可以自选,具体参考文档。
from ecdsa import SigningKey, NIST384p, VerifyingKey
def generate_key():
"""
产生公钥和私钥
:return: 二者组合
"""
sk = SigningKey.generate(curve=NIST384p)
vk = sk.get_verifying_key()
return vk, sk
def make_transaction(sk, message):
"""
加密交易
:param sk_string: 私钥,用于签名
:param message: 消息
:return: 签名
"""
signature = sk.sign(str(message).encode("utf8")) # 统一编码格式
return signature
def is_valid(vk_string, message, signature):
"""
验证交易是否合法
:param vk_string: 公钥的字符串
:param message: 消息
:param signature: 签名
:return: <bool> True合法,False不合法
"""
vk = VerifyingKey.from_string(vk_string, NIST384p)
try:
vk.verify(signature, str(message).encode("utf8")) # 统一编码格式
return True
except:
return False
message = "I am a transaction !"
vk, sk = generate_key() # 产生公钥和私钥
vk_string = vk.to_string()
sig = make_transaction(sk, message) # 模拟交易签名
print(type(sig)) # 仅仅是为了验证下数据格式
if is_valid(vk_string, message, sig):
print("True")
else:
print("False")