技术经验分享:affineCipherandafineHacker

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 技术经验分享:affineCipherandafineHacker

乘数加密法


在讲仿射加密法之前,我们先说乘数加密法


凯撒加密法中,加密和解密符号涉及把他们转化成数字,加上或者减去密钥,再把新的数字换成符号


如果我们不使用加而用乘法,可以吗?当然,只需要用mod运算把一个大的整数唯一映射到一个字符


就好了


乘数加密法的优势是,可以使用一个很大的key, 而不局限于凯撒加密法的密钥空间 0~25


缺点是A总是映射到A,为了克服这种缺点,我们再使用一次凯撒加密法即可


缺点是并不是所有key都能使用


比如若选择key=8,则有


A


B


C


D


E


F


G


H


I


J


K


L


M


A


I


Q


Y


G


O


W


E


M


U


C


K


S


N


O


P


Q


R


S


T


U


V


W


X


Y


Z


A


I


Q


Y


G


O


W


E


M


U


C


K


S


这甚至不是一一映射!!没有用


仿射加密法


乘数加密法+凯撒加密法 = 仿射加密法


keyA应当满足一定条件:


  密钥A数字和符号集的大小必须互质,也就是说gcd(密钥A, 符号集大小) = 1


模算术运算 加法and乘法


模b运算中,整数x的乘法逆元是y:使得(x × y)mod b = 1


模b运算中,整数x的加法逆元是y:使得(x + y)mod b = 0


一般来说,只有当一个整数与n互素的时候,他才会在Zn中存在一个乘法逆元


使用扩展欧几里得算法可以方便地找到一个数字的模逆,python实现:


def findModInverse(a, m):


# Returns the modular inverse of a % m, which is


# the number x such that ax % m = 1


# 如果a 和 m 不互质,则不存在模逆


if gcd(a, m) != 1:


return None # no mod inverse if a & m aren't relatively prime


# Calculate using the Extended Euclidean Algorithm:


u1, u2, u3 = 1, 0, a


v1, v2, v3 = 0, 1, m


while v3 != 0:


q = u3 // v3 # // is the integer division operator


v1, v2, v3, u1, u2, u3 = (u1 - q v1), (u2 - q v2), (u3 - q v3), v1, v2, v3


return u1 % m


输出:




15


]> cryptomath.findModInverse(37, 41)


10


]> cryptomath.findModInverse(8953851, 26)


17


]>


前面是开胃菜,接下来要展示点真正下饭的东西了!


仿射加密法


我们要使用两个密钥,记住一个数是方便地。使用简单的数学技巧将一个数分解成两个key


  如使用key = 2023 则:


    keyA = key // len(密文符号集) 2023 // 95 = 21


    keyB = key % len(密文符号集) 2023 % 95 = 28


    显然 keyA len(密文符号集) + keyB = key (21 95) + 28 = 2023


这两个密钥显然不能在程序中出差错,所以用元组保存是可取的。


元组是python中的一种数据类型。可以通过索引和分片来访问,但是很重要的一点,元组里面的值不能被更改!


对于生成的密钥,我们要确认其可行性:


keyA不能为1


keyB不能为0


keyA、keyB必须大于0,keyB不大于ken(密文符号集) -1


最重要的一点,满足keyA必须与密文符号集的大小互质,才能使得这是一个一一映射。


仿射加密算法


# Affine Cipher


# (BSD Licensed)


'''


1.The affine cipher can be thought of as the combination of which two other ciphers?


2.What is a tuple?


3.How is a tuple different from a list?


4.Why does having Key A be 1 make the affine cipher weak?


5.Why does having Key B be 0 make the affine cipher weak?


answer


1.The shift and multiplicative ciphers.


2.A data type in Python similar to lists, except immutable.


3.Tuples are immutable, meaning they cannot have their items changed.


4.Because multiplying the symbol's number by 1 does not change it.


5.Because adding 0 to the symbol's number does not change it.


'''


import sys, pyperclip, cryptomath, random


SYMBOLS = """ !"#$%&'()+,-./0123456789:;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ【\】^_`abcdefghijklmnopqrstuvwxyz{|}~""" # note the space at the front


def main():


myMessage = """"A computer would deserve to be called intelligent if it could deceive a human into believing that it was human." -Alan Turing"""


myKey = 2023


myMode = 'encrypt' # set to 'encrypt' or 'decrypt'


if myMode == 'encrypt':


translated = encryptMessage(myKey, myMessage)


elif myMode == 'decrypt':


translated = decryptMessage(myKey, myMessage)


print('Key: %s' % (myKey))


print('%sed text:' % (myMode.title()))


print(translated)


pyperclip.copy(translated)


print('Full %sed text copied to clipboard.' % (myMode))


def getKeyParts(key):


keyA = key // len(SYMBOLS)


keyB = key % len(SYMBOLS)


return (keyA, keyB)


def checkKeys(keyA, keyB, mode):


if keyA == 1 and mode == 'encrypt':


sys.exit('The affine cipher becomes incredibly weak when key A is set to 1. Choose a different key.')


if keyB == 0 and mode == 'encrypt':


sys.exit('The affine cipher becomes incredibly weak when key B is set to 0. Choose a different key.')


if keyA < 0 or keyB < 0 or keyB > len(SYMBOLS) - 1:


sys.exit('Key A must be greater than 0 and Key B must be between 0 and %s.' % (len(SYMBOLS) - 1))


if cryptomath.gcd(keyA, len(SYMBOLS)) != 1:


sys.exit('Key A (%s) and the symbol set size (%s) are not relatively prime. Choose a different key.' % (keyA, len(SYMBOLS)))


def encryptMessage(key, message):


keyA, keyB = getKeyParts(key)


checkKeys(keyA, keyB, 'encrypt')


ciphertext = ''


for symbol in message:


if symbol in SYMBOLS:


# encrypt this symbol


symIndex = SYMBOLS.find(symbol)


# 乘数加密 + 凯撒加密 = 仿射加密方法


ciphertext += SYMBOLS【(symIndex keyA + keyB) % len(SYMBOLS)】


else:


#如果在符号集中没有这个特殊符号,不能舍弃,保留,保证密文和明文等长


ciphertext += symbol # just append this symbol unencrypted


return ciphertext


def decryptMessage(key, message):


keyA, keyB = getKeyParts(key)


checkKeys(keyA, keyB, 'decrypt')


plaintext = ''


#需要找到keyA的乘法模逆


modInverseOfKeyA = cryptomath.findModInverse(keyA, len(SYMBOLS))


for symbol in message:


if symbol in SYMBOLS:


# decrypt this symbol


symIndex = SYMBOLS.find(symbol)


plaintext += SYMBOLS【(symIndex - keyB) modInverseOfKeyA % len(SYMBOLS)】


else:


plaintext += symbol # just append this symbol undecrypted


return plaintext


def getRandomKey():


while True:


keyA = random.randint(2, len(SYMBOLS))


keyB = random.randint(2, len(SYMBOLS))


if cryptomath.gcd(keyA, len(SYMBOLS)) == 1:


return keyA len(SYMBOLS) + keyB


# If affineCipher.py is run (instead of imported as a module) call


# the main() function.


if name == 'main':


main()


输出:


Key: 2023


Encrypted text:


fX}(rTH

Full encrypted text copied to clipboard.


PS D:\PiaYie\jczhang\密码学\py密码学编程教学代码

暴力破译仿射密码


那么,暴力破译的话,就必须明白仿射加密法有多少个密钥?


keyB: “回调”受限:1 ~ len(密文符号集)


keyA: 与len(密文符号集)互质的数,是否也会出现“回调”的情况?


//代码效果参考:http://www.jhylw.com.cn/595335755.html

SYMBOLS = """ !"#$%&'() +,-./0123456789:;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ【\】^_`abcdefghijklmnopqrstuvwxyz{|}~""" # note the space at the front

len(SYMBOLS) = 95


测试一下


# This program proves that the keyspace of the affine cipher is limited


# to len(SYMBOLS) ^ 2.


import affineCipher, cryptomath


message = 'Make things as simple as possible, but not simpler.'


for keyA in range(2, 100):


key = keyA len(affineCipher.SYMBOLS) + 1


if cryptomath.gcd(keyA, len(affineCipher.SYMBOLS)) == 1:


print(keyA, affineCipher.encryptMessage(key, message))


输出:


n-2020.7.96456\pythonFiles\lib\python\debugpy\launcher' '49271' '--' 'd:\PiaYie\jczhang\SJTU\密码学\py密码学编程教学代码\affineKeyTest.py'


2 {DXL!jRT^Ph!Dh!hT\bZL!Dh!bhhTFZL9!Flj!^j!hT\bZLf=


3 I&D2!;>M8!&!>JSG2!&!SP\>)G2E!)b!MP!>JSG2YK


4 vg0w!T$(@T!P(8D4wLY


6 q+gC!>U【yO8!+8!8【s&mC!+8!& 88【1mCi!1D>!y >!8【s&mC2u


7 ?lS)!3>Eh7,!l,!,EavZ)!l,!vo,,EsZ)u!s:3!ho3!,EavZ)%$


8 lN?n!('/W~ !N ! /OgGn!N !g /VGn"!V0(!W(! /OgGnw2


9 :0+T!|oxFfs!0s!sx=X4T!0s!XOssx94T.!9&|!FO|!sx=X4Tj@


11 5Sb !fAL$6【!S【!【Lx:m !S【!:/【【L^m F!^qf!$/f!【Lx:m P\


12 b5Ne!【*6r}O!5O!O6f+Ze!5O!+~OO6AZeR!Ag【!r~【!O6f+ZeCj


13 0v:K!Pr aeC!vC!C T{GK!vC!{nCC $GK^!$】P!anP!C T{GK6x


14 】X&1!E【iPM7!X7!7iBl41!X7!l^77if41j!fSE!P^E!7iBl41)'


16 X{】!/-=.|~!{~!~=}Nm!{~!N>~~=,m#!,?/!.>/!~=}Nm\nC


17 &】IB!$u'|dr!】r!r'k?ZB!】r!?.rr'nZB/!n5$!|.$!r'k?ZBaQ


18 S?5(!x^pkLf!?f!fpY0G(!?f!0}ffpQG(;!Q+x!k}x!fpY0G(T


21 {DX9!Wx.8cB!DB!B.#bm9!DB!bMBB.Ym9!YlW!8MW!B.#bm9-


22 I&D~!Law'K6!&6!6wpSZ~!&6!S=66w<Z~k!<bL!'=L!6wpSZ~ 8


23 vg0d!AJau3!g!a^DGd!g!D-**a~Gdw!~XA!u-A!a^DGdrF


24 DI{J!63Kdz}!I}!}KL54J!I}!5|}}Ka4J$!aN6!d|6!}KL54JeT


26 ?lSu! d~BJe!le!e~(vmu!le!v\ee~'mu<!': !B\ !e~(vmuKp


27 lN?【!tMh12Y!NY!YhugZ【!NY!gLYYhiZ【H!i0t!1Lt!YhugZ【>~


28 :0+A!i6R yM!0M!MRcXGA!0M!X

29 gqv'!^~<naA!qA!A<QI4'!qA!I,AA</4'`!/{^!n,^!A

31 b5NR!HPoL1)!5)!)o-+mR!5)!+k))oTmRx!TgH!LkH!)o-+mRiW


32 0v:8!=9Y;x|!v|!|Yz{Z8!v|!{【||Y7Z8%!7】=!;【=!|Yz{Z8\e


33 】X&}!2"C`p!Xp!pChlG}!Xp!lKppCyG}1!yS2!K2!pChlG}Os


34 +:qc!'j-xHd!:d!d-V】4c!:d!】;dd-\4c=!\I'!x;'!d-V】4cB"


36 &】I/!p<VwL!】L!L2?m/!】L!?zLL"m/U!"5p!Vzp!L2?m/(>


37 S?5t!e%JE@!?@!@J 0Zt!?@!0j@@JdZta!d+e!Eje!@J 0ZtzL


39 Nbl@!OV}#/(!b(!(}【q4@!b(!qJ((}4@y!vO!#JO!(}【q4@h</p> <p>41 I&Dk!9(Q^o!&o!oQ7Smk!&o!SooQOmk2!Ob9!`9!oQ7SmkF%


42 vg0Q!.p;OFc!gc!c;%DZQ!gc!Dycc;2ZQ>!2X.!Oy.!c;%DZQ93


43 DI{7!#Y%>.W!IW!W%r5G7!IW!5iWW%tG7J!tN#!>i#!W%r5G7,A


44 q+g|!wBn-uK!+K!Kn&4|!+K!&YKKnW4|V!WDw!-Yw!Kn&4|~O


46 lN?H!asBjE3!N3!3BgmHdk


47 :0+.!V\,Y-'!0'!',XZ.!0'!X)'',Z.z!&V!Y)V!',XZ.Wy


48 gqvs!KEuHtz!qz!zuwIGs!qz!IxzzuBGs'!B{K!HxK!zuwIGsJ(


49 5SbY!@._7\n!Sn!ne:4Y!Sn!:hnn%4Y3!%q@!7h@!n_e:4Y=6


51 0v:%!_3t,V!vV!V3A{m%!vV!{HVV3Jm%K!J】!tH!V3A{m%#R


52 】X&j!~H|csJ!XJ!J|/lZj!XJ!l8JJ|-ZjW!-S~!c8~!J|/lZju`


53 +:qP!s1fR【>!:>!>f|】GP!:>!】(]foGPc!oIs!R(s!>f|】GPhn


54 X{】6!hyPAC2!{2!2PjN46!{2!Nw22PR46o!R?h!Awh!2PjN46【|


56 S?5a!RK$~ry!?y!y$F0ma!?y!0Wyy$wma(!w+R!~WR!y$F0maA9


58 Nbl-!|W\Ba!ba!aW"qG-!ba!q7aaW=G-@!=v

59 {DXr!1eAKU!DU!UAob4r!DU!b'UUA 4rL! l1!K'1!UAob4ryc


61 vg0>!z7t)Y=!g=!=tKDm>!g=!Df==tEm>d!EXz!)fz!=tKDm>_


62 DI{$!o

相关文章
|
20天前
|
运维 Kubernetes 网络协议
运维之道:从新手到专家的成长之路
【10月更文挑战第21天】 本文旨在探讨运维领域的成长路径,通过分享个人经历和行业见解,为读者提供一条从入门到精通的清晰路线图。我们将从基础技能的学习开始,逐步深入到高级技巧的应用,最终达到专业水平的提升。文章强调了持续学习和实践的重要性,并鼓励读者在面对挑战时保持积极态度,不断探索未知领域。
22 6
|
17天前
|
运维 Prometheus 监控
运维之道:从新手到专家的旅程
【10月更文挑战第24天】 在数字化时代,运维工作如同一座桥梁,连接着技术与业务,确保系统的稳定运行。本文将带你踏上一段从运维新手成长为专家的旅程,探索运维的核心价值、技能提升路径以及面对挑战时的应对策略。通过深入浅出的语言和生动的案例,让你领略运维世界的奥秘与魅力。
11 0
|
2月前
|
Java 关系型数据库 API
后端开发之道:从新手到专家的蜕变之旅
在数字化时代的浪潮中,后端开发如同一座桥梁,连接着数据世界的每一个角落。本文将带领读者踏上一段从零基础到精通后端开发的旅程,探索编程语言的选择、框架的应用、数据库的设计以及API的开发等关键知识点。我们将以通俗易懂的语言,结合条理清晰的结构,逐步揭开后端开发的神秘面纱,让每一位读者都能在这段旅途中找到属于自己的位置和方向。
|
5月前
技术经验分享:comparisonmethodviolates必现
技术经验分享:comparisonmethodviolates必现
25 0
技术经验分享:comparisonmethodviolates必现
|
5月前
|
应用服务中间件 PHP nginx
技术经验分享:fastcgimain
技术经验分享:fastcgimain
|
5月前
|
存储 缓存 NoSQL
技术经验分享:braum的使用
技术经验分享:braum的使用
23 0
|
5月前
|
C++
技术经验分享:C++程序设计的技巧
技术经验分享:C++程序设计的技巧
37 0
|
5月前
|
JavaScript
技术经验分享:javascriptvar的理解
技术经验分享:javascriptvar的理解
24 0
|
5月前
|
移动开发 HTML5
技术经验分享:CQUOJ9766ChillyWilly
技术经验分享:CQUOJ9766ChillyWilly
22 0
|
5月前
|
前端开发 JavaScript 容器
技术经验分享:CSSFIXEDpornjavhd
技术经验分享:CSSFIXEDpornjavhd
75 0