Quantcast
Channel: CodeSection,代码区,网络安全 - CodeSec
Viewing all articles
Browse latest Browse all 12749

公链实战系列2――椭圆加密算法生成公钥、私钥

0
0

在系列1里面我们讲了Base58加密算法,今天我们来讲一讲钱包地址,也就是当你在使用比特币交易的时候的账户和密码(当然,区块链里面一般不这么叫) 总之,你理解就好。

在比特币中,公、私钥的生成采用的核心算法是椭圆加密算法(Elliptic curve cryptography)简称ECC, ECC是一种建立在公开密匙的算法,也就是非对称加密算法。 类似RSA、ElGamal算法等。 ECC被公认为在给定密钥长度下最安全的加密算法。(当然,最近随着量子计算的发展,对椭圆加密算法的安全也提出了质疑与挑战) 比特币中的公、私钥生成以及签名算法ECDSA都是基于ECC。 下面简单说一下ECC的原理,至于多ECC实现比较感兴趣的同学,可以直接去读源代码。椭圆加密算法的实现在本文中不是重点,本文主要讲解如何利用椭圆加密算法和前面提到的Base58生成地址。

公钥加密,也称为非对称加密。其是现在网络安全或者区块链信任的基础,公钥加密最大的特征就是通信双方各有一对公、私钥,这一对公、私钥有着千丝万缕的数学关系。 每个人都公开自己的公钥,保存自己的私钥。 正如前面提到的,由于是非对称加密,也就是说拿到公钥是没法解密的。公钥有以下几种使用场景:

公钥加密,私钥解密。 比如Tom给Magic写了一份信,他不想让其他人知道信的内容,于是用Magic的公钥对信的明文进行加密,将明文加密成了大家认不出的密文,之后通过网络发送给了Magic Magic收到密文之后,由于密是用自己的公钥加密的,所以只有Magic能够加密,因此Magic用自己的私钥对密文进行了解密,然后正确的读到了信的内容

上述过程中,即使窃听者拿到了密文的所有信息,以及Magic和Tom两个人的公钥,也没法读到信的内容,因为无法解密。

私钥加密、公钥解密

Tom写了一份公开声明的文件,她用自己的私钥对文件进行了加密,生成了密文,公布在自己的网站中。

Magic 下载了这份声明文件,并用Tom的公钥对密文进行了解密,正确读到了文件的内容

这个过程可能大家有点疑惑, 既然Tom对自己发布的文件进行了加密,他的公钥又是公开的,那为什么又让大家可以通过自己的公钥对密文进行解密呢? 其实这种使用场景主要是用于溯源。也就是验证文章的来源,通过用Tom公钥对密文的解密,我们就可以知道这份声明真的是Tom发出的,而不是伪造的。

接下来我们来看看,如何利用椭圆加密算法,生成公、私钥以及在比特币当中,如何生成一个有效的地址。

类似:

MR8ya3LGG3x2tJY8VjLB3JSesZrGvs

代码实现:

#!/usr/bin/env python # -*- coding:utf-8 -*- """ This Document is Created by At 2018/7/7 """ import hashlib from fastecdsa import keys, curve from crypto.base58 import base58encode, base58decode version = "0x" addressChecksumLen = 4 class Wallet: """ doc 钱包 """ def __init__(self): pass def new_keypair(self): """ 生成公私钥的键值对""" priv_key = keys.gen_private_key(curve.P256) pub_key = keys.get_public_key(priv_key, curve.P256) pub_key = "".join([str(pub_key.x), str(pub_key.y)]) return priv_key, pub_key def get_address(self): """ :return: """ priv_key, pub_key = self.new_keypair() pubkey_hash = self.hash_pk(pub_key) version_payload = "".join([str(version), str(pubkey_hash)]) checksum = self.checksum(version_payload) full_payload = "".join([str(version_payload), str(checksum)]) address = base58encode(full_payload) return address def hash_pk(self, pub_key): """ 公钥加密 :param pub_key: :return: """ if not isinstance(pub_key, (bytes, bytearray, str)): raise TypeError("pub 类型错误,需要str 或者bytes类型!") if isinstance(pub_key, str): pub_key = pub_key.encode("utf-8") # sha256 加密 pub_sha256 = hashlib.sha256(pub_key).hexdigest() # ripemd160 obj = hashlib.new("ripemd160", pub_sha256.encode('utf-8')) ripemd160_value = obj.hexdigest() return ripemd160_value def checksum(self, payload): """""" if not isinstance(payload, (bytes, bytearray, str)): raise TypeError("payload 类型错误,需要str 或者bytes类型!") if isinstance(payload, str): payload = payload.encode("utf-8") first_sha = hashlib.sha256(payload).hexdigest() second_sha = hashlib.sha256(first_sha.encode('utf-8')).hexdigest() return second_sha[:addressChecksumLen] def validate_addr(self, address): """ :return: """ pub_key_hash = base58decode(address) actural_check_sum = pub_key_hash[len(pub_key_hash) - addressChecksumLen:] version = pub_key_hash[0] pub_key_hash = pub_key_hash[1:len(pub_key_hash) - addressChecksumLen] payload = "".join([str(version), str(pub_key_hash)]) target_check_sum = self.checksum(payload) return actural_check_sum == target_check_sum

Viewing all articles
Browse latest Browse all 12749

Latest Images

Trending Articles





Latest Images