异或加密在“大多数”时间都有效
我的任务是对 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:
我突然想到我可能有字符的加密形式是换行符的问题,但据我所知,这并不能解释第一个示例中的古怪行为或第二个示例中的所有古怪行为。
关于换行符,我的 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")
code>.]
>>> 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()])
其中加密
和解密
编码
采用/解码
基64。
I've been tasked with password-protecting a Java app with minimal concern for real security. So it seemed sensible to store username/password pairs in a text file and then encrypt it. For the encryption, it seemed appropriate to use XOR ciphers because they're easy and fast (remember--it just has to discourage the casual user, not be bulletproof).
I wrote all the appropriate Java, and then realized I needed a way to encrypt the config file. I wrote an additional method, but it was clunky to use more than once or twice (and seemed to only work for some inputs), so I decided it was best to write something in Python, to be played with at a REPL.
This is what I ended up with:
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()]
On the surface, it works:
>>> x = encrypt("Hello world!")
>>> x
';\x11\r\x0f\x04O\x01\n\x00\n\x08N'
>>> decrypt(x)
'Hello world!'
But then things start to fall apart:
>>> export({"foo" : "bar", "baz" : "quux", "spam" : "eggs"}, "users.dat")
>>> import_data("users.dat")
['"foo" "bar"e', '"baz" "quux"}', '"spam" "eggs"y']
And here's how vim reads it -
And then:
>>> 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:
It occurred to me that I might be having a problem with a character's encrypted form being a newline, but as far as I see that doesn't explain the wacky behavior in the first example or all of the wacky behavior in the second one.
Regarding the newlines, my Plan B is to encrypt the entire file--newlines and all--and then slurp it back up, decrypt it, split it on "\n", and proceed with my line-based parsing.
Thanks in advance.
Update: Here's my implementation of Plan B (described two paragraphs ago).
def import2(file):
with open(file) as f:
return decrypt(f.read())
and then:
>>> export({"foo" : "bar", "this" : "that", "admin_istrator" : "letmein"}, "users2.dat")
>>> import2("users2.dat")
'"this" "that"y%smg&91uux!}"admin_istrator" "letmein"y'
Update Two: Binary.
[Code is the same as above, except that all open
s are open(file, "rb")
or 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"']
Final update: Base 64, other shenanigans.
def import2(file):
with open(file, "rb") as f:
return filter(str.strip, [decrypt(i) for i in f.readlines()])
where encrypt
and decrypt
encode
in/decode
base 64.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您正在尝试在文本模式文件中存储二进制文件。使用
open(file, "wb")
进行写入,使用open(file, "rb")
进行读取,以二进制模式打开文件并修复问题。在文本模式下,每个
"\r"
、"\n"
和"\r\n"
序列都被视为换行符,因此它们会被转换转换为本地操作系统行结束约定(Windows 为"\r\n"
,Unix 为"\n"
,Unix 为"\r"
老Mac)。如果你从文本文件中读取它们,你总是会得到"\n"
相反,如果你写它们,我不记得实际的行为,但你肯定也会得到混乱而不是你的数据 :)使用 XOR 加密,您很可能会遇到此类问题 :)
如果您被迫不使用二进制文件,请尝试使用 base64 编码(例如
"some\0te \n\nxt 与bi\x01naries".encode('base64')
)。要解码,请使用.decode
(谢谢,Captain Obvious!)。You are trying to store binary in text mode file. Use
open(file, "wb")
for writing andopen(file, "rb")
for reading to open file in binary mode and fix an issue.In text mode every
"\r"
,"\n"
and"\r\n"
sequences are treated as newlines so they are converted into your local OS line ending convention ("\r\n"
for Windows,"\n"
for Unix,"\r"
for old Macs). In case you read them from text file, you will always get"\n"
instead, in case you write them, I don't remember actual behavior, but you will surely also get mess instead of your data :)And with XOR encryption it's very likely you'll run into this kind of stuff :)
If you are forced not to use binary files, try base64 encoding (e.g.
"some\0te\n\nxt with bi\x01naries".encode('base64')
). To decode use.decode
(thanks, Captain Obvious!).问题是您没有读取您编码的相同数据(您在加密后添加“\n”),只需对您读取的数据执行 rstrip() 即可:
The problem is you are not reading the same data you codified (you add a '\n' after the encryption), just do a rstrip() of the data you read:
您可以通过加密换行符而不是重置行之间的密钥来修复它。
这应该变成一个类,并且
key
将是一个实例变量,而不是像这里一样的全局变量You can fix it by encrypting the newlines and not resetting the key between lines
This should be turned into a class, and
key
would be an instance variable instead of a global as it is here