cryptography工具包

  1. from cryptography.hazmat.primitives.asymmetric import rsa, padding
  2. from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
  3. from cryptography.hazmat.backends import default_backend
  4. from cryptography.hazmat.primitives import serialization, hashes
  5. from cryptography.hazmat.primitives.serialization import Encoding, PrivateFormat, NoEncryption, PublicFormat
  6. import base64
  7. # 生成公钥和私钥
  8. def generate_keys():
  9. private_key = rsa.generate_private_key(
  10. public_exponent=655537,
  11. key_size=1024,
  12. backend=default_backend()
  13. )
  14. serialized_private_key = private_key.private_bytes(
  15. Encoding.PEM,
  16. PrivateFormat.PKCS8,
  17. NoEncryption()
  18. )
  19. public_key = private_key.public_key()
  20. serialized_public_key = public_key.public_bytes(
  21. Encoding.PEM,
  22. PublicFormat.SubjectPublicKeyInfo
  23. )
  24. print(private_key, public_key)
  25. return serialized_private_key, serialized_public_key
  26. def get_private_key():
  27. return """
  28. -----BEGIN PRIVATE KEY-----
  29. MIICdAIBADANBgkqhkiG9w0BAQEFAASCAl4wggJaAgEAAoGBAM1vDAM29PvzQ76I
  30. BBSSeC6+9cb6hC29wSkkIv0widZCxjXv9pGUgcv+O45cyJAKz/BNYzfCBvhgYGQX
  31. v+ym2pT+viSdrNR3+loAKuG+JH4E/mpIf5t+nJiMaGaN4CIyJ4uTsTUHbytFALUt
  32. Td8Vhy9Hfwb1VZRNCKWoVByoBHezAgMKALECf2jve5Rl61MpCxNIqY+WaLTYQ9L5
  33. 6UGLHvlhBXgV/04fN1CiVMHsEeVj79HbZZsSTXpsLQPGxlFknWSorMyRG6Uy3hhp
  34. nvWSvtrQrbuZIgDUjMfLXncRHj8NMF8CFa4oNDSOSbkOBN7DRKYsfa2svZoeRWvf
  35. 7sEMfEzIgIFpk1ECQQDzjBgbHnipALjsHLcNje45KWSdLUejEteCjkL+qZtUodsT
  36. 53Bud9HsVPzBj4FTjfMsI468BNF1AFrXOct3eMihAkEA1/ARROMt4rHMgaSOGE/s
  37. zJnEDG51uGfWF6dJCNhWm94vAFUySz0ksvSgHLY8KgAxF8gQvQ0qduQoBez47Po7
  38. 0wJBALCggjzdavd8suzRyupN3ckVl4f2iMpsAoP/cJpk2GTnbSTKAON+SyCPiVHi
  39. 0s5+xv50QxdrUXUoarQXI0Rk93ECQG3omUD3iKNulAbC5UUQDP748tGnjxKo+Mv6
  40. 9u/3upNYa1V7dwY26DVoChsU4WoVhefz62kHnKUo15RNXhaqovMCQAxh/ctJ/oU4
  41. +h434f/NrDVRYYhwvxS9+8bTAbe9J7vbn20NrRYvW/A9YLADkANaxXtdC2hEwKpm
  42. m9+AhWGzmr0=
  43. -----END PRIVATE KEY-----
  44. """
  45. def get_public_key():
  46. return """"
  47. -----BEGIN PUBLIC KEY-----
  48. MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDNbwwDNvT780O+iAQUknguvvXG
  49. +oQtvcEpJCL9MInWQsY17/aRlIHL/juOXMiQCs/wTWM3wgb4YGBkF7/sptqU/r4k
  50. nazUd/paACrhviR+BP5qSH+bfpyYjGhmjeAiMieLk7E1B28rRQC1LU3fFYcvR38G
  51. 9VWUTQilqFQcqAR3swIDCgCx
  52. -----END PUBLIC KEY-----
  53. """
  54. # 载入公钥并加密
  55. def load_public_key(message, key):
  56. public_key = serialization.load_pem_public_key(
  57. data=key.encode(),
  58. # data=get_public_key().encode(),
  59. backend=default_backend()
  60. )
  61. plaintext = public_key.encrypt(
  62. message,
  63. padding.OAEP( # 有疑问,不知道为啥填充还要有hash算法对原文hash,那这样不是解不了么
  64. mgf=padding.MGF1(algorithm=hashes.SHA1()),
  65. algorithm=hashes.SHA1(),
  66. label=None
  67. )
  68. # padding.PKCS1v15() # 也可以用这个 和解密保持一致
  69. )
  70. return base64.b64encode(plaintext)
  71. # 载入私钥并解密码
  72. def load_private_key(ciphertext, key):
  73. ciphertext = base64.b64decode(ciphertext)
  74. private_key = serialization.load_pem_private_key(
  75. data=key.encode(),
  76. # data=get_private_key().encode(),
  77. password=None,
  78. backend=default_backend()
  79. )
  80. plaintext = private_key.decrypt(
  81. ciphertext,
  82. padding.OAEP(
  83. mgf=padding.MGF1(algorithm=hashes.SHA1()),
  84. algorithm=hashes.SHA1(),
  85. label=None
  86. )
  87. # padding.PKCS1v15() # 也可以用这个 和加密保持一致
  88. )
  89. return plaintext
  90. """
  91. 注:
  92. 私钥签名过程:
  93. 1、hash算法对原文进行摘要
  94. 2、对上面的摘要用私钥进行加密得到一个签名
  95. 3、原文和签名一起发送给接收方
  96. 公钥验签过程:
  97. 1、用公钥对签名进行解密得到摘要1
  98. 2、hash算法对原文进行摘要得到摘要2
  99. 3、对比摘要2和摘要1是否一致
  100. """
  101. # 载入私钥并用签名
  102. def load_private_key_sign(message):
  103. message = message.encode()
  104. private_key = serialization.load_pem_private_key(
  105. data=get_private_key().encode(),
  106. password=None,
  107. backend=default_backend()
  108. )
  109. signature = private_key.sign(
  110. message,
  111. # padding.PKCS1v15(), # # 也可以用这个
  112. padding.PSS(
  113. mgf=padding.MGF1(algorithm=hashes.SHA1()),
  114. salt_length=padding.PSS.MAX_LENGTH
  115. ),
  116. hashes.SHA256()
  117. )
  118. # 这里面不用base64编码也可以,只是如果直接转换成字符串很有可能乱码
  119. return base64.b64encode(signature)
  120. # 载入公钥并验签
  121. def load_public_key_verify(signature, message):
  122. message = message.encode()
  123. signature = base64.b64decode(signature) # 上面用了base64编码,这里面就要解码
  124. public_key = serialization.load_pem_public_key(
  125. data=get_public_key().encode(),
  126. backend=default_backend()
  127. )
  128. verify_flag = public_key.verify(
  129. signature,
  130. message,
  131. # padding.PKCS1v15(), # 也可以用这个
  132. padding.PSS(
  133. mgf=padding.MGF1(algorithm=hashes.SHA1()),
  134. salt_length=padding.PSS.MAX_LENGTH
  135. ),
  136. hashes.SHA256()
  137. )
  138. return verify_flag
  139. # 加密、解密测试
  140. res = generate_keys()
  141. # print(res[0].decode())
  142. # print(res[1].decode())
  143. ciphertext = load_public_key("123456".encode(), res[1].decode())
  144. src_text = load_private_key(ciphertext, res[0].decode())
  145. print(src_text.decode())
  146. # 签名、验签测试
  147. sign = load_private_key_sign("xion")
  148. print(sign)
  149. print(load_public_key_verify(sign, "xion"))