Python的加密

  • Post author:
  • Post category:python




1.加密的分类

  • 对称加密

    Symmetric Cryptography

    ,消息的发送者和接收者使用相同的key进行加密和解密
  • 非对称加密

    Asymmetric Cryptography

    (也叫

    Public-key Cryptography

    ),消息的加密和解密使用不同的key



2.哈希函数

MD5

import hashlib
password = b"password123"
salt = b"2022"
hash = hashlib.md5 (password + salt).hexdigest()
print (hash)

注意

哈希碰撞: 不同的输入经过同一哈希函数得到相同的输出

SHA

import hashlib
hash_object = hashlib.sha256(b'Hello World')
hex_dig = hash_object.hexdigest()
print(hex_dig)
hash_object = hashlib.sha256(b'Hello World!')
hex_dig = hash_object.hexdigest()
print(hex_dig)

注意

哈希函数具有不可逆性,也就是无法通过哈希值逆向算出原始输入,这点非常重要,否则通过哈希存储的密码就不安全了



3.数字签名

签名过程(签名由私钥持有方发起):

•首先准备一个要发送的明文消息

•通过哈希算法,把这条明文消息转成哈希值

•使用私钥对这个哈希值进行签名

•把明文消息连同签名发送给公钥持有方

验证过程(公钥持有方进行签名验证):

•收到原始明文信息,对其进行哈希,取得哈希值H1

•通过公钥对签名消息进行解密,取得哈希值H2

•比较H1和H2,如果相等,则证明发送信息者,确实为私钥拥有方。

python演示

from Crypto.PublicKey import RSA

key_pair = RSA.generate(bits=1024)
print("Public key:")
print(f' N={hex(key_pair.n)}')
print(f' e={hex(key_pair.e)}')
print("Private key:")
print(f' N={hex(key_pair.n)}')
print(f' d={hex(key_pair.d)}')

# 生成签名
msg = b'A message for signing'
from hashlib import sha512

hash = int.from_bytes(sha512(msg).digest(), byteorder='big')  # 使用了Python内置的pow方法进行乘方和模运算
signature = pow(hash, key_pair.d, key_pair.n)
print("Signature:", hex(signature))

# 签名的验证
msg = b'A message for signing'
hash = int.from_bytes(sha512(msg).digest(), byteorder='big')
hash_from_signature = pow(signature, key_pair.e, key_pair.n)
print("Signature valid:", hash == hash_from_signature)

openssl演示

#生成RSA私钥
openssl genrsa -out private.pem 1024
#生成RSA公钥
openssl rsa -in private.pem -pubout >  public.pem
#对data.txt进行签名
openssl dgst -sha1 -sign private.pem -out sha1.sign data.txt
#对data.txt进行验签名
openssl dgst -sha1 -verify public.pem -signature sha1.sign data.txt



4.消息认证

消息认证( Message authentication codes )

•消息认证一般是用在

对称加密系统

,通信双方共享一个秘钥

•数字签名是用在

非对称加密系统

,也就是公钥私钥加密

使用Python计算HMAC-SHA256:

import hashlib, hmac, binascii

mac = hmac.new(b'key', b'some msg', hashlib.sha256).digest()
print(binascii.hexlify(mac))

MAC的使用场景

在这里插入图片描述

•通信双方共享一个秘钥,并且协商好MAC的算法(比如HMAC-SHA256)

•消息发送方把未加密的消息,连同消息+秘钥计算出的MAC值发送给消息接收方

•接收方通过秘钥和消息计算出MAC值,如果计算的MAC和接收到的MAC值相同,则可以说明消息违背第三方篡改。



5.Fernet方法

Fernet是AES+HMAC的一种应用场景

pip install cryptography

示例

import hashlib
import base64

from cryptography.fernet import Fernet


def create_url_safe_base64_encoded_bytes(secret):
    """convert secret into 32 url-safe base64-encoded bytes for Fernet key"""
    # get 32 bytes SHA256 hash
    m = hashlib.sha256()
    m.update(secret.encode())
    return base64.urlsafe_b64encode(m.digest())


def encrypt(secret, plain_text):
    f = Fernet(create_url_safe_base64_encoded_bytes(secret))
    return f.encrypt(plain_text.encode()).decode()


def decrypt(secret, cipher):
    f = Fernet(create_url_safe_base64_encoded_bytes(secret))
    return f.decrypt(cipher).decode()


def encrypt_file(input_file_name, output_file_name, secret):
    # 一个文件加密的例子,注意读取bytes
    f = Fernet(create_url_safe_base64_encoded_bytes(secret))
    with open(input_file_name, 'rb') as f_in:
        content_raw = f_in.read()
    encrypted = f.encrypt(content_raw)
    with open(output_file_name, 'wb') as f_out:
        f_out.write(encrypted)


if __name__ == "__main__":
    cipher_text = encrypt(secret='password', plain_text="message")
    print(cipher_text)
    plain_text = decrypt(secret='password', cipher=cipher_text)
    print(plain_text)



6.数字证书

PKI(Public Key Infrastructure ) 简称公钥基础设施 ,它是一个在数字世界里用来认证用户或者设备的技术,由一些受信任的机构签发一个特殊的“文件”来证明一个秘钥属于特定的用户和设备,用户和设备从而可以使用该认证过的秘钥来代表自己的身份,进行消息的传递

在这里插入图片描述



6.1证书的内容

•证书拥有者的基本信息,(比如HTTPS证书的话,包括拥有者的域名CNAME,公司或者组织名称,地点等)

•证书颁发者的基本信息

•证书拥有者的公钥

•对公钥和其他信息的签名



6.2OpenSSL生成自签名证书

1.生成 CA的RSA的私钥

openssl genrsa -out ca.key 2048

2.CA公钥生产的签名(根证书)

openssl req -new -x509 -key ca.key -out ca.crt -days 365<<EOF
DN
DN
BJ
BJ
Test
Test
test.com
EOF  

3.证书申请者(网站)的RSA公钥私钥

openssl genrsa -out my-website.key 2048

4.证书申请者(网站)公钥 + 网站信息,签名后生成CRS

openssl req -new -key my-website.key -out my-website.csr<<EOF
CN
BJ
BJ
CS
C
my-website.tips
test@test.com
666666
test
EOF  

5.查看csr文件信息

openssl req -text -noout -verify -in my-website.csr

6.对csr文件进行签名

openssl x509 -req -in my-website.csr -CA ../ca/ca.crt -CAkey ../ca/ca.key -set_serial 01 -out my-website.crt -days 365

7.查看证书申请者生成的CRT证书

openssl x509 -in my-website.crt -text -noout

8.证书测试

from flask import Flask
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run(ssl_context=('my-website.crt', 'my-website.key'))



版权声明:本文为weixin_44689630原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。