哪種算法是最簡單的可逆固定大小保長對稱“密碼學”,碰撞機率低?
我不是數學家/密碼學家,所以我不能充分利用這個其他問題,而且似乎(?)比我有更多的要求(SAC)。
我說簡單,因為我需要它有一個快速的實現,也因為安全性在我的案例中是無關緊要的。然而,低碰撞機率是重要的要求。
MD5(textA + keyB) = MD5(textC + keyD)
低我的意思是與不同文本和鍵的機率相當的東西。text 和 key 都有固定的大小,例如 16 字節。這裡的加號表示串聯。例如,AES 適合此任務,但它比 MD5 慢 100 倍。當然,MD5是不可逆的,所以不能用。
另一個要求是它也應該是不可交換的,
encrypt(textA, keyB) != encrypt(keyB, textA)
否則我想我可以只使用 XOR 逐位運算。編輯
到目前為止,我所做的是在 Python 中實現以下 128 位“密碼學”。但是,有很多碰撞:
def pepper(msg): bit = (msg & 0b1111111) % 120 + 8 return msg ^ (2 ** bit) def rev_hash(msg_int, key_int): """A "reversible hash", the nightmare of cryptologists.""" lshift = (((msg_int & mask_127ones) << 1) | (msg_int >> 127)) result = lshift ^ key_int return pepper(result) def rev_unhash(encrypted_msg_int, key_int): xor = pepper(encrypted_msg_int) ^ key_int rshift = (xor >> 1) | ((xor & 1) << 127) return rshift
所要求的由具有 128 位密鑰和塊大小的塊密碼來實現(但請注意,當其中一個密鑰已知時發生衝突是微不足道的)。我們不能使用流密碼(即使使用兩個密鑰,衝突也是微不足道的),也不能使用 RSA 加密中使用的 OAEP 填充(在實踐中,它不是長度保持,也不是很簡單)。
AES-128 是一種合適的分組密碼,而且速度不慢。它通常在純軟體中以每核每秒超過 100 萬次 16 字節加密的速度執行,有時是 20M(用於重複使用相同的密鑰),甚至 200M(使用 AES-NI 硬體)。當然,這不適用於在純 python 中實現的 AES。
但是從python 中使用 AES很容易,即使我們使用問題的 message-as-int 介面。
from Crypto.Cipher import AES def rev_hash(msg_int, key_int): return int.from_bytes(AES.new(key_int.to_bytes(16,'big'),AES.MODE_ECB).encrypt(msg_int.to_bytes(16,'big')),'big') def rev_unhash(encrypted_msg_int, key_int): return int.from_bytes(AES.new(key_int.to_bytes(16,'big'),AES.MODE_ECB).decrypt(encrypted_msg_int.to_bytes(16,'big')),'big')
這可能是可以接受的快。
to_bytes
如果我們使用本機字節串介面(避免andfrom_bytes
)並修改介面以在使用相同密鑰的呼叫中重用 AES 實例,那將很難被擊敗。可以製作簡單、快速、安全的分組密碼:最多選擇其中兩個功能。在這裡,其中一個要求可以理解為:進行沖突的難度必須與在附加了不同(秘密)密鑰的 MD5 雜湊之間進行沖突的難度相當,即使兩個密鑰手頭都有許多明文/密文對。結合可逆性,這意味著 64 位安全性,因為 MD5 在這些條件下仍然具有很強的抗碰撞能力。有了這個要求,就很難做出簡單快速的事情,尤其是在純 python 中。
沒有任何安全要求,這是一個非常簡單的自包含 128 位分組密碼
def rev_hash(msg_int, key_int): for x in [305065944875308933,445871615361279994733287202953785,859072698151683073,893999628687995393356516725455569]: msg_int = (((msg_int>>64)^msg_int^key_int)*x+1)&((1<<128)-1) return msg_int^key_int def rev_unhash(encrypted_msg_int, key_int): encrypted_msg_int ^= key_int for x in [409772003941621297,679237006192346672534347824675841,229702291678999561,786310896237332493342854003018061]: encrypted_msg_int = ((encrypted_msg_int*x-x)&((1<<128)-1))^key_int encrypted_msg_int ^= encrypted_msg_int>>64 return encrypted_msg_int
基本原理:有 5 輪,每輪可逆地作用於整個狀態。每輪使用 XOR 與密鑰,並且(除了最後一輪)模乘以常數(給出左擴散)加上 1 模 2 128, 和左半邊的 XOR 到右半邊(這給出了右擴散,並交替加法和 XOR 以打破線性)。常數被預先計算為四個 18 位隨機素數,這些素數從大約一百萬個中選出,用於具有 33 位模逆,與逆交替。這種依賴輪數的常數的使用有望部分彌補密鑰調度的完全缺失。事情的安排使得加密是緊湊的。解密甚至稍微複雜一些,因為它需要以相反的順序進行。加法避免了使用鍵 0 在零處的靜止點。
速度僅比使用 AES 的第一個範例稍微好一點(例如僅兩倍),但以犧牲安全性為代價。同樣,第一個範例使用重新考慮的界面會更快。