我的任务是密码保护Java应用程序,而对真正的安全性的关注最少。因此,在文本文件中存储用户名/密码对然后加密它似乎是明智的。对于加密,使用XOR密码似乎是合适的,因为它们简单快速(记住 - 它只是不鼓励临时用户,而不是防弹)。
我编写了所有相应的Java,然后意识到我需要一种方法来加密配置文件。我写了一个额外的方法,但使用超过一次或两次(并且似乎仅适用于某些输入)是笨重的,所以我认为最好用Python编写一些内容,以便在REPL中播放。
这就是我最终的结果:
from itertools import izip, cycle
KEY = "stackoverflow"
def encrypt(text):
return ''.join(chr(ord(x) ^ ord(y)) for (x,y) in izip(text,cycle(KEY)))
def decrypt(text):
return encrypt(text)
def export(users, file):
with open(file, "w") as f:
for user, password in users.items():
f.write(encrypt('"%s" "%s"'%(user, password)) + "\n")
def import_data(file):
with open(file) as f:
return [decrypt(i) for i in f.readlines()]
从表面上看,它有效:
>>> x = encrypt("Hello world!")
>>> x
';\x11\r\x0f\x04O\x01\n\x00\n\x08N'
>>> decrypt(x)
'Hello world!'
但事情开始分崩离析:
>>> export({"foo" : "bar", "baz" : "quux", "spam" : "eggs"}, "users.dat")
>>> import_data("users.dat")
['"foo" "bar"e', '"baz" "quux"}', '"spam" "eggs"y']
以下是vim如何读取它 -
然后:
>>> export({"what" : "not", "this" : "that", "admin_istrator" : "quux"}, "users2.dat")
>>> import_data("users2.dat")
['"thi', "k97$ma{~'l", '"what" "not"}', '"admin_istrator" "quux', '7~']
的Vim:
我想到我可能遇到一个字符的加密形式是换行符的问题,但据我所知,这并不能解释第一个例子中的古怪行为或 all 在第二个中古怪的行为。
关于换行符,我的B计划是加密整个文件 - 换行符和全部 - 然后将其重新填充,解密,将其拆分为“\ n”,然后继续进行基于行的解析。
提前致谢。
更新:这是我对B计划的实施(前两段描述)。
def import2(file):
with open(file) as f:
return decrypt(f.read())
然后:
>>> export({"foo" : "bar", "this" : "that", "admin_istrator" : "letmein"}, "users2.dat")
>>> import2("users2.dat")
'"this" "that"y%smg&91uux!}"admin_istrator" "letmein"y'
更新二:二进制。
[代码与上述相同,只是所有open
都是open(file, "rb")
或open(file, "wb")
。]
>>> export({"foo" : "bar", "this" : "that", "admin_istrator" : "letmein"}, "users2.dat")
>>> import2("users2.dat")
'"this" "that"y%smg&91uux!}"admin_istrator" "letmein"y'
>>> import_data("users2.dat")
['"t', "k97$ma{~'", '"foo" "bar"', '"admin_istrator" "letmein"']
最终更新:Base 64,其他恶作剧。
def import2(file):
with open(file, "rb") as f:
return filter(str.strip, [decrypt(i) for i in f.readlines()])
其中encrypt
和decrypt
encode
位于/ decode
base 64。
答案 0 :(得分:1)
您正在尝试将二进制文件存储在文本模式文件中。使用open(file, "wb")
进行写入,使用open(file, "rb")
进行阅读,以二进制模式打开文件并解决问题。
在文本模式下,每个"\r"
,"\n"
和"\r\n"
序列都被视为换行符,因此它们会转换为您的本地操作系统行结束约定("\r\n"
for Windows,{ {1}}用于Unix,"\n"
用于旧Mac)。如果您从文本文件中读取它们,您将始终获得"\r"
,如果您编写它们,我不记得实际行为,但您肯定会弄乱而不是数据:)
使用XOR加密,很可能会遇到这种情况:)
如果您被迫不使用二进制文件,请尝试使用base64编码(例如"\n"
)。解码使用"some\0te\n\nxt with bi\x01naries".encode('base64')
(谢谢,船长明显!)。
答案 1 :(得分:0)
问题是你没有读取你编纂的相同数据(在加密后添加'\ n'),只需对你读过的数据做一个rstrip():
def import_data(file):
with open(file) as f:
return [decrypt(i.rstrip()) for i in f.readlines()]
答案 2 :(得分:0)
您可以通过加密换行符来修复它,而不是在行之间重置键
from itertools import izip, cycle
KEY = "stackoverflow"
def encrypt(text):
return ''.join(chr(ord(x) ^ ord(y)) for (x,y) in izip(text,key))
def decrypt(text):
return encrypt(text)
def export(users, file):
with open(file, "w") as f:
for user, password in users.items():
f.write(encrypt('"%s" "%s"\n'%(user, password)))
def import_data(file):
with open(file) as f:
return [decrypt(i) for i in f]
key = cycle(KEY)
export({"foo" : "bar", "baz" : "quux", "spam" : "eggs"}, "users.dat")
key = cycle(KEY)
for row in import_data("users.dat"):
print row
这应该变成一个类,key
将是一个实例变量而不是全局,因为它在这里