非对称加密 原理及实践

对称加密加密解密过程使用同一个密钥,在消息传递中,密钥也会被传来穿去,万一密钥被截获,那就完蛋了。

非对称加密过程中的密钥被分为私钥公钥

  • 公钥被用在加密阶段
  • 私钥被用在解密阶段

主要有两个应用场景:加密解密签名验签。典型的非对称加密算法有RSA。

1. 加密解密

假设B要和A秘密交流:

  1. A根据RSA算法生成了一个私钥、公钥对。公钥是公开的,任何人都可以知道,包括B;私钥只有A知道。
  2. B将自己想要对A说的明文使用A的公钥通过RSA加密,生成密文,发送出去。
  3. A接收到来自B的密文,使用自己的私钥通过RSA解密,生成明文。

此场景主要为了防止中间人截获信息,即使中间人截获到密文,就算他知道A的公钥,由于不知道A的私钥,还是无法知道密文啥意思。

Code Example :

# -*- coding: utf-8 -*-
import base64

from Crypto import Random
from Crypto.Cipher import PKCS1_v1_5
from Crypto.PublicKey import RSA


def generate_key_pair():
    """
    生成私钥公钥
    :return: 
    """
    rsa = RSA.generate(bits=1024, randfunc=Random.new().read)
    private_key = rsa.exportKey()
    public_key = rsa.publickey().exportKey()
    return private_key, public_key


def encrypt(plain_text, public_key):
    """
    根据公钥对原文加密
    :param plain_text: 
    :type plain_text: str
    :param public_key: 
    :return: 
    """
    pk = RSA.importKey(public_key)
    cipher = PKCS1_v1_5.new(pk)
    cipher_text = base64.b64encode(cipher.encrypt(plain_text.encode('utf-8')))
    return cipher_text


def decrypt(cipher_text, private_key):
    """
    根据私钥对密文进行解密
    :param cipher_text: 
    :type cipher_text: bytes
    :param private_key: 
    :return: 
    """
    pk = RSA.importKey(private_key)
    cipher = PKCS1_v1_5.new(pk)
    text = cipher.decrypt(base64.b64decode(cipher_text), Random.new().read)
    return text


if __name__ == '__main__':
    text = '我是一个好男人!'
    prk, puk = generate_key_pair()
    cipher_text = encrypt(text, puk)
    plain_text = decrypt(cipher_text, prk).decode('utf-8')
    print(plain_text)

Output

我是一个好男人!

2. 签名验签

假设B要确定A是A,而不是中间者伪造的:

  1. A根据RSA算法生成了一个私钥、公钥对。公钥是公开的,任何人都可以知道,包括B;私钥只有A知道。
  2. A使用自己的私钥对一段消息进行签名。
  3. B使用A的公钥对同一段消息进行验签,成功则证明A是A。

签名验签是为了解决中间人伪造A与B通信的问题。

Code Example:

# -*- coding: utf-8 -*-
import base64

from Crypto import Random
from Crypto.Hash import SHA
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5


def generate_key_pair():
    """
    生成私钥公钥
    :return: 
    """
    rsa = RSA.generate(bits=1024, randfunc=Random.new().read)
    private_key = rsa.exportKey()
    public_key = rsa.publickey().exportKey()
    return private_key, public_key


def sign(message, private_key):
    """
    根据私钥加签
    :param message: 
    :type message: str
    :param private_key: 
    :type private_key: bytes
    :return: 
    """
    pk = RSA.importKey(private_key)
    signer = PKCS1_v1_5.new(pk)
    digest = SHA.new()
    digest.update(message.encode('utf-8'))
    sign = signer.sign(digest)
    signature = base64.b64encode(sign)
    return signature


def verify(message, public_key, signature):
    """
    根据公钥验签
    :param message: 
    :type message: str
    :param public_key: 
    :type public_key: bytes
    :param signature: 
    :type signature: bytes
    :return: 
    """
    pk = RSA.importKey(public_key)
    verifier = PKCS1_v1_5.new(pk)
    digest = SHA.new()
    digest.update(message.encode('utf-8'))
    is_verified = verifier.verify(digest, base64.b64decode(signature))
    return is_verified


if __name__ == '__main__':
    message = "brown"
    private_key, public_key = generate_key_pair()
    signature = sign(message, private_key)
    print(verify(message, public_key, signature))

Output:

True

3. RSA实现细节

见维基百科

RSA加密算法


Ref

Pycrypto与RSA密码技术笔记

你可能感兴趣的:(python)