1-Installation
pip install cryptography
2-cryptography learning
View the directory structure of cryptography
cryptography/ hazmat/ # Main directory, symmetrically encrypted and decrypted library files are all in this directory backends/ # This directory will not be researched for the time being, this directory has a lot to do with openssl bindings/ # This directory will not be researched for the time being, this directory is related to openssl primitives/ # This article mainly learns the contents in this directory, including filling data, symmetric encryption and decryption, asymmetric encryption and decryption, signature verification of public and private keys asymmetric/ Asymmetric password related content,If you need it, you can learn more about the content of the file【Commonly used】 ciphers/ Symmetric encryption algorithm content,What this article mainly tells -- :aesdAlgorithm content,IncludeChaCha20Poly1305、AESCCM、AESGCM、AESOCB3。 -- :The main contents of symmetric algorithms,IncludeAES、Camellia、TripleDES、ChaCha20、SM4etc. -- :Basically not available in actual use -- :Encryption mode kdf/ # Encryption key derivation is related to key storage, please understand it yourself if you need to serialization/ Serialization related,If you need to know twofactor/ 该模块包Include与双因素认证Related的algorithm。at present,它包Include了一种基于基于哈希的消息身份验证码(HMAC)Algorithm to generate and verify one-time password values。If you need to know -- :cmacRelated -- constant_time.py -- :Crypto hash function connection -- :hmacalgorithm -- :Haven't used it -- :filling -- :poly1305algorithm -- ....Other documents x509/ # x509 certificate related content -- :对称algorithm的实现,usecryptography最基础的use,
2.1-Using of fernet
The most basic use of cryptography
A brief introduction to the Fernet method
classmethod generate_key():Class Methods,Used for generationbase64-encoded 32-byte key. encrypt(data):Example method,Encrypted data encrypt_at_time(data, current_time):Encrypt the passed data using explicitly passed current time decrypt(token, ttl=None):Example method,Decrypt the data decrypt_at_time(token, ttl, current_time):Use the explicitly passed current time to decrypt the token extract_timestamp(token):Returns the timestamp of the token。Then,The caller can decide whether the token is about to expire,For example,Issue a new token MultiFernet(fernets):MultiFernetkind,这个kind为FernetImplement key flow。It accepts aFernetInstance List,and achieve the sameAPI
FernetExample of usage
The example comes from the contents of the library documentation introduction
Cryptography Documentation Release 43.0.0.dev1
>>> from import Fernet >>> key = Fernet.generate_key() >>> f = Fernet(key) >>> token = (b"my deep dark secret") >>> token b'...' # The results are different every time>>> (token) b'my deep dark secret'
2.2-padding fill
-
Provide PKCS7 and ANSIX923 filling methods
-
PKCS7
: Fill to the specified length, the fill content is the length of the fill -
ANSIX923
:Fill the last byte as length, the rest is 0
Here we take PKCS7 as an example:
import binascii from import padding class MyPadding: def __init__(self, block_size: int): self.block_size = block_size def padding(self, padding_data): b_padding_data = padding_data.encode('utf8') padder = padding.PKCS7(block_size=self.block_size).padder() result = (b_padding_data) + () return result def unpadding(self, unpadding_data): unpadder = padding.PKCS7(block_size=self.block_size).unpadder() result = (unpadding_data) + () return result if __name__ == '__main__': my_padding = MyPadding(128) data = "123456789" p = my_padding.padding(data) print(p) print(type(p)) print(binascii.b2a_hex(p)) d = my_padding.unpadding(p) print(d) ''' b'123456789\x07\x07\x07\x07\x07\x07\x07' <class 'bytes'> b'31323334353637383907070707070707' b'123456789' '''
ANSIX923:
>>> padder = padding.ANSIX923(128).padder() >>> padded_data = (b"11111111111111112222222222") >>> padded_data += () >>> padded_data b'11111111111111112222222222\x00\x00\x00\x00\x00\x06' >>> unpadder = padding.ANSIX923(128).unpadder() >>> data = (padded_data) >>> data += () >>> data b'11111111111111112222222222'
2.3-Hash
Here we briefly show the use of the hash library for cryptography.
- Instance hash object (hashes.'hash_name'()) -> Replace 'hash_name' with hash algorithm name, such as SHA1, SHA256, etc. If you are not sure which ones are supported, you can view the file, which contains the list.
- If there is a lot of hash content, you can update it multiple times. There is no content. Finally, you can finalize it.
- HASH:SHA1,SHA512_224,SHA512_256,SHA224,SHA256,SHA384,SHA512,SHA3_224,SHA3_256,SHA3_384,SHA3_512,SHAKE128,SHAKE256,MD5,BLAKE2b,BLAKE2s,SM3
>>> from import hashes >>> digest = (hashes.SHA256()) >>> (b"abc") >>> (b"123") >>> () b'l\xa1=R\xcap\xc8\x83\xe0\xf0\xbb\x10\x1eBZ\x89\xe8bM\xe5\x1d\xb2\xd29%\x93\xafj\ x84\x11\x80\x90'
If you don't want to use cryptography's hash, you can use the hashlib library that comes with python.
import hashlib __hash__ = [ 'md5','sha1','sha224','sha256','sha384','sha512','blake2b','blake2s','ripemd160','whirlpool','sha3_224','sha3_256','sha3_384','sha3_512','sm3',] class MyHash: def __init__(self, hash_name: str): self.hash_name = hash_name.lower() def hash(self, hash_data: str): if self.hash_name not in __hash__: raise "unsupported hash, confirm the input hash name" hash_object = (self.hash_name) hash_object.update(hash_data.encode('utf-8')) return hash_object.hexdigest() if __name__ == '__main__': data = 'abc123' my_hash = MyHash('SHA256') print(my_hash.hash(data))
2.4-ciphers (Symmetrical Algorithm AES as an example)
Algorithms such as AES are combined with CBC mode. A simple example of encrypting content using AES and then decrypting the content:
>>> import os >>> from import Cipher, algorithms, modes >>> key = (32) >>> iv = (16) >>> cipher = Cipher((key), (iv)) >>> encryptor = () >>> ct = (b"a secret message") + () >>> decryptor = () >>> (ct) + () b'a secret message'
Encapsulation use:
If you need to use other algorithms, you only need to encapsulate them according to the following and simply modify them. Most of them only need to modify the name of the algorithm used in encryption and decryption.
#!/usr/bin/env python # -*- coding: UTF-8 -*- """ Encryption modes that require IV: CBC, OFB, CFB, CFB8 Encryption algorithm: ["AES","Camellia","TripleDES","Blowfish","CAST5","ARC4","IDEA","SEED","ChaCha20","SM4"] """ import binascii import os from import Cipher, algorithms, modes import my_padding MODES_NAME = ["CBC", "ECB", "OFB", "CFB"] def gen_key(key_len): return (key_len) def _model_object(alg_modes, alg_iv): if alg_modes.upper() not in MODES_NAME: raise "unsupported modes, confirm the input hash name" modes_dict = { "CBC": (alg_iv), "ECB": (), "OFB": (alg_iv), "CFB": (alg_iv) } return modes_dict.get(alg_modes.upper()) def hex2string(hex_string): bytes_string = binascii.a2b_hex(hex_string) return bytes_string.decode('utf8') class MyAES: name = 'AES' block_size = 128 key_sizes = frozenset([128, 192, 256, 512]) def __init__(self, alg_key: bytes = None, alg_modes: str = 'CBC', alg_iv: bytes = b'1234567812345678'): # The default key_size is 32 if alg_key is None: self.__alg_key = gen_key(32) else: self.__alg_key = alg_key self.__alg_iv = alg_iv self.__alg_modes = _model_object(alg_modes, alg_iv) def get_key(self): return binascii.b2a_hex(self.__alg_key) def set_key(self, alg_key: bytes): # Make a judgment on alg_key if not isinstance(alg_key, bytes): raise TypeError("Type error: {0} is not an instance of bytes".format(type(alg_key))) self.__alg_key = alg_key def get_iv(self): return binascii.b2a_hex(self.__alg_iv) def set_iv(self, iv: bytes): if not isinstance(iv, bytes): raise TypeError("Type error: {0} is not an instance of bytes".format(type(iv))) self.__alg_iv = iv def encrypt(self, plain_data: str): """ Enter a string to complete the encryption operation :param plain_data: plaintext string :return: Hexadecimal cipher string """ # Complete data filling and convert to bytes to fill data data_padding = my_padding.MyPadding(MyAES.block_size).padding(plain_data) # aes object my_alg = Cipher((self.__alg_key), self.__alg_modes) encryptor = my_alg.encryptor() # Encryption operation is completed result = (data_padding) + () # Convert to capital hexadecimal string output return binascii.b2a_hex(result).upper().decode() def decrypt(self, cipher_data: str): """ Enter hexadecimal ciphertext data and return to the original text :param cipher_data: Hexadecimal ciphertext data string :return: """ cipher_data_bytes = binascii.a2b_hex(cipher_data) my_alg = Cipher((self.__alg_key), self.__alg_modes) decrypt = my_alg.decryptor() # Decryption operation is completed result = (cipher_data_bytes) + () data_unpadding = my_padding.MyPadding(MyAES.block_size).unpadding(result) # Convert to capital hexadecimal string output return binascii.b2a_hex(data_unpadding).upper().decode() if __name__ == '__main__': aes = MyAES() data = 'hello world' cipher = (data) plain = (cipher) print('cipher:', cipher) print('plain:', hex2string(plain)) print('key:', aes.get_key()) print('iv:', aes.get_iv()) print('alg_name:', ) ''' cipher: 6EAE64A7B78A5C0985A1CADA8FAAB7D0 plain: hello world key: b'4f56291a9aaa86fbd341ac5ca0bb10fa5d583d281b55f853172e83197effa0c2' iv: b'31323334353637383132333435363738' alg_name: AES '''
2.5-asymmetric (Asymmetric algorithm RSA as an example)
asymmetric
The corresponding location is//cryptography/hazmat/primitives/asymmetric
Under the path,cryptography
The library supports a variety of asymmetric algorithms, including: ed25519, RSA, dh, dsa, ed448, etc. This takes the most common RSA algorithm as an example.
According to the introduction in the official document, the main content is:
-
Generation
: Generate an RSA private key -
key loading
: Load the key in PEM format -
Key serialization
: Key serialization, you can obtain a base64 format key -
Signing
: Use the private key to sign the message, and the public key can verify the result -
Verification
: Verification of the corresponding public key pair message -
Encryption
: Encrypt the data using a public key, so that only those with the private key can already be decrypted -
Decryption
: Private key decrypts public key encryption information -
Padding
: RSA signature requires a specific hash function and needs to be filled. The message is filled during encryption. -
Numbers
: Contains the composition of RSA keys, and can obtain the composition of the corresponding public and private keys. It is generally not recommended to use it. -
Handling partial RSA private keys
: If you can't use it, it is usually only possible for professional password users to use it. -
Key interfaces
: The main interface corresponding to the key
Checkasymmetric
In the directoryFile, learn the above main content based on the content in the source code
Function: generate_private_key
def generate_private_key( public_exponent: int, key_size: int, backend: = None, )-> RSAPrivateKey: pass ''' public_exponent: index, based on cryptography knowledge, this defaults to pass 65537 key_size Parameters • public_exponent (int) – index, based on cryptography knowledge, this defaults to pass 65537 • key_size (int) – refers to the private key length (bit), such as 1024bit, 2048bit, 4096bit • backend - default Returns Returns the RSAPrivateKey class, which is also defined in the `` file '''
Class: RSAPrivateKey (private key class)
class RSAPrivateKey(metaclass=): @ def decrypt(self, ciphertext: bytes, padding: AsymmetricPadding) -> bytes: """ Decrypt the provided ciphertext. You can see that in addition to the ciphertext, the parameter transmission also requires a fill algorithm. The corresponding fill algorithm can be viewed under `asymmetric` """ @property @ def key_size(self) -> int: """ The length of the key, that is, the key_size passed in through the generate_private_key function """ @ def public_key(self) -> RSAPublicKey: """ Associated with this private keyRSAPublicKey(Also a class,Public key class)。 """ @ def sign( self, data: bytes, padding: AsymmetricPadding, algorithm: [asym_utils.Prehashed, ], ) -> bytes: """ Signing messages. It involves fill algorithms, as well as hash algorithms """ @ def private_numbers(self) -> RSAPrivateNumbers: """ Returning the RSAPrivateNumbers class is usually rarely used, and no specific research is done """ @ def private_bytes( self, encoding: _serialization.Encoding, format: _serialization.PrivateFormat, encryption_algorithm: _serialization.KeySerializationEncryption, ) -> bytes: """ Returns the serialization of the private key """
Class: RSAPublicKey (public key class)
class RSAPublicKey(metaclass=): @ def encrypt(self, plaintext: bytes, padding: AsymmetricPadding) -> bytes: """ Encrypt the given plaintext """ @property @ def key_size(self) -> int: """ The bit length of the common mode. """ @ def public_numbers(self) -> RSAPublicNumbers: """ Return the RSAPublicNumbers class """ @ def public_bytes( self, encoding: _serialization.Encoding, format: _serialization.PublicFormat, ) -> bytes: """ Returns the serialization of the public key """ @ def verify( self, signature: bytes, data: bytes, padding: AsymmetricPadding, algorithm: [asym_utils.Prehashed, ], ) -> None: """ Verify the message """ @ def recover_data_from_signature( self, signature: bytes, padding: AsymmetricPadding, algorithm: [], ) -> bytes: """ Recover original data from signature. """ @ def __eq__(self, other: object) -> bool: """ Checks equality. """
Other content
- class RSAPrivateNumbers: RSAPrivateNumbers class, mentioned in the previous content, obtaining the content of the private key, such as p, q, d, etc. If the external knows the value of these private keys, you can also use the class method private_key to return the RSAPrivateKey class
- class RSAPublicNumbers: RSAPublicNumbers class, mentioned in the previous content, obtains the content of the public key. For example, if e and n are known to the external value of these public keys, you can also use the class method public_key to return to the RSAPublicKey class.
- etc. (The others are supporting functions, please understand by yourself if you are interested)
Use of asymmetric algorithms
The corresponding file location: It is located in the same level as the file. This padding file is specially used for filling in asymmetric algorithms. It only provides three filling methods:
-
PKCS1v15
: A simple fill scheme that can be used for signature and encryption. Not recommendedPKCS1v15
For new applications, it is the first choice for encryptionOAEP
, the first choice for signaturePSS
-
PSS
:RSA
Signature recommended fill algorithm. Can't be withRSA
Use encryption together -
OAEP
:RSA
Encrypted fill algorithm. It cannot be withRSA
Use signatures together
# ExamplekindPKCS1v15:No parameters are required,It's the easiest way to fill it,The result is the same every time kindOAEP:need3Parameters parameter: • mgf – Mask generation function object. Only supported MGF1. • algorithm – An example of hashing algorithm • label (bytes) – App Tags to Set(Didn't understand),defaultNoneJust. kindPSS:need2Parameters parameter: • mgf – Mask generation function object. Only supported MGF1. • salt_length (int) – The length of salt。It is recommended to set it toPSS.DIGEST_LENGTHorPSS.MAX_LENGTH.
Example
Based on the above content, the main content of RSA can be divided into the following four parts
- Generate key pair -> corresponding private key class -> private key class has a corresponding method to obtain public key class
- The methods corresponding to public and private keys: common are encryption, decryption, signature, and signature verification
- Serialization of public and private keys
- Obtain the components of public and private keys, or generate the corresponding public key class private key class based on the corresponding value
Others: The serialization directory is used to serialize the contents of the private key and public key, and save or load the public key and private key. There is no specific introduction here, only examples are given. If you need it, you can understand the contents of the serialization.
- Key generation, encryption, decryption, signature, verification, view key pair information, serialization
from import rsa from import hashes from import padding from import serialization import binascii # The following examples are all from the official documentation and are integrated# Generate key pair, generate_private_key returns the RSAPrivateKey classprivate_key = rsa.generate_private_key(public_exponent=65537, key_size=2048) # Get the corresponding public key class RSAPublicKeypublic_key = private_key.public_key() # Use the private key to complete some operations, decrypt and sign# Use public key to complete some operations, encryption, and signature verification# Signature, the filling method can be changed to pkcs1v15, padding.PKCS1v15, and the signature result can be returned.sign_message = b"A message I want to sign" signature = private_key.sign( sign_message, ( mgf=padding.MGF1(hashes.SHA256()), salt_length=.MAX_LENGTH), hashes.SHA256()) print("signature :",binascii.b2a_hex(signature)) # Verify signature: There is a public key, message, signature value and the signature algorithm used. This has no return value. Failure to verify the signature will cause an exception: InvalidSignaturetry: public_key.verify( signature, sign_message, ( mgf=padding.MGF1(hashes.SHA256()), salt_length=.MAX_LENGTH), hashes.SHA256()) print("verify:True") except Exception: print("verify:False") # Encryption operationencrypted_message = b"encrypted data" ciphertext = public_key.encrypt( encrypted_message, ( mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None)) print("encrypted_message:",encrypted_message) print("ciphertext:",binascii.b2a_hex(ciphertext)) # Decryption operationplaintext = private_key.decrypt( ciphertext, ( mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None)) print("plaintext:",plaintext) print("\n\nRSAPrivateNumbers and RSAPublicNumbers:") print("\n--RSAPrivateNumbers") private_numbers = private_key.private_numbers() print("private_key_p:",private_numbers.p) print("private_key_q:",private_numbers.q) print("private_key_d:",private_numbers.d) print("\n--RSAPublicNumbers") public_numbers = public_key.public_numbers() print("public_numbers_e:",public_numbers.e) print("public_numbers_n:",public_numbers.n) print("\n\nSerialization:") print("private_key(encryption):") pem1 = private_key.private_bytes( encoding=, format=.PKCS8, encryption_algorithm=(b'mypassword')) # Change mypassword to a specific passwordprint(()) print("\nprivate_key(不encryption):") pem2 = private_key.private_bytes( encoding=, format=, encryption_algorithm=()) print(()) print("\npublic_key:") pem3 = public_key.public_bytes( encoding=, format=) print(()) ''' serialization: The functions involved include load public and private keys, which can load data in pem, der and other formats, as well as certificate-related data. If you need it, you can learn about it. '''
result:
message: b'41206d65737361676520492077616e7420746f207369676e' verify:True encrypted_message: b'encrypted data' ciphertext: b'2de0f1fe1b5d72b947b8dbf71d05c38dc68bd651726070e606b4a9458d7c0fa16dfb07172171ba859a3409218e0b7ecad7b17fe56fd35bb49e31f0841acde909975620e83a1877219d15238f6688347431c36feb7663b177a966493109fe231e99e670f25d3ffc110a5676446026760ab739adb18fec25880eac014b1f2954a3b73db5678434bf60863dd06004dc829d221d3379e3cc063a6b4b85bfc5be169cfc299635a4e49b78054c57e792122b6b9aed137f7aedf25bc597788e0dd504e7b1c1da9afb8b6f80fe302ae51695473df63062990689afb466c96971756afd83326ac45839a031060194a0eed3aa169712cf6a4269a3cc16a5b10f5c605806c3' plaintext: b'encrypted data' RSAPrivateNumbersandRSAPublicNumbers: --RSAPrivateNumbers private_key_p: 147707585390291063655757186262664106581403583389769944190047479079802050557725461099143359285822400756601173686331008082783603762936206021035899801451983264373148026750004290322897832812789405156566036002605846423080016655535724545169357406940078465489591648499524311055428140666709043701951435405479083981507 private_key_q: 129818834990747146076466076783245566173460449186750491874222727814890697974924830062686005653997995728519629633284989915391162771546276906687785728345643383550878857450814037005853925931576826949107171864400879318575256878287526216494946410211681273209849751153418151910847326891086641035970617228184947974907 private_key_d: 8810065303547375928762349845316578013736506843080962512785868984734235290147877769264533096278362621787580696227653983919152226155921915698934833065258407586046747526250001963974218056036596580241940226949193816099076733090875075170550805899822656343465349396304500236060334137387244149410275988416202842542643262376837913857243207448439181111570332656768871231679656608370503370807857876773764088762784617137105654224500539668074456531405130162650453503803762719548271686520860271816511040217898091202461965447102304587164219886390683471833950962879479877256508594964292975127590603085155442999424663885457883776781 --RSAPublicNumbers public_numbers_e: 65537 public_numbers_n: 19175226654663889483686962299907428291529655241439907017383929316612785301398873015319640846560893067121406664962032451400135480242458058156856037813351939755130872193811111511174598277655024080213743703416336724973770112469751247100806621044026350130573166065079473679741161647303238677556416507350559120976572285358670246819946035044400185934220271734966395030418149358791928954989911148327721467003737750718274576389626687388317759384228357042486488866743832265506806649718988419123733129099398851518371219540705498141408901068424765912060559147570293587318212074428767533901711200492332308159704597121102288044849 Serialization: private_key(encryption): [b'-----BEGIN ENCRYPTED PRIVATE KEY-----', b'MIIFNTBfBgkqhkiG9w0BBQ0wUjAxBgkqhkiG9w0BBQwwJAQQIgxxwKU52uh4HZra', b'9yMxDwICCAAwDAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEOmuIolT9bVH3sVl', b'FarjNV8EggTQizU+Wlfb7PPYR7Pw2/QZl3Br4q79fDrdwNTWBcF5gZg7/+2tkFCn', b'X61/kcYkt9r+znyzjRQ6q3DeW2kfGL6iKEpHnon8OZcg23ZadNw4ossUDGg0dQWD', b'xzXZ8ztM+saQW05gl622cBjcpmWH7rrD6EjOMKMSwEh1iowrnb/1vk/h5cbe72fv', b'JWAPyQMLlRZyFncXukXY2UQe5+8wJquNoSmr4bBdWy5BshUstZEj7+bquzhOn4nm', b'VL1E/u6fhx3F3nfq9HfZg5BCZo1g0otMlcNUo7ecKdqQ6Cx4P0CwoJEYd9Rr1v5O', b'KV5M0tcp7Nt1FdTX0gTJZXYa8rMor+uvjuLV8cd8e9ygxRbdAau/X0Jh6tbKS/fh', b'EI7BxHaaiZXR7wNx08A/Sbup09Bo8awebjr+gEZuiwW2lO5UvEaqXI6g3w7H2SmK', b'xB5zRa6vtZkoobUZfKLDkRYW8Q7wIm6/zfUQ/xB6V0rgVZgVZ5Yo4nQnq/teqkEC', b'MuhI++rC7liTrpydf3lr+OI67WpbHnzgodNSSNp579p1SbGYcDSQK2/FOMmEfINE', b'2+2AAcAU2pNbj/XGyE8EEl/5wv/IHCbGQXOiJhxZcFIL/cbJh9r3zM4UJQRek91k', b'fQ5UF+sJF9D7iH8+6wH3iWKRAhyRtbukHQ1J1b+qH9GwPfkJM6JTR221WfyoAi84', b'3B+BxZLRWu1rTmMu3erUt90Gua9oDfQ5awvMr7c4ng3i1lFw9uT8xPlxr9GPbA4v', b'pU5/E+VTRo6PghuDLZarTdIHH2VURW1gEzttJiVgODRyN0MEEEC80vWTW6L3gnZO', b'fYufxLySQvxULeAJL+VkRKqQQa8xC8CogLXFa+nM4qIcgU83gjfaYk6VEf/M3Fkh', b'gHinbWdRdXL4WPBLqWtGIZa5/Ybt+ElEbonPZBaasIySp0BBtKjhdQhEtf3nGh0i', b'/Mo7RnWPd5B8SPmFx9Sy0boLMle4OxsWog2lXpN0Nf3zJeSgh9AohDLm1vvxadT+', b'FVQZXN5Y2pOKbK+H621r3kDy9HqSotISa20HLGs58bSEY4YSLwzOUAcFqjBb70t4', b'oP+j0lYse8ZcAZ7sW9uubekYeA55vIKDZKuNuysnpm5QEF42Zhq1Cz0VSS/addPs', b'KbgDqSVqCALqwdWcy5K3PXa77IwZorXg1woVvL/iw7PZoJ26XB8dSPk7jD75Lza7', b'W542mxrg6TrHVZfcDEpGEchWj4Nh/80NGxSwHXEiTRow4sHxfCePyK2N61YjBykw', b'//QXjBhB3R4nDZUxvAkwkEU1mV89U9TOtF3L9pEFSeA2Z3Vlyo57++yGsPtPeIvI', b'uFg9fSL9EjOgjWNjgfa3Mn2UBWV+eOi9LTH5M6Xslhqu0/2QPF8Z2TQ9i1RjecaD', b'eaezPrgjOq9IL9NERjaT8t1ocnfZbPbNUDmAGWVC0bi16WSM/QqzagzOxVrhevoN', b'YjBKh0PF29C0d05R6nc9jW8HJAHj/CEkUtx+S4LcCYMiBwFJwHeCfYXzOYx2iLkW', b'8q7FVndB11mxg9VYDf7aXpgItNTEwTl8iJRXhLE1FDA6dO2g1t1gMmZwIvdGNXc4', b'Qta6kOyRqypsMsxmu/5U87XxgR99D5Fyljt1F3T/3ir3hIjk2xIOze8=', b'-----END ENCRYPTED PRIVATE KEY-----'] private_key(不encryption): [b'-----BEGIN RSA PRIVATE KEY-----', b'MIIEpAIBAAKCAQEAl+WlWH3VkNfRFXjxpmNrTskYDEF/MFGufYy5gfZ8+p9O2Cwk', b'RC2s6jv8dtdxi+a+GUvnks54xdnKAeOAgdd9HHs9hK0DmeGymVFUUfglfgIm3xm5', b'A33i2m6Eg/5Uipq3fVPx4sqlME2uHJs4Vb/4wN+Tz/F2xllIsSzeHR3oKg8EYc0w', b'oW3EHqLpvBUy+V5OIjlkajXFLpCIFlYMAXGbDJ9jTNP4IU8sDUc1MDCB4MyNE9Qs', b'YTjujj8YFbNmTEM3RSMV/oCTtsEmVIjxENNMb94+8tmpzMku//oQALTwZ9aKJsoV', b'VERVmu42gxJtRIYWrIpkhf713GWYUUdBwiTDMQIDAQABAoIBAEXKBmkdD6XH8tG5', b'ytVW8nO1Yy4mXai2rsQShx0WQh/oWBJsXZFRpxPL0dhMbmgH8SmwPUqvQMAuq2io', b'vV9qwZn3abFuyKvIDgXxXxt2Nsupc3Cn4eCf0z3m702x6efw5ANaMVWxI6qI1klg', b'a8bCOCltz/0HhTnmxcZZxgd8uTGxFQ431w5iqnWJ26u57eSjoxLPdAQxqbBVbwOY', b'x2clL/5MK9VDroVn6k/dnQlKjJ1YhCOLq9AlAQ8kaudhB7xNGp19d9k5LJJKZCjX', b'SuGA1Fi0Dk0AvyUsK5IQ83LutT5jZezKNE8wkc1ryj+OnYBi9zbqArdi0Euam/aT', b'4Sq1xw0CgYEA0lezj+p6vasX14PlVic/rdlmpWqQqWHZR6kltOtK+x50W0QHHtPC', b'fTyDk3hJ4DczzBmjsyVHQPjkw3dqY3KtSWOrInjoJGGOBxQgv85c+uaLXsh9iOM2', b'H64JYHboXcp5G2+So3nz6mzrlB/j9St/CrZB6d1RenWJH6y86nWrOsMCgYEAuN4/', b'kb/aZ7PbdGK71zjCHqCGK9EvV3Lo0rn/HUQSr8g/kiBsKtXOLwi9vaF+VM5xVcJ2', b'DvH835CP7zoF6/58NAh90I5nOCJ6Ukt9VsWJvx7+78QSykU9L0BJLWarA6nQlEis', b'kNSNB1NE27Zu3KHnXRaFM+LKv4pxP9CJ+Bb24vsCgYEAwBPCLxuJ9gV1AiK5nBC/', b'P7wU1d0YOPTXe27kte9fSy2mR2k5r1bkdYR7CoF/xLXkIO8Q45iZFqWyESTNC/8+', b'apQPRK1wHzjOf3xL45tIoP1CK82dhREm7Yr5mRM8Ydlw+jLKj2nf6SSJg3wTqGCN', b'5HRGgI7PxqnqC/irktbdBA0CgYEAmKBMxW0qyPFR3p3hTUf75ENNYoGa30zscYXD', b'3QqljuD5sw/3ncnVJznFRPk+jo++PDqHM8GPr5fvbWdvGi6Jpn/YN8ZJ66tzZ9wR', b'SAFgvxy9B4DOrpZJdGhTwhsAV87seHAjoJMLOCAEOo08rAUzOcRtBrBYCZkn9LKc', b'Jen3vN8CgYAStWv4jLNEGcJWweAIgQlGoaJPLGEd5aGP7au2NWtUsG1cbj8NUYox', b'CAweSjQrmvA1fHIWrMO3Cc99/04/aRQwHcLdgqCVMXBDIe9tuBo/QhTTcfC5bGye', b'X/HTMjfXHpsBUocsDpeQ/zeoKclZFQUsUbVg2Bfs292kaFr7YginHQ==', b'-----END RSA PRIVATE KEY-----'] public_key: [b'-----BEGIN PUBLIC KEY-----', b'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl+WlWH3VkNfRFXjxpmNr', b'TskYDEF/MFGufYy5gfZ8+p9O2CwkRC2s6jv8dtdxi+a+GUvnks54xdnKAeOAgdd9', b'HHs9hK0DmeGymVFUUfglfgIm3xm5A33i2m6Eg/5Uipq3fVPx4sqlME2uHJs4Vb/4', b'wN+Tz/F2xllIsSzeHR3oKg8EYc0woW3EHqLpvBUy+V5OIjlkajXFLpCIFlYMAXGb', b'DJ9jTNP4IU8sDUc1MDCB4MyNE9QsYTjujj8YFbNmTEM3RSMV/oCTtsEmVIjxENNM', b'b94+8tmpzMku//oQALTwZ9aKJsoVVERVmu42gxJtRIYWrIpkhf713GWYUUdBwiTD', b'MQIDAQAB', b'-----END PUBLIC KEY-----']
This is the end of this article about the implementation of the cryptography library in python. For more related content of the python cryptography library, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!