我的密码(python脚本)有多安全?

时间:2012-05-20 10:28:59

标签: python encryption

我已经提出了使用Python的加密例程,我很感激任何人都可以看一下。我正在寻找一些信息;之前是否使用过这种方法/变体,如果是这样,它的名称是什么?它有多安全?

我们的想法是通过互联网传输数据,并使用双方都知道的两个密码进行加密。

它使用SHA1哈希对密码进行编码,然后使用哈希中的字符创建偏移查找表。将偏移值添加到普通字符以生成加密字符。它使用一对一的方法,而不是压缩或添加数据。

如果使用“burger”和“meat”这两个词生成两个SHA1哈希值,那么生成'wPjOew6AdoNOYgjf7y'的字符串'Hello StackOverflow'。

这是整个代码,对于超长字典数组抱歉:S

代码运行使用: win32上的Python 2.7.2(默认,2011年6月12日,15:08:59)[MSC v.1500 32位(英特尔)]

import sys

# burger
sha1_pass1 = '7a86b15480e0a870f0b07a4d23a54ef8f9acac44'

# meat
sha1_pass2 = 'bb40f75a9c6038e0da200fc5c3a6f371c1592c66'

# Characters available to encrypt (can be extended)
valid_chars = '0123456789 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.,!?' * 2

offset = {'00':0,
    '01':1,
    '02':2,
    '03':3,
    '04':4,
    '05':5,
    '06':6,
    '07':7,
    '08':8,
    '09':9,
    '0a':10,
    '0b':11,
    '0c':12,
    '0d':13,
    '0e':14,
    '0f':15,
    '10':16,
    '11':17,
    '12':18,
    '13':19,
    '14':20,
    '15':21,
    '16':22,
    '17':23,
    '18':24,
    '19':25,
    '1a':26,
    '1b':27,
    '1c':28,
    '1d':29,
    '1e':30,
    '1f':31,
    '20':32,
    '21':33,
    '22':34,
    '23':35,
    '24':36,
    '25':37,
    '26':38,
    '27':39,
    '28':40,
    '29':41,
    '2a':42,
    '2b':43,
    '2c':44,
    '2d':45,
    '2e':46,
    '2f':47,
    '30':48,
    '31':49,
    '32':50,
    '33':51,
    '34':52,
    '35':53,
    '36':54,
    '37':55,
    '38':56,
    '39':57,
    '3a':58,
    '3b':59,
    '3c':60,
    '3d':61,
    '3e':62,
    '3f':63,
    '40':64,
    '41':65,
    '42':66,
    '43':0,
    '44':1,
    '45':2,
    '46':3,
    '47':4,
    '48':5,
    '49':6,
    '4a':7,
    '4b':8,
    '4c':9,
    '4d':10,
    '4e':11,
    '4f':12,
    '50':13,
    '51':14,
    '52':15,
    '53':16,
    '54':17,
    '55':18,
    '56':19,
    '57':20,
    '58':21,
    '59':22,
    '5a':23,
    '5b':24,
    '5c':25,
    '5d':26,
    '5e':27,
    '5f':28,
    '60':29,
    '61':30,
    '62':31,
    '63':32,
    '64':33,
    '65':34,
    '66':35,
    '67':36,
    '68':37,
    '69':38,
    '6a':39,
    '6b':40,
    '6c':41,
    '6d':42,
    '6e':43,
    '6f':44,
    '70':45,
    '71':46,    
    '72':47,
    '73':48,
    '74':49,
    '75':50,
    '76':51,
    '77':52,
    '78':53,
    '79':54,
    '7a':55,
    '7b':56,
    '7c':57,
    '7d':58,
    '7e':59,
    '7f':60,
    '80':61,
    '81':62,
    '82':63,
    '83':64,
    '84':65,
    '85':66,
    '86':0,
    '87':1,
    '88':2,
    '89':3,
    '8a':4,
    '8b':5,
    '8c':6,
    '8d':7,
    '8e':8,
    '8f':9,
    '90':10,
    '91':11,
    '92':12,
    '93':13,
    '94':14,
    '95':15,
    '96':16,
    '97':17,
    '98':18,
    '99':19,
    '9a':20,
    '9b':21,
    '9c':22,
    '9d':23,
    '9e':24,
    '9f':25,
    'a0':26,
    'a1':27,
    'a2':28,
    'a3':29,
    'a4':30,
    'a5':31,
    'a6':32,
    'a7':33,
    'a8':34,
    'a9':35,
    'aa':36,
    'ab':37,
    'ac':38,
    'ad':39,
    'ae':40,
    'af':41,
    'b0':42,
    'b1':43,
    'b2':44,
    'b3':45,
    'b4':46,
    'b5':47,
    'b6':48,
    'b7':49,
    'b8':50,
    'b9':51,
    'ba':52,
    'bb':53,
    'bc':54,
    'bd':55,
    'be':56,
    'bf':57,
    'c0':58,
    'c1':59,
    'c2':60,
    'c3':61,
    'c4':62,
    'c5':63,
    'c6':64,
    'c7':65,
    'c8':66,
    'c9':0,
    'ca':1,
    'cb':2,
    'cc':3,
    'cd':4,
    'ce':5,
    'cf':6,
    'd0':7,
    'd1':8,
    'd2':9,
    'd3':10,
    'd4':11,
    'd5':12,
    'd6':13,
    'd7':14,
    'd8':15,
    'd9':16,
    'da':17,
    'db':18,
    'dc':19,
    'dd':20,
    'de':21,
    'df':22,
    'e0':23,
    'e1':24,
    'e2':25,
    'e3':26,
    'e4':27,
    'e5':28,
    'e6':29,
    'e7':30,
    'e8':31,
    'e9':32,
    'ea':33,
    'eb':34,
    'ec':35,
    'ed':36,
    'ee':37,
    'ef':38,
    'f0':39,
    'f1':40,
    'f2':41,
    'f3':42,
    'f4':43,
    'f5':44,
    'f6':45,
    'f7':46,
    'f8':47,
    'f9':48,
    'fa':49,
    'fb':50,
    'fc':51,
    'fd':52,
    'fe':53,
    'ff':54,}


cipher = []

# create the lookup table in cipher
for n in range(40):
    sp1 = sha1_pass1[n]
    sp2 = sha1_pass2[n]

    cipher.append(offset[sp1 + sp2])

# get a user defined string
ask = raw_input('\n\n>>> ')

print ('\n') # make some space

# exit if return
if not ask:
    sys.exit(1)

cipher_pos = 0    

# progress through the user string
for n in range(len(ask)):
    c = ask[n] # character n 

    # get the position of character in string
    p = valid_chars.find(c) 
    if p == -1: sys.exit(1) # if not found then end

    p += cipher[cipher_pos] # add the offset created by the passwords
    cipher_pos += 1
    if cipher_pos == 40: cipher_pos = 0 # reset lookup table position so it repeats

    # get new character
    x = valid_chars[p] 

    sys.stdout.write(x)

sys.stdout.flush()

print('\n')  

2 个答案:

答案 0 :(得分:7)

您的代码是Vigenère cipher,密码长度为40个字符。因此,您只需在链接的维基百科页面上查找其弱点即可。

最明显的攻击是:

  

频率分析

     

一旦知道了密钥的长度,就可以将密文重写成那么多列,每列对应于密钥的单个字母。每列由明文组成,该明文由单个凯撒密码加密;凯撒键(shift)只是用于该列的Vigenère键的字母。使用类似于打破凯撒密码的方法,可以发现密文中的字母。

你有点落后于时代,你的计划已于1553年发明。


您的代码的另一个问题是它是没有初始化向量的synchronous stream cipher。这些密码具有通用的弱点,即不止一次使用密钥允许攻击者减去两个密文,从而消除密钥。结果就是普通文本的不同之处。在实践中,这通常足以获得两个明文。

答案 1 :(得分:2)

您的加密当然不安全。

我认为这是最大的问题:

if cipher_pos == 40: cipher_pos = 0 # reset lookup table position so it repeats

这将导致偏移模式每40个字符重复一次。对于长篇文本,很可能会出现像'the'这样的单词,并将其转换为相同的密文。分析重复部分的密文并猜测原始单词是什么将允许您猜测偏移表的部分。对文本的不同部分重复这种技术最终将为您提供整个偏移表,允许您解密整个消息。

以下计划文字:

the bat the bed the book the boy the bun the can the cake the cap the car the cat the cow the cub the cup the dad the the doy the dog the doll the dust the fan the feet the girl the gun the hall

成为这个密文:

iScC2xLgwtH Eg6 erW U?xwRdRxlB4tYEMeBexq
?0fH0zsucFKeCe3k0j7hXOlm3Y?AqzW6bkYhGcfd
iKrK5wuvzlWhHb5u,j7hXOlG3Y?AqzX6!kYhGcwk
4KbRowLohlGoJblh0jVo0.iFZ?JwGS95dsJ Hdqc
iScC6BwAcFKeCiar7j7hXOpG1Y?Aqz,66w

当字符排列为每行40个字符时,请注意密文中的模式。