其他分享
首页 > 其他分享> > 区块链是如何应用非对称加密技术的

区块链是如何应用非对称加密技术的

作者:互联网

区块链是如何应用非对称加密技术的呢?

在百度搜索这个问题,除了广告,大多都是解释非对称加密原理的文章,暂时没有发现讲解区块链是如何使用非对称加密技术的。

知乎搜了一下,找到一个该问题的提问,但目前还没有回答。

好吧,我也似懂非懂,模棱两可,这个问题该怎么解决呢?

 

看源代码!

 

于是,我找了一个区块链的项目,找到了非对称加密这部分的代码,接下来,结合代码,讲解一下区块链是如何应用非对称加密的。

 

 

以 Python 代码为例,我们先看主要函数。

def client ( a, m, f, t, p ):
    if a:
        if a == "n":
            public_key, private_key = generate_ECDSA_keys()
            click.echo("")
            click.echo("address:{0}".format(public_key))
            click.echo("")
            click.echo("private_key:{0}".format(private_key))
            click.echo("")
            print("ok!")
        if a == "s":
            if ( m and f and t and p ):
                print(send_transaction(f, t, m, p))

这一部分是生成一个公钥和私钥。公钥和私钥是非对称加密中的一对密钥,但公钥是公开的,私钥是私自持有的。经公钥加密后的密文,可以通过私钥解开。

 

公钥是全范围广播发布的。打个比方,公钥类似于银行卡号,私钥就类似于银行卡密码。

 

也就是说,公钥也可以理解为一个地址,私钥理解为这个地址的密码。

 

我们先看公钥和私钥的生成函数。

def generate_ECDSA_keys():
    sk = ecdsa.SigningKey.generate(curve=ecdsa.SECP256k1) 
    private_key = sk.to_string().hex() 
    vk = sk.get_verifying_key() 
    public_key = vk.to_string().hex()
    public_key = base64.b64encode(bytes.fromhex(public_key))
    return public_key.decode(),private_key

 

可以看出,sk 是一个签名,私钥 pricate_key 是通过签名转化而来。

其中,这句代码表示公钥是由私钥得出的。

vk = sk.get_verifying_key()

 

是怎么得出的呢?我们看看 get_verifying_key 函数。

def get_verifying_key(self):
    """
    Return the VerifyingKey associated with this private key.
    Equivalent to reading the `verifying_key` field of an instance.
    :return: a public key that can be used to verify the signatures made
        with this SigningKey
    :rtype: VerifyingKey
    """

 

可以看出,这个函数的返回值是指:

A public key that can be used to verify the signatures made with this SigningKey

一个可验证使用此签名密钥生成签名的公钥。

 

因此,应该能够明白私钥和公钥的产生原理了吧。

 

generate_ECDSA_keys 函数输出的内容类似如下:

address:Z/qsNWOAAWULpqvtM/OMHmJE+6PG0oPUsOMGk2ySYgrUB5noaZsD6b0NbbPgslr1cdninkqYKcJ+sx74/Mhn2A==
private_key:196f72bf05e307458a0691ca73a2981d859e499ef9fc264183feddde5bd47217

地址(公钥)跟私钥。

 

接下来,需要启节点,查看区块链的信息。

if __name__ == '__main__':
    make_a_genesis_block()
    parser = ArgumentParser()
    parser.add_argument('-p', '--port', default=8080, type=int, help='port to listen on')
    args = parser.parse_args()
    port = args.port
    app.run(debug=True, host='0.0.0.0', port=port)

 

然后,根据如下代码,使用签名,发送消息上链。-f 是发送消息的节点地址,-t 是接收信息的节点地址,-p 是私钥。

@click.option('-f', help='from address')
@click.option('-t', help='to address')
@click.option('-p', help='private_key')

 

然后,我们具体看看如何上链的。

if a == "s":
    if ( m and f and t and p ):
        print(send_transaction(f, t, m, p))

 

可以看出,send_transcation 函数是对消息进行上链的函数,即发送交易信息函数,接下来我们进入这个函数。

 
def send_transaction(from_address, to_address, memo, private_key, private_key_own):
    if private_key == private_key_own:
        signature, message = sign_ECDSA_msg(private_key)
        url = "http://localhost:8080/post"
        d = {"from_address": from_address, "to_address": to_address,"memo":memo,
             "signature":signature,"message":message}
        r = requests.post(url, data=d)
        return r.text
    else:
        return ("Wrong address or key length! Verify and try again.")

 

大体分析一下这个函数的设计思想。

    if private_key == private_key_own:

这里就是验证接收到的私钥与所持有的私钥是否吻合的环节。如果不吻合,直接跳到 else,无法进行上链操作。

 

如果吻合,则 sign_ECDSA_msg 函数执行。

 

当私钥 private_key 解开加密信息后,会产生 signature 和 message,即签名与信息。那么私钥解密的函数,就是 sign_ECDSA_msg 这个函数。进一步地,我们进入这个函数,看看私钥是如何解密的。

def sign_ECDSA_msg(private_key):
    message = str(round(time()))
    bmessage = message.encode()
    sk = ecdsa.SigningKey.from_string(bytes.fromhex(private_key), 
                                      curve=ecdsa.SECP256k1)
    signature = base64.b64encode(sk.sign(bmessage))
    return signature, message

 

我们看到,message 是得到一个时间序列。这里边的核心函数是 from_string 函数,这是引入的第三方库里的函数,我们看一下这个函数的解释。

def from_string(cls, string, curve=NIST192p, hashfunc=sha1):
    """
    Decode the private key from :term:`raw encoding`.
    Note: the name of this method is a misnomer coming from days of
    Python 2, when binary strings and character strings shared a type.
    In Python 3, the expected type is `bytes`.
    :param string: the raw encoding of the private key
    :type string: bytes like object
    :param curve: The curve on which the point needs to reside
    :type curve: ecdsa.curves.Curve
    :param hashfunc: The default hash function that will be used for
        signing, needs to implement the same interface
        as hashlib.sha1
    :type hashfunc: callable
    :raises MalformedPointError: if the length of encoding doesn't match
        the provided curve or the encoded values is too large
    :raises RuntimeError: if the generation of public key from private
        key failed
    :return: Initialised SigningKey object
    :rtype: SigningKey
    """

 

可以看出,输入的是密钥,输出的是一个签名,具体是什么签名,这里不用深入研究,因为这个输出还会输入到下一个函数 b64encode 函数。进一步地,我们看看这个函数的作用。

def b64encode(s, altchars=None):
    """Encode the bytes-like object s using Base64 and return a bytes object.
    Optional altchars should be a byte string of length 2 which specifies an
    alternative alphabet for the '+' and '/' characters.  This allows an
    application to e.g. generate url or filesystem safe Base64 strings.
    """

 

可以看出,这是一个对字节编码的函数。也就是说,通过 sign_ECDSA_msg 函数得到了存储信息和签名。

 

然后,在 send_transcation 中,对 sign_ECDSA_msg 函数得到的信息进行上链,节点是 8080。

 

就这样,区块链中的公钥、私钥以及非对称加密技术的工作机制,就能理清了。

 

当然,这个代码比较简单,介绍的最基础的区块链原理,大家在学习的过程中也可以循序渐进,了解更复杂的区块链技术。

标签:公钥,私钥,函数,address,private,key,链是,区块,加密技术
来源: https://blog.csdn.net/XYlittlework/article/details/115560301