Python 爬蟲進階必備 | AES-CBC 的 Pyhon 實現要怎麼寫?給代碼就完事了

2021-03-02 鹹魚學Python
終於可以光明正大的水一篇文章了。

還是老規矩,本文重要部分就是文章結尾的代碼,路過的大佬不想聽鹹魚嘮嗑的直接劃到結尾拿代碼就好了,記得點讚,寶貝。

先講講為什麼寫這篇文章,就是昨天分析了某服務平臺的加密數據分析,果不其然炸了不少小白讀者,老夫甚是欣慰。

於是,在孤寂的深夜。

有讀者找到我想問問關於AES加密的 Python 實現應該怎麼寫,聽到這個需求我第一時間是拒絕的

對,就是這麼真實,畢竟我是鹹魚,能 BB 絕對不會動手的

但是,畢竟讀者爸爸都是磨人的小妖精,所以我屈服了。

之後我就打開了某個不可描述的網站開始找資源

果然,找到了不少關於 AES 加密的文章,不過看文章的日期基本是2017-2019的居多。

而且這裡一定要提一句,Python 的 PyCrypto 已死,現在用 Python 實現加密常用的是PyCryptodom

PyCryptodom可以使用下面這句命令安裝

pip3 install pycryptodome 
# pip3 install -i https://pypi.douban.com/simple pycryptodome 

然後不停使用 CV 大法調試網上的代碼,不得不吐槽一句,C*DN 網站真的垃圾,十篇文章有九篇文章雷同。

先看下關於pycryptodome的用法

from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA256
from Crypto.Cipher import AES

如果有嘗試過用 Python 實現的朋友一定遇到過下面的報錯

TypeError: Object type <class 'str'> cannot be passed to C code

這個報錯的解決辦法非常簡單,但是昨晚沒有找到原因的時候真的和噩夢一樣

最後在stackoverflow找到了處理辦法,大家可以去圍觀下

https://stackoverflow.com/questions/50302827

處理辦法也很簡單,encode就行了

obj = AES.new('This is a key123'.encode("utf8"), AES.MODE_CBC, 'This is an IV456'.encode("utf8"))

解決了這個問題之後,之後就是通暢無阻了

這裡直接給出AES-CBC兩種輸出的代碼,以下代碼的加解密結果與http://tool.chacuo.net/cryptaes相同。

AES-CBC 輸出 Hash 的示例代碼

from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex


class PrpCrypt(object):
    def __init__(self, key):
        self.key = key.encode('utf-8')
        self.mode = AES.MODE_CBC

    # 加密函數,如果text不足16位就用空格補足為16位,
    # 如果大於16當時不是16的倍數,那就補足為16的倍數。
    def encrypt(self, text):
        text = text.encode('utf-8')
        cryptor = AES.new(self.key, self.mode, b'0123456789ABCDEF')
        # 這裡密鑰key 長度必須為16(AES-128),
        # 24(AES-192),或者32 (AES-256)Bytes 長度
        # 目前AES-128 足夠目前使用
        length = 16
        count = len(text)
        if count < length:
            add = (length - count)
            # \0 backspace
            # text = text + ('\0' * add)
            text = text + ('\0' * add).encode('utf-8')
        elif count > length:
            add = (length - (count % length))
            # text = text + ('\0' * add)
            text = text + ('\0' * add).encode('utf-8')
        self.ciphertext = cryptor.encrypt(text)
        # 因為AES加密時候得到的字符串不一定是ascii字符集的,輸出到終端或者保存時候可能存在問題
        # 所以這裡統一把加密後的字符串轉化為16進位字符串
        return b2a_hex(self.ciphertext)

    # 解密後,去掉補足的空格用strip() 去掉
    def decrypt(self, text):
        cryptor = AES.new(self.key, self.mode, b'0123456789ABCDEF')
        plain_text = cryptor.decrypt(a2b_hex(text))
        # return plain_text.rstrip('\0')
        return bytes.decode(plain_text).rstrip('\0')


if __name__ == '__main__':
    pc = PrpCrypt('jo8j9wGw%6HbxfFn')  # 初始化密鑰 key
    e = pc.encrypt('{"code":200,"data":{"apts":[]},"message":"","success":true}')  # 加密
    d = pc.decrypt("lXgLoJQ3MAUdzLX+ORj5/pJlkRAU423JfyUKVd5IwfCSxw6d1mHwBdHV9p3kmKCYwNRmAIEWeb/9ypLCqTZ1FA==")  # 解密
    print("加密:", e)
    print("解密:", d)

AES-CBC 輸出 Base64 的示例代碼

from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex
import base64

class PrpCrypt(object):
    def __init__(self, key):
        self.key = key.encode('utf-8')
        self.mode = AES.MODE_CBC

    # 加密函數,如果text不足16位就用空格補足為16位,
    # 如果大於16當時不是16的倍數,那就補足為16的倍數。
    def encrypt(self, text):
        text = text.encode('utf-8')
        cryptor = AES.new(self.key, self.mode, b'0123456789ABCDEF')
        # 這裡密鑰key 長度必須為16(AES-128),
        # 24(AES-192),或者32 (AES-256)Bytes 長度
        # 目前AES-128 足夠目前使用
        length = 16
        count = len(text)
        if count < length:
            add = (length - count)
            # \0 backspace
            # text = text + ('\0' * add)
            text = text + ('\0' * add).encode('utf-8')
        elif count > length:
            add = (length - (count % length))
            # text = text + ('\0' * add)
            text = text + ('\0' * add).encode('utf-8')
        self.ciphertext = cryptor.encrypt(text)
        return base64.b64encode(self.ciphertext).decode()

    # 解密後,去掉補足的空格用strip() 去掉
    def decrypt(self, text):
        cryptor = AES.new(self.key, self.mode, b'0123456789ABCDEF')
        decryptByts = base64.b64decode(text)
        plain_text = cryptor.decrypt(decryptByts)
        return bytes.decode(plain_text).rstrip('\0')


if __name__ == '__main__':
    pc = PrpCrypt('jo8j9wGw%6HbxfFn')  # 初始化密鑰 key
    e = pc.encrypt('{"code":200,"data":{"apts":[]},"message":"","success":true}')  # 加密
    d = pc.decrypt("lXgLoJQ3MAUdzLX+ORj5/pJlkRAU423JfyUKVd5IwfCSxw6d1mHwBdHV9p3kmKCYwNRmAIEWeb/9ypLCqTZ1FA==")  # 解密
    print("加密:", e)
    print("解密:", d)

這裡只給出了代碼,關於 AES 的原理講解之類的信息在夜幕的系列課程已經講過了,這裡不再贅述。

今天的內容就到這裡,咱們下次再會~

相關焦點

  • Python視頻教程網課編程零基礎入門數據分析網絡爬蟲全套Python...
    ,然後再根據自 己的需求和規劃選擇學習其他方向課程,學完後一定要多實踐 總目錄 零基礎全能篇(4套課程) 實用編程技巧進價(1套課程) 數據分析與挖掘(8套課程) 辦公自動化(3套課程) 機器學習與人工智慧(7套課程) 開發實戰篇(4套課程) 量化投資(2套課程) 網絡爬蟲(
  • 聊聊學python轉行、具體學習方法、自學python用於辦公、寫爬蟲等...
    Python這幾年都挺火的,比如說應用於數據分析、機器學習、自動化辦公、寫爬蟲採集數據等等……因為我之前發過幾篇和python有關的推文,所以不止一個朋友加私信問我說,你是怎麼學的,能不能談一談學習的經驗和技巧。
  • 如何開始寫你的第一個python腳本——簡單爬蟲入門!
    好多朋友在入門python的時候都是以爬蟲入手,而網絡爬蟲是近幾年比較流行的概念,特別是在大數據分析熱門起來以後,學習網絡爬蟲的人越來越多,哦對,現在叫數據挖掘了!其實,一般的爬蟲具有2個功能:取數據和存數據!好像說了句廢話。。。
  • 從零開始的python爬蟲速成指南
    小夥伴感興趣可以自取~此外,我這還有兩本比較經典的python爬蟲電子書,在微信公眾號【輪子工廠】後臺回復 」爬蟲」 可以領取。Python爬蟲入門七之正則表達式二、爬蟲實戰Python爬蟲實戰一之爬取糗事百科段子Python爬蟲實戰二之爬取百度貼吧帖子Python爬蟲實戰三之實現山東大學無線網絡掉線自動重連Python爬蟲實戰四之抓取淘寶MM照片Python爬蟲實戰五之模擬登錄淘寶並獲取所有訂單Python
  • Python爬蟲:一些常用的爬蟲技巧總結
    也差不多一年多了,python應用最多的場景還是web快速開發、爬蟲、自動化運維:寫過簡單網站、寫過自動發帖腳本、寫過收發郵件腳本、寫過簡單驗證碼識別腳本。,於是對爬蟲一律拒絕請求。這時可以通過修改http包中的header來實現,代碼片段如下:import urllib2 headers = {    'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6
  • Python 爬蟲面試題 170 道
    59.python 字典和 json 字符串相互轉化方法60.請寫一個 Python 邏輯,計算一個文件中的大寫字母數量61. 請寫一段 Python連接 Mongo 資料庫,然後的查詢代碼。62.說一說 Redis 的基本類型。
  • Python 爬蟲:8 個常用的爬蟲技巧總結!
    用python也差不多一年多了,python應用最多的場景還是web快速開發、爬蟲、自動化運維:寫過簡單網站、寫過自動發帖腳本、寫過收發郵件腳本
  • Python破解反爬蟲:最新反爬蟲有道翻譯中英文互譯破解,附代碼
    python這裡小編今天就給大家發一個最新的破解有道翻譯反爬蟲機制的python代碼,你也可以百度,但百度上目前的所有有道翻譯的爬蟲代碼都已經不能用,大家可以自測!話不多說,我們先看結果,代碼在第三幅圖
  • AutoScraper: Python 實現的輕量級爬蟲
    【導讀】該項目專為自動爬蟲而設計,使爬蟲變得容易。它獲取網頁的url或html內容以及我們要從該頁面抓取的示例數據列表。
  • 【安卓逆向之密碼學】從一個簡單的AES-256-CBC開始
    很久沒寫文章了,我又回來了,這回開始,應該會慢慢更新一些有關安卓逆向中的學習記錄,主要的目的還是鞏固自己的學習,不做筆記學習的東西容易忘記,當然,如果給大家帶來了收穫,別忘了點讚、收藏和轉發,哈哈哈今天要帶來的是一個有關AES加密相關的APP分析,如果參加了看雪高研安卓班的話,應該就知道我說的是哪個了。話不多說,直接開始。
  • Python爬蟲學到什麼程度就可以去找工作了?
    有朋友在群裡和大家討論,問的最多的問題就是,python 爬蟲學到什麼程度可以去找工作了,關於這點,和大家分享下我的理解。尤其是 java,同時掌握它們和擁有相關開發經驗是很重要的加分項2、 大部分的公司都要求爬蟲技術有一定的深度和廣度,深度就是類似反反爬、加密破解、驗證登錄等等技術;廣度就是分布式、雲計算等等,這都是加分項3、 爬蟲,不是抓取到數據就完事了,如果有數據抽取、清洗、消重等方面經驗,也是加分項
  • 小叮噹Python進階(二):爬蟲與加密算法Part2之AES
    2.Python實現AES首先要確保已經安裝好Cryptodome模塊,若未安裝,可參考「小叮噹Python進階(二):爬蟲與加密算法Part1」進行安裝。以上便是加密算法AES與Python實現的介紹,RSA算法將在其它篇幅為大家介紹。
  • python實踐:利用爬蟲刷網課
    前言:用過python的人應該都會知道爬蟲這個東西,網絡爬蟲(又被稱為網頁蜘蛛,網絡機器人,在FOAF社區中間,更經常的稱為網頁追逐者),是一種按照一定的規則,自動地抓取全球資訊網信息的程序或者腳本。今天就來講講如何利用爬蟲技術刷網課。實戰:最近學校又推送了一波網課,一個一個的看實在太費時間,於是乎就想到了爬蟲來自動刷網課。
  • Python爬蟲之urllib庫—爬蟲的第一步
    第一個爬蟲代碼的實現我想應該是從urllib開始吧,博主開始學習的時候就是使用urllib庫敲了幾行代碼就實現了簡單的爬數據功能,我想大多夥伴們也都是這麼過來的
  • 適合新手學習的Python爬蟲書籍
    用Python寫網絡爬蟲《用Python寫網絡爬蟲》作為使用Python來爬取網絡數據的傑出指南,講解了從靜態頁面爬取數據的方法以及使用緩存來管理伺服器負載的方法精通Python網絡爬蟲:核心技術、框架與項目實戰本書從技術、工具與實戰3個維度講解了Python網絡爬蟲:技術維度:詳細講解了Python網絡爬蟲實現的核心技術
  • python爬蟲-- Scrapy入門
    前言轉行做python程式設計師已經有三個月了,這三個月用Scrapy爬蟲框架寫了兩百多個爬蟲,不能說精通了Scrapy,但是已經對Scrapy有了一定的熟悉
  • 寫一段Python爬蟲前,需要準備什麼?
    PyCharm 編輯器Python 2.7(3.X也行) 集成環境對,只需要準備這兩個東西就可以開始敲下你人生的第一段Python代碼了。當然,如果頭鐵想自己親自搭建環境,也可以手動安裝python安裝包後,用pip安裝各種依賴。一切準備妥當後,我們在終端裡可以敲出 Python 會出現版本信息。
  • Python爬蟲與文本分析應用案例研討會
    Python作為一門面向對象的程式語言,簡潔的語法使得編寫數十行代碼即可實現爬蟲功能使用Python來編寫爬蟲實現簡單且效率高,同時爬取的數據可以使用Python強大的第三方數據處理庫來進行分析,最重要的是學習成本低,如此之好的東西怎能不學習呢?
  • Python爬蟲入門教程:超級簡單的Python爬蟲教程
    這是一篇詳細介紹 Python 爬蟲入門的教程,從實戰出發,適合初學者。讀者只需在閱讀過程緊跟文章思路,理清相應的實現代碼,30 分鐘即可學會編寫簡單的 Python 爬蟲。如果用人體來比喻,HTML 是人的骨架,並且定義了人的嘴巴、眼睛、耳朵等要長在哪裡。CSS 是人的外觀細節,如嘴巴長什麼樣子,眼睛是雙眼皮還是單眼皮,是大眼睛還是小眼睛,皮膚是黑色的還是白色的等。JScript 表示人的技能,例如跳舞、唱歌或者演奏樂器等。
  • 寫網絡爬蟲程序的難度是怎麼分等級的
    寫網絡爬蟲程序的難度是怎麼分等級的 猿人學 發表於 2020-02-05 11:49:55 寫爬蟲,是一個非常考驗綜合實力的活兒。