Python pycryptodome的加解密、签名验签使用心得

1、加载密钥

key = Crypto.PublicKey.RSA.import_key(open(key_path).read())

2、签名与验签

用RSA-PSS using SHA-256举例

def Rsa256_sign_data(data, rsa_key):
	try:
		h = Crypto.Hash.SHA256.new(data)
		rsa_sign = Crypto.Signature.PKCS1_PSS.new(rsa_key)
        #new(rsa_key, mgfunc=None, saltLen=None, randfunc=None)
		if rsa_sign.can_sign():
			return rsa_sign.sign(h)
		else:
			raise Exception
	except Exception as err:
		log_print("RSA sign fail", '', err)
	return signature

def Rsa256_verify_data(data, sig, rsa_key):
	try:
		h = Crypto.Hash.SHA256.new(data)
		Crypto.Signature.PKCS1_PSS.new(rsa_key).verify(h, sig)
		return True
	except Exception as err:
        print("RSA verify fail", '', err)
		return False

new的参数包括rsa_key,mgfunc(回调函数,不写的话,默认采用mgf1,且和data采用相同的hash算法),saltlen(以byte为单位,默认为32,即使256bits),randfunc(没用过诶),new后将生成类Crypto.Signature.PSS_SigScheme的对象

class PSS_SigScheme:
    """A signature object for ``RSASSA-PSS``.
    Do not instantiate directly.
    Use :func:`Crypto.Signature.pss.new`.
    """

    def __init__(self, key, mgfunc, saltLen, randfunc):
        #代码就不贴上了
    def can_sign(self):
        #代码就不贴上了
    def sign(self, msg_hash):
        #代码就不贴上了
    def verify(self, msg_hash, signature):
        #代码就不贴上了
        #raise ValueError: if the signature is not valid.

3、加解密

1)用RSA-OAEP using SHA-256举例

def Rsa_OAEP_256_Encrypt(data, rsa_key):
	try:
		rsa_oaep = Crypto.Cipher.PKCS1_OAEP.new(rsa_key,Crypto.Hash.SHA256)
        #new(key, hashAlgo=None, mgfunc=None, label=b'', randfunc=None):
		if rsa_oaep.can_encrypt():
			return rsa_oaep.encrypt(data)
		else:
			raise Exception
	except Exception as err:
		print('RSA encrypt fail', '', err)
        return b''
    
def Rsa_OAEP_256_Decrypt(data, rsa_key):
	try:
		rsa_oaep = Crypto.Cipher.PKCS1_OAEP.new(rsa_key,Crypto.Hash.SHA256)
		if rsa_oaep.can_decrypt():
			return rsa_oaep.decrypt(data)
		else :
			raise Exception
	except Exception as err:
		print('RSA decrypt fail', '', err)
		return b''

new的参数包括key,hashAlgo(默认采用Crypto.Hash.SHA1),mgfunc(同上),label(没用过欸),randfunc(没用过欸),new后将生成类Crypto.Cipher.PKCS1_OAEP.PKCS1OAEP_Cipher对象

class PKCS1OAEP_Cipher:
    """Cipher object for PKCS#1 v1.5 OAEP.
    Do not create directly: use :func:`new` instead."""

    def __init__(self, key, hashAlgo, mgfunc, label, randfunc):

    def can_encrypt(self):

    def can_decrypt(self):

    def encrypt(self, message):

    def decrypt(self, ciphertext):
        

2)用AES-GCM举例

key_int =Crypto.Random.random.getrandbits(256)#生成的是一个大数,需要转换成bytes string
key = key_int.to_bytes(32,byteorder = 'big')#32 = 256/8

iv_int = Crypto.Random.random.getrandbits(96)
iv = iv_int.to_bytes(12,byteorder = 'big')

def aes256gcm_encrypt(data,key,iv,tag_len):
	try:
		aes = Crypto.Cipher.AES.new(key,Crypto.Cipher.AES.MODE_GCM,iv,mac_len=tag_len)
		return aes.encrypt_and_digest(data)
	except Exception as err:
		print("aes256gcm encrypt fail"," ",err)
		return b'',b''#返回密文和tag
    

def aes256gcm_decrypt(data,key,iv,tag):
	try:
		aes = Crypto.Cipher.AES.new(key,Crypto.Cipher.AES.MODE_GCM,iv,mac_len=len(tag))
		return aes.decrypt_and_verify(data,tag)
	except Exception as err
		print("aes256gcm decrypt fail"," ",err)
		return b''

Crypto.Random.random.getrandbits 有点坑,需要转换成byte string

new包括以下参数key,mode(选择以下模式),*args(iv或nonce),**kwargs(得需要查看对应模式的__init__)

AES包含以下模式,MODE_ECB = 1、MODE_CBC = 2、MODE_CFB = 3、MODE_OFB = 5、MODE_CTR = 6、MODE_OPENPGP = 7、MODE_CCM = 8、MODE_EAX = 9、MODE_SIV = 10、MODE_GCM = 11、MODE_OCB = 12

扫描二维码关注公众号,回复: 4462406 查看本文章

AES-GCM模式下,new返回类Crypto.Cipher._mode_gcm.GcmMode对象

class GcmMode(object):
    """Galois Counter Mode (GCM).

    This is an Authenticated Encryption with Associated Data (`AEAD`_) mode.
    It provides both confidentiality and authenticity.

    The header of the message may be left in the clear, if needed, and it will
    still be subject to authentication. The decryption step tells the receiver
    if the message comes from a source that really knowns the secret key.
    Additionally, decryption detects if any part of the message - including the
    header - has been modified or corrupted.

    This mode requires a *nonce*.

    This mode is only available for ciphers that operate on 128 bits blocks
    (e.g. AES but not TDES).

    See `NIST SP800-38D`_.

    .. _`NIST SP800-38D`: http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf
    .. _AEAD: http://blog.cryptographyengineering.com/2012/05/how-to-choose-authenticated-encryption.html

    :undocumented: __init__
    """

    def __init__(self, factory, key, nonce, mac_len, cipher_params, ghash_c):

    def update(self, assoc_data):

    def _update(self, data):

    def _pad_cache_and_update(self):

    def encrypt(self, plaintext):

    def decrypt(self, ciphertext):

    def digest(self):

    def _compute_mac(self):

    def hexdigest(self):

    def verify(self, received_mac_tag):

    def hexverify(self, hex_mac_tag):

    def encrypt_and_digest(self, plaintext):

    def decrypt_and_verify(self, ciphertext, received_mac_tag):

参考:

忘了链接在哪,得找找

猜你喜欢

转载自blog.csdn.net/ZRXSLYG/article/details/83042765
今日推荐