python加密

字符串與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進制的字節(jié)

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中出現(xiàn)特殊字符的編碼方式。其原理便是將超出ASCII范圍的字符轉(zhuǎn)換成帶%的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. 將所有字符轉(zhuǎn)化為ASCII碼。
  2. 將ASCII碼轉(zhuǎn)化為8位二進制 。
  3. 將二進制3個歸成一組(不足3個在后邊補0)共24位,再拆分成4組,每組6位。
  4. 統(tǒng)一在6位二進制前補兩個0湊足8位。
  5. 將補0后的二進制轉(zhuǎn)為十進制。
  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、抗修改性,對于原數(shù)據(jù)進行任何改變,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"))  # 如果有參數(shù),在原先的基礎(chǔ)上在做一層加密
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,加密后的數(shù)據(jù)長度更長,更安全。

import hashlib

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

print(a)  # 5890a73fed38bf09622c34ad9391f1d09c0ec100

DES加密

對稱加密體質(zhì)。DES是一個分組加密算法,典型的DES以64位為分組對數(shù)據(jù)加密,加密的和解密用的是同一個算法。
DES算法的入口參數(shù)有3個,key、data、mode。key為工作密鑰,7個字節(jié)。data為需要加解密的數(shù)據(jù)。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的倍數(shù),需要對文本進行填充
    :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等工具生成一對公私鑰對,使用被公鑰加密的數(shù)據(jù)可以使用私鑰來解密,反之亦然,使用私鑰加密的數(shù)據(jù)也可以被公鑰加密。

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))

轉(zhuǎn)載文章:Python 常見加密方式和實現(xiàn)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容