美文网首页
python加密

python加密

作者: 远方的橄榄树 | 来源:发表于2021-10-07 14:23 被阅读0次

字符串与bytes

s = "我爱你"
a = s.encode("utf-8")
b = a.decode("utf-8")
print(a)  # b'\xe6\x88\x91\xe7\x88\xb1\xe4\xbd\xa0'
print(b)  # 我爱你

binascii

binascii模块以更合适的方式展示16进制的字节

import binascii

s = "我爱你"
a = s.encode("utf-8")
b = binascii.b2a_hex(a)
c = binascii.a2b_hex(b)

print(a)  # b'\xe6\x88\x91\xe7\x88\xb1\xe4\xbd\xa0'
print(b)  # b'e68891e788b1e4bda0'
print(c)  # b'\xe6\x88\x91\xe7\x88\xb1\xe4\xbd\xa0'

URL编码

URL编码是一种浏览器用来避免URL中出现特殊字符的编码方式。其原理便是将超出ASCII范围的字符转换成带%的16进制格式。

from urllib import parse


url = "https://www.baidu.com?value=我爱你"
a = parse.quote(url)
b = parse.unquote(a)

print(a)  # https%3A//www.baidu.com%3Fvalue%3D%E6%88%91%E7%88%B1%E4%BD%A0
print(b)  # https://www.baidu.com?value=我爱你

Base64编码

原理

  1. 将所有字符转化为ASCII码。
  2. 将ASCII码转化为8位二进制 。
  3. 将二进制3个归成一组(不足3个在后边补0)共24位,再拆分成4组,每组6位。
  4. 统一在6位二进制前补两个0凑足8位。
  5. 将补0后的二进制转为十进制。
  6. 从Base64编码表获取十进制对应的Base64编码。
import base64

s = "我爱你"
a = base64.b64encode(s.encode("utf-8"))
b = base64.b64decode(a)

print(a)  # b'5oiR54ix5L2g'
print(b.decode("utf-8"))  # 我爱你

MD5编码

特点
1、长度固定
2、抗修改性,对于原数据进行任何改变,MD5都会改变
3、强碰撞性,不同文件的MD5值基本上是唯一的
4、不可逆性

import hashlib

s = "我爱你"
md5 = hashlib.md5()
md5.update(s.encode("utf-8"))
a = md5.hexdigest()

key = "123456"
md5_2 = hashlib.md5(bytes(key, encoding="utf-8"))  # 如果有参数,在原先的基础上在做一层加密
md5_2.update(s.encode("utf-8"))
b = md5_2.hexdigest()

print(a)  # 4f2016c6b934d55bd7120e5d0e62cce3
print(b)  # 5054fb0f1535be3289f1ba92027e8325

计算大文件的md5值

import hashlib


def get_file_md5(file):
    m = hashlib.md5()
    while True:
        data = file.read(10240)
        if not data:
            break
        m.update(data)
    return m.hexdigest()


FILE_NAME = "D:/Steam/game.zip"
with open(FILE_NAME, 'rb') as f:
    file_md5 = get_file_md5(f)
print(file_md5)

hmac

import hmac

s = "我爱你"
salt = "123456"
hm = hmac.new(s.encode(encoding="utf-8"), salt.encode(encoding="utf-8"), "MD5")

print(hm.digest())  # b'\x17\xae\xe8\xc3f\xb0\xd0\xee\xd1\x87\xa3=\x1b\xd8%\xb1'
print(hm.hexdigest())  # 17aee8c366b0d0eed187a33d1bd825b1

sha1加密
Security Hash Algorithm(安全哈希算法)。sha1基于MD5,加密后的数据长度更长,更安全。

import hashlib

s = "我爱你"
a = hashlib.sha1(s.encode(encoding="utf-8")).hexdigest()

print(a)  # 5890a73fed38bf09622c34ad9391f1d09c0ec100

DES加密

对称加密体质。DES是一个分组加密算法,典型的DES以64位为分组对数据加密,加密的和解密用的是同一个算法。
DES算法的入口参数有3个,key、data、mode。key为工作密钥,7个字节。data为需要加解密的数据。mode为DES的工作模式。
密钥长64位,由56位key和第8、16、24、32、40、48、56、64位校验位组成。

DES加密需要第三方依赖包。pip install pycryptodome

from Crypto.Cipher import DES
import binascii


def pad(text):
    """
    如果加密文本不是8的倍数,需要对文本进行填充
    :param text:
    :return:
    """
    pad_text = (8 - len(text) % 8) * "*" if len(text) % 8 else ""
    return text + pad_text


key = "12345678"
s = "hello, my friend"
des = DES.new(key.encode("utf-8"), DES.MODE_ECB)
data = pad(s)
encrypted_data = des.encrypt(data.encode("utf-8"))
plain_data = des.decrypt(encrypted_data)

print(data)  # hello, my friend
print(binascii.b2a_hex(encrypted_data))  # b'8d0c263b163a0b90eafe513008caa8f6'
print(plain_data)  # b'hello, my friend'

AES

Advanced Encryption Standard

from Crypto.Cipher import AES
from Crypto import Random

import binascii

data = "我爱你"
key = "12345678abcdefgh"  # b密钥key必须位16位、24位或32位
iv = Random.new().read(AES.block_size)
aes_encrypt = AES.new(key.encode("utf-8"), AES.MODE_CFB, iv)
cipher_text = iv + aes_encrypt.encrypt(data.encode("utf-8"))

aes_decrypt = AES.new(key.encode("utf-8"), AES.MODE_CFB, cipher_text[:16])
decrypt_text = aes_decrypt.decrypt(cipher_text[16:])

print(binascii.b2a_hex(iv))  # b'c491c0df41490bb643976ae0672a9b1c'
print(binascii.b2a_hex(cipher_text))  # b'c491c0df41490bb643976ae0672a9b1c598dfd7be91cfbc1ad'
print(decrypt_text.decode("utf-8"))  # 我爱你

RSA

非对称加密
使用openssl,keytools等工具生成一对公私钥对,使用被公钥加密的数据可以使用私钥来解密,反之亦然,使用私钥加密的数据也可以被公钥加密。

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
import binascii


class MyRSA:
    def __init__(self):
        self.private_rsa_key = ""  # 密钥
        self.rsa_public_pem = ""  # 公钥

    def create_rsa_key(self, password):
        key = RSA.generate(1024)
        encrypted_key = key.exportKey(passphrase=password.encode("utf-8"), pkcs=8,
                                      protection="scryptAndAES128-CBC")
        self.private_rsa_key = encrypted_key
        self.rsa_public_pem = key.publickey().exportKey()

    def encrypt(self, text):
        recipient_key = RSA.import_key(self.rsa_public_pem)
        cipher_rsa = PKCS1_v1_5.new(recipient_key)
        encrypted_text = cipher_rsa.encrypt(text.encode("utf-8"))
        return encrypted_text

    def decrypt(self, encrypted_text, password):

        private_key = RSA.import_key(self.private_rsa_key, password)
        cipher_rsa = PKCS1_v1_5.new(private_key)
        text = cipher_rsa.decrypt(encrypted_text, None)
        return text


password = "123456"
rsa = MyRSA()
rsa.create_rsa_key(password)
encrypted_text = rsa.encrypt("我爱你")
decrypted_text = rsa.decrypt(encrypted_text, password)

print(binascii.b2a_hex(encrypted_text))
print(decrypted_text.decode("utf-8"))
print(binascii.b2a_hex(rsa.private_rsa_key))
print(binascii.b2a_hex(rsa.rsa_public_pem))

转载文章:Python 常见加密方式和实现

相关文章

网友评论

      本文标题:python加密

      本文链接:https://www.haomeiwen.com/subject/ppwanltx.html