1、背景 cryptography 库是一个强大的 Python 加密库,提供了对加密算法和协议的高层和低层访问。它是用来实现数据加密、签名、密钥管理等功能的。以下是一些常见用法的详解。
2、安装 1 pip install cryptography
3、对称加密 对称加密是指加密和解密使用相同的密钥。Fernet 是 cryptography 库中提供的对称加密类。
示例:使用 Fernet 进行加密和解密
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 from cryptography.fernet import Fernet key = Fernet.generate_key() cipher_suite = Fernet(key) plain_text = b"Hello, World!" cipher_text = cipher_suite.encrypt(plain_text) print(f"Cipher Text: {cipher_text} " ) decrypted_text = cipher_suite.decrypt(cipher_text) print(f"Decrypted Text: {decrypted_text.decode('utf-8' )} " )""" Cipher Text: b'gAAAAABm1SuaILy-UxWXz4hpBxVmrFlrZ1pPGJPTLZNMqqp38qwcHjTX16BbWasLUvhkCCL485jSfCTZ0HQWUptYniUX6EAwQA==' Decrypted Text: Hello, World! """
4、非对称加密 非对称加密使用一对密钥:公钥和私钥。cryptography 库中提供了 RSA 算法的实现。
示例:使用 RSA 进行加密和解密
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 from cryptography.hazmat.backends import default_backendfrom cryptography.hazmat.primitives.asymmetric import rsa, paddingfrom cryptography.hazmat.primitives import serialization, hashes private_key = rsa.generate_private_key( public_exponent=65537 , key_size=2048 , backend=default_backend() ) public_key = private_key.public_key() message = b"Hello, RSA!" cipher_text = public_key.encrypt( message, padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None ) ) print(f"Cipher Text: {cipher_text} " ) decrypted_text = private_key.decrypt( cipher_text, padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None ) ) print(f"Decrypted Text: {decrypted_text.decode('utf-8' )} " )""" Cipher Text: b';2\xdf\xc80%\x19\xf4\x95\xbc<\xfa\xb7\xe7\'\x94\xed!\xd0\x17\xdf\xb7c\xe3Q\xd6caEU\xc6 g(r\xa1-\xa1*y\xf9\xac\x1d"\xa7F\xd8J[w6Ly7\x06m5\xd2\x1d\xa9\x87A_\xb6\n\x078\xfb\xcc\x80\xf8\xad#\x86\x88\x97\xd8j\x17s\xf4\xc0\t\xc2\xb24i\x1c\x1c\xc1\x96\r\xac2\xd9\xaf\xfal\xa2n\xac\xb7\xa4C\xb6\xac\x1a,\xec\x94\xfa\x9b\xf2\xca\x030v#\x00\xdc\xd6\xa7\xf8:o\x1eK\xc3L\xf4\x88B\ru\xa1\x8b\xc0//@\x0c\x84\x047\xa7\xa1\x1f\x82\xe2\xdd\x0f\tT\x9df\xb5\x98n\xe2\xb8\x0e\x8c\xcb\x95T\x93SjX\xaf;97\xad\x19\x9el\x8d\xa3\xacr\xe0tT\x8c\x18\xa2!\x15\xd8\xf3\x8e\x88{\x01\x96[\xfa\xff\xc70\xef\xfe\xa5C\x01b?\xe7\xa9\xbdLw\xa8\x05^?\xbe\x94p\xa4#j\xeb\xef\xfb\xac\x92\xca|}`\xce\xe6\x7f&\xd2h\x19\x19K\x91\xde\xc5\xce\xdc\x91\xb7|\xaf\x9ef\x8d\xc8\xb7\xaf' Decrypted Text: Hello, RSA! """
5、数字签名 数字签名可以用来验证消息的完整性和来源。可以使用非对称加密的私钥进行签名,使用公钥进行验证。
示例:使用 RSA 进行数字签名
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 from cryptography.hazmat.backends import default_backendfrom cryptography.hazmat.primitives.asymmetric import rsafrom cryptography.hazmat.primitives import serialization, hashesfrom cryptography.hazmat.primitives.asymmetric import padding""" 代码解释: 生成密钥对: 使用 RSA 算法生成一个私钥和相应的公钥。这里的公钥和私钥都是 2048 位的。 签名消息: 用私钥对一条消息进行签名,使用 PSS 填充和 SHA-256 哈希算法。 验证签名: 使用公钥验证签名是否有效。若有效,则证明消息在签名前未被篡改。 """ private_key = rsa.generate_private_key( public_exponent=65537 , key_size=2048 , backend=default_backend() ) public_key = private_key.public_key() private_pem = private_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.TraditionalOpenSSL, encryption_algorithm=serialization.NoEncryption() ) print("Private Key:" ) print(private_pem.decode()) message = b"Hello, this is a secret message." signature = private_key.sign( message, padding.PSS( mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH ), hashes.SHA256() ) print("Signature:" ) print(signature.hex())try : public_key.verify( signature, message, padding.PSS( mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH ), hashes.SHA256() ) print("Signature is valid." )except Exception as e: print("Signature is invalid:" , str(e))""" Private Key: -----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAq3zlAQlVy/4/S+St69LJubb/OUfZLdI1L+ERXfwZOfro0sWU DXhkx7ZDAyZPG72eIcYjl4yOlUM51Ih+1ukFDwC+iKPIT8Dc2nBCP5gpTTNOdb+Y U0LLaCzqZa5QBivl6Su3y8G2k9pACiENGPWjw7ph/Ev+0UFxk/Zu7xV85XZPUQZE xdSHrSAvLI7vcjQPC2PURNf7NwYRw0QFe/7/xah4omu1YLO6BllJDahxcnp/MgYd /do/i0R34s4IX0mhK2E0napaBI5DsAmIt81juO3RJVXpxbe2+RIrrD53UJVSt5qg R+y1xjT2gCTn8pIDkx3yJHX6Iftq0hPFvh3gGwIDAQABAoIBAA8/L/yFxXSOeuHh skWaJ1L/6QpBOpcp2OO/Dt8R0nZcD3Dp8y4NaxHHQTGu/sVDIyOdQmiE19/VKyJG g9cnaZ/ksOFk2nhIzU9jQBNNEThVcZ+OH4TLlq/WSn2Bit45mfE/cKceO9WXx9jU CR4+fMcis6KNvoQBXbqfjvZqgoEY0bTTmhisEslpG+utKxhjKgVlFlFTb7RxTci7 OTyOpstpfvx1ZgQz+ck6rR6MhonUvHObvEpxHLIBADp+ND+8K29mMSl0/YkGJRLO Y4NuBn2JP+x3KkFjGdRr27z5tqODLyNXNEj9o1WuiH20ssrSvuHc4PDd8r2lGAsG xB9WpzUCgYEA7bE3Wh5R1S1RzhGQjJGyXcsEQuzoSyCvpbiMKOlggU2f4RLu1wiH lVF8Hy7WQntlEs2Mty6hUCu2jwThX3emdXisO7/LMAsYXYPrjLwbPVEmpmgHP1Ng 7TdiskHZuc+IaEXdnLQo2cfwnwyjTGYA4G0G40dht4pDELUPAYino6UCgYEAuLJE 7bP844JShS9rXm/nwbPQcPPsKDXAIE/EvkKW9zpURiMMI/22F2ZiNFMDuSkgu0MV PgfBhZwu0UY005Us8x1Q7iH8WgByELBIFsbTfhxlw/tCM1wDCgKTdXvB1TJqSPYZ NJIIdNPxE+uhRvsxWcbbhyN7ZFwUKO428MxFKL8CgYA5xovH0freMGfkCQzzvi52 8fQVOHS2XjmTtKoM/70/cNjd4rY/eolKWEYtZjsaadgFnAUKOcFoNVfop60IgZLq lux2kYYYJXpEsN4+lTKh0unsJPkuAVxcDMxmu+7qZXGotuLJRllvplPstSu0VE7+ PkIgWKd975OhqgD9xHPLKQKBgA2W4Ed1FMhQkG3IPWgnZ6/y4QVOjTOwMMCv3dP5 5k2udwDqFzyWsE0sdVFQQlffVM8ycl+sBmskQLWZKs3ejf4dTBUZXw3oNnxP3B4A 5xLCWCKBXC+XN4oHAn6EapCbMwLHSLd7fy/JYFWM4sLsPIdUgFaDH9MUi08vp88z 2GrVAoGBAKzyYoz2z71y4hC5ZXyMSefuGHRoODOgu8DYJVviJybyJ5rtLfUi1eu7 sLhhfA4oE/XiXLeGDDc4DuQ5KbrbR6X6nWI1oAT8ptwk5IoYHPfRsccaVtIwYVQr 2W0tup110R110LdwfhIsHQJONnbOu6wMuNtmJbT4ZXezXH7pa14V -----END RSA PRIVATE KEY----- Signature: 9cfa80431114b49b0c1c1847af7d87e055889824bb6b4a06fd0b46d85d3200c083284382a1ee73e7f20a467986d858ae9f1888039fdef6b550beaf46ffe8fe181a214089727dc5f8907d580d404df75ff18ab5bb95ab1b2a6a84247771532fd75c3252cbb1a41dbaf28d02ef84b07fdd80284354d848f191a1bd3ffd571010e50a03d070c2db25c54196cb1aa9a8d3ef579d5522dfc591528a781ef27345986c52ef2bd75cd7444ee9de4ed74b2b8ad2234c1b4aea3097897daf24f3dd144bf2d4f00b7b46e06cdc2342def8eff4f782dedc20de4b0aa5c1ead7527627815186596e0e28f23c83364c56383e13217e0497ea843607b6b923464d98e0c70d98f7 Signature is valid. """
6、密钥序列化与反序列化 下面是一个示例,演示如何生成密钥并进行序列化和反序列化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 from cryptography.fernet import Fernet""" 代码说明: 生成密钥: Fernet.generate_key() 生成一个新的密钥。 序列化: 使用 key.decode('utf-8') 将密钥从字节转换为字符串,方便存储(例如保存到文件或数据库)。 反序列化: 使用 serialized_key.encode('utf-8') 将字符串转换回字节,以便恢复原始密钥。 加密与解密: 使用序列化后的密钥创建 Fernet 实例,可以对消息进行加密和解密。 """ key = Fernet.generate_key() fernet = Fernet(key) serialized_key = key.decode('utf-8' ) print(f"Serialized Key: {serialized_key} " ) deserialized_key = serialized_key.encode('utf-8' ) fernet = Fernet(deserialized_key) message = b"Hello, World!" encrypted_message = fernet.encrypt(message) print(f"Encrypted Message: {encrypted_message} " ) decrypted_message = fernet.decrypt(encrypted_message) print(f"Decrypted Message: {decrypted_message.decode('utf-8' )} " )""" Serialized Key: BQqk2MbwlcWt6Bt39topcwIao2Gk2M_R3doVN37EHDA= Encrypted Message: b'gAAAAABm1S2Uwc4-4urM6bSfC3S7Az05xrJscPlP0WJlocDnXz8L6rddP3uCUVuQKsw507H6bnVsHcyj9OS1qDGVTawT9OwzQw==' Decrypted Message: Hello, World! """
7、通信数据加密 下面是一个使用 cryptography 库和 Python 的 socket 模块来实现简单的加密通信的示例。
服务端代码(server.py):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 import socketfrom cryptography.fernet import Fernet key = Fernet.generate_key() cipher_suite = Fernet(key)with open("secret.key" , "wb" ) as key_file: key_file.write(key) server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind(('localhost' , 65432 )) server_socket.listen() print("等待连接..." ) conn, addr = server_socket.accept()with conn: print('连接来自' , addr) while True : encrypted_data = conn.recv(1024 ) if not encrypted_data: break decrypted_data = cipher_suite.decrypt(encrypted_data) print("接收到:" , decrypted_data.decode()) server_socket.close()
客户端代码(client.py):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import socketfrom cryptography.fernet import Fernetwith open("secret.key" , "rb" ) as key_file: key = key_file.read() cipher_suite = Fernet(key) client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client_socket.connect(('localhost' , 65432 )) message = "你好,服务器!" encrypted_message = cipher_suite.encrypt(message.encode()) client_socket.sendall(encrypted_message) client_socket.close()
注意事项
密钥管理:在实际应用中,密钥的存储和管理是至关重要的。不要将密钥硬编码在代码中。 错误处理:示例代码中缺乏错误处理,实际使用时需要考虑到网络异常等情况。 加密方式:这里使用的是对称加密,适合小规模数据,若涉及到用户身份验证或更复杂的场景,可以考虑使用 SSL/TLS 等。 通过上述代码示例,你可以了解到如何使用 cryptography 库以及 Python 的 socket 模块来实现基本的网络通信加密。