主頁 > 後端開發 > Python加密庫 Crypto.Cipher包中 ChaCha20 介紹

Python加密庫 Crypto.Cipher包中 ChaCha20 介紹

2023-03-09 07:15:35 後端開發

該軟體包包含用于保護機密性的演算法 的資料,Crypto.Cipher

有三種型別的加密演算法:

  1. 對稱密碼:所有各方都使用相同的密鑰 解密和加密資料, 對稱密碼通常非常快,可以處理 非常大量的資料,
  2. 非對稱密碼:發送方和接收方使用不同的密鑰, 發送方使用公鑰(非機密)加密,而接收方 使用私鑰(機密)解密, 非對稱密碼通常非常慢,可以處理 只有非常小的有效載荷,示例:PKCS#1 OAEP (RSA),
  3. 混合密碼:上述兩種型別的密碼可以組合使用 在繼承兩者優點的結構中, 非對稱密碼用于保護短期 對稱鍵, 和對稱密碼(在該密鑰下)加密 實際訊息,

對稱密碼

有兩種型別的對稱密碼:

  • 流密碼:最自然的密碼型別: 它們一次加密一個位元組的資料, 參見ChaCha20和XChaCha20和Salsa20,

  • 分組密碼:只能以固定數量操作的密碼 的資料,最重要的分組密碼是AES,它具有 塊大小為 128 位(16 位元組),

    通常,分組密碼通常僅與 一種操作模式,允許加密 可變數量的資料,某些模式(如點擊率)可以有效地轉動 將分組密碼轉換為流密碼,

廣泛的共識是,密碼提供 只有機密性,沒有任何形式的身份驗證,是不可取的, 相反,基元已被定義為集成對稱加密和 身份驗證 (MAC),例如:

  • 分組密碼(如 GCM)的現代操作模式,
  • 流密碼與 MAC 函式配對,如 ChaCha20-Poly1305 和 XChaCha20-Poly1305,

ChaCha20 和 XChaCha20

ChaCha20是由Daniel J. Bernstein設計的流密碼, 密鑰長度為 256 位(32 位元組), 密碼需要亂數,不得重復使用 跨使用同一密鑰執行的加密,

有三種變體,由亂數的長度定義:

亂數長度描述最大資料如果隨機亂數和相同的鍵
8 位元組(默認) 由伯恩斯坦設計的原始ChaCha20, 無限制 最多 200 000 條訊息
12 位元組 RFC7539 中定義的 TLS ChaCha20, 256 千兆位元組 最多 130 億條訊息
24 位元組 XChaCha20,仍處于草稿階段, 256 千兆位元組 無限制
這是ChaCha20(Bernstein的版本)如何加密資料的一個例子:

import json
from base64 import b64encode
from Crypto.Cipher import ChaCha20
from Crypto.Random import get_random_bytes

plaintext = b'Attack at dawn'
key = get_random_bytes(32)
cipher = ChaCha20.new(key=key)
ciphertext = cipher.encrypt(plaintext)

nonce = b64encode(cipher.nonce).decode('utf-8')
ct = b64encode(ciphertext).decode('utf-8')
result = json.dumps({'nonce':nonce, 'ciphertext':ct})
print(result)
{"nonce": "IZScZh28fDo=", "ciphertext": "ZatgU1f30WDHriaN8ts="}
這就是您解密它的方式:

import json
from base64 import b64decode
from Crypto.Cipher import ChaCha20

# We assume that the key was somehow securely shared
try:
    b64 = json.loads(json_input)
    nonce = b64decode(b64['nonce'])
    ciphertext = b64decode(b64['ciphertext'])
    cipher = ChaCha20.new(key=key, nonce=nonce)
    plaintext = cipher.decrypt(ciphertext)
   print("The message was " + plaintext)
except (ValueError, KeyError):
    print("Incorrect decryption")
為了擁有符合 RFC7539 標準的 ChaCha20 密碼, 您需要顯式生成 96 位(12 位元組)引數并將其傳遞給:noncenew()

nonce_rfc7539 = get_random_bytes(12)
cipher = ChaCha20.new(key=key, nonce=nonce_rfc7539)

 

警告

ChaCha20不保證您解密的資料的真實性! 換句話說,攻擊者可能會操縱傳輸中的資料, 為了防止這種情況,您還必須使用訊息身份驗證 用于驗證密文的代碼(如 HMAC) (加密然后 Mac),或者,您可以使用ChaCha20_Poly1305

.classCrypto.Cipher.ChaCha20.ChaCha20Cipher(亂數)

ChaCha20(或XChaCha20)密碼物件, 不要直接創建它,請改用 new(),

變數: 亂數 (位元組)– 長度為 8、12 或 24 位元組的亂數
decrypt(密文輸出=無)

解密一段資料,

引數: 密文 (位元組/位元組陣列/記憶體視圖)– 要解密的資料,任何大小,
關鍵字引數:
  輸出 (位元組/位元組陣列/記憶體視圖)– 明文的位置 被寫到,如果為 ,則回傳明文,None
回傳: 如果是,則明文回傳為 , 否則,outputNonebytesNone
encrypt(純文本輸出 = 無)

加密一段資料,

引數: 明文 (位元組/位元組陣列/記憶體視圖)– 要加密的資料,任何大小,
關鍵字引數:
  輸出 (位元組/位元組陣列/記憶體視圖)– 密文的位置 被寫到,如果為 ,則回傳密文,None
回傳: 如果是,則密文回傳為 , 否則,outputNonebytesNone
seek(位置)

查找密鑰流中的某個位置,

引數: 位置 (整數)– 密鑰流中的絕對位置,以位元組為單位,
Crypto.Cipher.ChaCha20.new(**夸格斯)

創建新的 ChaCha20 或 XChaCha20 密碼

關鍵字引數:
 
  • key (bytes/bytearray/memoryview) – 要使用的密鑰, 它必須為 32 位元組長,
  • nonce(bytes/bytearray/memoryview) –

    強制值 不得重用于任何其他加密 使用此密鑰完成,

    對于 ChaCha20,它必須為 8 或 12 個位元組,

    對于 XChaCha20,它必須為 24 位元組長,

    如果未提供,將隨機生成 8 個位元組 (您可以在屬性中找到它們),nonce

回傳:

一個 Crypto.Cipher.ChaCha20.ChaCha20Cipher 物件

轉載:ChaCha20 和 XChaCha20 — PyCryptodome 3.17.0 檔案

ChaCha20-Poly1305 和 XChaCha20-Poly1305

ChaCha20-Poly1305 是具有關聯資料 (AEAD) 的經過身份驗證的密碼, 它與一個 32 位元組的密鑰和一個亂數一起作業 絕不能在同一密鑰下執行的加密中重復使用, 密碼生成一個 16 位元組標記,接收方必須使用該標記來驗證訊息,

該演算法有三種變體,由亂數的長度定義:

亂數長度描述最大明文數如果隨機亂數和相同的鍵
8 位元組 基于伯恩斯坦的原始ChaCha20, 無限制 最多 200 000 條訊息
12 位元組(默認) 在 TLS 中使用并在 RFC7539 中指定的版本, 256 千兆位元組 最多 130 億條訊息
24 位元組 XChaCha20-Poly1305,仍處于草稿階段, 256 千兆位元組 無限制

密碼的 API 及其有限狀態機與分組密碼的現代操作模式相同,

通過呼叫 Crypto.Cipher.ChaCha20_Poly1305.new() 創建新密碼,

以下是 ChaCha20-Poly1305(TLS 版本)如何加密和驗證資料的示例:

 import json
 from base64 import b64encode
 from Crypto.Cipher import ChaCha20_Poly1305
 from Crypto.Random import get_random_bytes

 header = b"header"
 plaintext = b'Attack at dawn'
 key = get_random_bytes(32)
 cipher = ChaCha20_Poly1305.new(key=key)
 cipher.update(header)
 ciphertext, tag = cipher.encrypt_and_digest(plaintext)

 jk = [ 'nonce', 'header', 'ciphertext', 'tag' ]
 jv = [ b64encode(x).decode('utf-8') for x in (cipher.nonce, header, ciphertext, tag) ]
 result = json.dumps(dict(zip(jk, jv)))
 print(result)
{"nonce": "4EE/9uqhoZ3mQXmm", "header": "aGVhZGVy", "ciphertext": "Wmmo4Vzn+eS3tUPv2a8=", "tag": "/FgVbM8qhzssPRY80T0iVA=="}
在上面的示例中,會自動創建一個 96 位(12 位元組)亂數, 可以將其作為物件中的成員進行訪問,noncecipher

這是您解密資料并檢查其真實性的方式:

 import json
 from base64 import b64decode
 from Crypto.Cipher import ChaCha20_Poly1305

 # We assume that the key was securely shared beforehand
 try:
     b64 = json.loads(json_input)
     jk = [ 'nonce', 'header', 'ciphertext', 'tag' ]
    jv = {k:b64decode(b64[k]) for k in jk}

    cipher = ChaCha20_Poly1305.new(key=key, nonce=jv['nonce'])
    cipher.update(jv['header'])
    plaintext = cipher.decrypt_and_verify(jv['ciphertext'], jv['tag'])
    print("The message was: " + plaintext)
 except (ValueError, KeyError):
    print("Incorrect decryption")

 

.classCrypto.Cipher.ChaCha20_Poly1305.ChaCha20Poly1305Cipher(亂數)?

ChaCha20-Poly1305 和 XChaCha20-Poly1305 密碼物件, 不要直接創建它,請改用 new(),

變數: 亂數 (位元組字串)– 長度為 8、12 或 24 位元組的亂數
decrypt(密文輸出=無)?

解密一段資料,

引數: 密文 (位元組/位元組陣列/記憶體視圖)– 要解密的資料,任何大小,
關鍵字引數:
  輸出 (位元組/位元組陣列/記憶體視圖)– 明文的位置 被寫到,如果為 ,則回傳明文,None
回傳: 如果是,則明文回傳為 , 否則,outputNonebytesNone
decrypt_and_verify(密文received_mac_tag)?

一步執行 decrypt() 和 verify(),

引數:
  • 密文(位元組/位元組陣列/記憶體視圖)– 要解密的資料片段,
  • received_mac_tag(位元組)— 這是從發送方接收的 16 位元組二進制 MAC,
回傳:

解密的資料(作為bytes)

提高:

值錯誤 – 如果 MAC 不匹配,郵件已被篡改 或者密鑰不正確,

digest()?

計算二進制身份驗證標記 (MAC),

回傳: MAC 標記,作為 16 .bytes
encrypt(純文本輸出 = 無)?

加密一段資料,

引數: 明文 (位元組/位元組陣列/記憶體視圖)– 要加密的資料,任何大小,
關鍵字引數:
  輸出 (位元組/位元組陣列/記憶體視圖)– 密文的位置 被寫到,如果為 ,則回傳密文,None
回傳: 如果是,則密文回傳為 , 否則,outputNonebytesNone
encrypt_and_digest(明文)?

在一個步驟中執行 encrypt() 和 digest(),

引數: 明文 (位元組/位元組陣列/記憶體視圖)– 要加密的資料,任何大小,
回傳: 包含兩個物件的元組:bytes
  • 密文,長度與明文相同
  • 16 位元組 MAC 標簽
hexdigest()?

計算可列印的身份驗證標記 (MAC),

此方法類似于摘要(),

回傳: MAC 標記,作為十六進制字串,
hexverify(hex_mac_tag)?

驗證可列印的身份驗證標記 (MAC),

此方法類似于 verify(),

引數: hex_mac_tag (字串)– 這是可列印的 MAC,
提高值錯誤:
  如果 MAC 不匹配,郵件已被篡改 或者密鑰不正確,
update(資料)?

保護關聯的資料,

關聯資料(也稱為其他經過身份驗證的資料 - AAD) 是必須保持清晰的資訊部分,而 仍然允許接收器驗證其完整性, 資料包標頭就是一個例子,

關聯的資料(可能拆分為多個段)為 在呼叫 decrypt() 或 encrypt() 之前輸入到 update() 中, 如果沒有關聯的資料,則不呼叫 update(),

引數: assoc_data (位元組/位元組陣列/記憶體視圖)– 一段關聯資料,它的大小沒有限制,
verify(received_mac_tag)?

驗證二進制身份驗證標記 (MAC),

接收方在最后呼叫此方法, 檢查相關資料(如果有)和解密 訊息有效,

引數: received_mac_tag (位元組/位元組陣列/記憶體視圖)– 這是從發送方收到的 16 位元組二進制 MAC,
提高值錯誤:
  如果 MAC 不匹配,郵件已被篡改 或者密鑰不正確,
Crypto.Cipher.ChaCha20_Poly1305.new(**夸格斯)?

創建新的 ChaCha20-Poly1305 或 XChaCha20-Poly1305 AEAD 密碼,

關鍵字引數:
 
  • key – 要使用的密鑰,它必須為 32 位元組長,
  • 亂數 –

    不得重用于任何其他加密的值 使用此密鑰完成,

    對于 ChaCha20-Poly1305,它的長度必須為 8 或 12 個位元組,

    對于 XChaCha20-Poly1305,它必須為 24 位元組長,

    如果未提供,將隨機生成 12 個 (您可以在屬性中找到它們),bytesnonce

回傳:

一個物件Crypto.Cipher.ChaCha20.ChaCha20Poly1305Cipher

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/546172.html

標籤:Python

上一篇:專案中多級快取設計實踐總結

下一篇:基于Python實作自動刷抖音,進行人臉識別,不是小姐姐自動劃走下一個!

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more