如果存在加密文件并且有人想要解密,则有几种方法可以尝试。 例如,如果您选择暴力攻击,那很简单:只需尝试所有可能的密钥,您就会找到正确的密钥。对于这个问题,这可能需要太长时间并不重要。 但尝试按键意味着以下步骤:
除了你需要知道用于加密的算法的问题外,我无法想象会怎么做#3。
原因如下:在解密数据后,我得到了一些“其他”数据。如果使用我能理解的语言加密纯文本文件,我现在可以检查结果是否是该语言中的文本。 如果它是一个已知的文件类型,我可以检查特定的文件头。
但是,由于人们试图解密某些秘密内容,如果正确解密,很可能不知道会有什么样的信息。
如果不知道要查找什么,如何检查解密结果是否正确?
答案 0 :(得分:4)
您可以使用像unix
这样的启发式方法file
命令用于检查已知的文件类型。如果你有解密的数据没有可识别的类型,解密它无论如何都无济于事,因为你无法解释它,所以它仍然像加密一样好。
答案 1 :(得分:4)
就像你建议的那样,人们会期望明文具有某种已知的格式,例如,JPEG图像,PDF文件等。这个想法是,给定的密文不可能被解密为有效的JPEG图像和有效的PDF文件(但见下文)。
但实际上并不重要。当人们谈论密码系统 secure 时,一个(粗略地)谈论你能够猜测对应于给定密文的明文的可能性。所以我选择随机消息 m 并加密它 c = E ( m )。我给你 c ,如果你不能猜测 m ,那么我们说密码系统是安全的,否则它就坏了。
这只是一个简单的安全定义。还有其他定义要求系统能够hide known plaintexts(语义安全):你给我两条消息,我加密其中一条消息,你将无法分辨我选择的消息。
关键是,在这些定义中,我们并不关心明文的格式,我们要求的是你无法猜出加密的明文。 所以没有第3步: - )
如果不考虑你的第3步,我们会尽可能清楚地提出安全问题:而不是争论猜测你使用哪种格式(zip,gzip,bzip2,...)是多么困难,我们只讨论与猜测键的可能性相比,打破系统的几率。这是一个old principle,您应该将所有安全性集中在密钥中 - 当您唯一的假设是密钥的保密时,它会大大简化事情。
最后,请注意,由于所有密钥都是合法的,因此您无法验证是否拥有正确的密钥。 one-time pad是一个极端的例子:你用明文 m ,选择一个完全随机的密钥 k 并将密文计算为 c < / em> = m XOR k 。这为您提供了一个完全随机的密文,它非常安全(唯一完全安全的密码系统,顺便说一句)。
搜索加密密钥时,您无法知道何时找到了正确的加密密钥。这是因为 c 可以是与 m 长度相同的任何文件的加密:如果使用密钥*加密消息 m' k'= c XOR m'你会看到你再次获得相同的密文,因此你无法知道 m 或 m'是原始信息。
而不是考虑排他性或者,你可以想到这样的一次性垫:我给你42号并告诉你这是两个整数的总和(负,正,你不知道)。一个整数是消息,另一个是密钥,42是密文。如上所述,您猜测密钥是没有意义的 - 如果您希望消息为100,则声明密钥为-58,如果您希望消息为0,则声明密钥为42,等等。一次性打击垫的工作方式与此类似,但改为使用位值。
关于在一次性密码中重用密钥:让我说我的密钥是7,你看到密文10和20,对应于明文3和13.从单独的密文,你现在知道了明文的差异是10.如果你以某种方式获得其中一个明文的知识,你现在可以得到另一个!如果数字对应于单个字母,您可以开始查看几个这样的差异,并尝试解决最终的填字游戏(或者让程序根据相关语言的频率分析来完成)。
答案 2 :(得分:2)
我不久前写了一个工具,通过简单地检查字节值的分布来检查文件是否可能加密,因为加密文件应该与随机噪声无法区分。这里的假设是,不正确解密的文件保留随机性,而正确解密的文件将表现出结构。
#!/usr/bin/env python
import math
import sys
import os
MAGIC_COEFF=3
def get_random_bytes(filename):
BLOCK_SIZE=1024*1024
BLOCKS=10
f=open(filename)
bytes=list(f.read(BLOCK_SIZE))
if len(bytes) < BLOCK_SIZE:
return bytes
f.seek(0, 2)
file_len = f.tell()
index = BLOCK_SIZE
cnt=0
while index < file_len and cnt < BLOCKS:
f.seek(index)
more_bytes = f.read(BLOCK_SIZE)
bytes.extend(more_bytes)
index+=ord(os.urandom(1))*BLOCK_SIZE
cnt+=1
return bytes
def failed_n_gram(n,bytes):
print "\t%d-gram analysis"%(n)
N = len(bytes)/n
states = 2**(8*n)
print "\tN: %d states: %d"%(N, states)
if N < states:
print "\tinsufficient data"
return False
histo = [0]*states
P = 1.0/states
expected = N/states * 1.0
# I forgot how this was derived, or what it is suppose to be
magic = math.sqrt(N*P*(1-P))*MAGIC_COEFF
print "\texpected: %f magic: %f" %(expected, magic)
idx=0
while idx<len(bytes)-n:
val=0
for x in xrange(n):
val = val << 8
val = val | ord(bytes[idx+x])
histo[val]+=1
idx+=1
count=histo[val]
if count - expected > magic:
print "\tfailed: %s occured %d times" %( hex(val), count)
return True
# need this check because the absence of certain bytes is also
# a sign something is up
for i in xrange(len(histo)):
count = histo[i]
if expected-count > magic:
print "\tfailed: %s occured %d times" %( hex(i), count)
return True
print ""
return False
def main():
for f in sys.argv[1:]:
print f
rand_bytes = get_random_bytes(f)
if failed_n_gram(3,rand_bytes):
continue
if failed_n_gram(2,rand_bytes):
continue
if failed_n_gram(1,rand_bytes):
continue
if __name__ == "__main__":
main()
我觉得这很合理:
$ entropy.py ~/bin/entropy.py entropy.py.enc entropy.py.zip
/Users/steve/bin/entropy.py
1-gram analysis
N: 1680 states: 256
expected: 6.000000 magic: 10.226918
failed: 0xa occured 17 times
entropy.py.enc
1-gram analysis
N: 1744 states: 256
expected: 6.000000 magic: 10.419895
entropy.py.zip
1-gram analysis
N: 821 states: 256
expected: 3.000000 magic: 7.149270
failed: 0x0 occured 11 times
此处.enc
来源是:
openssl enc -aes-256-cbc -in entropy.py -out entropy.py.enc
.zip
不言自明。
一些警告:
它不会检查整个文件,只检查第一个KB,然后检查文件中的随机块。因此,如果一个文件是随机数据附加说jpeg,它将欺骗该程序。唯一可以确定是否检查整个文件的方法。
根据我的经验,代码可以可靠地检测文件何时未加密(因为几乎所有有用的数据都具有结构),但由于其统计性质,有时可能会误诊加密/随机文件。
正如已经指出的那样,这种分析对于OTP来说是失败的,因为你可以让它说出你想要的任何东西。
使用风险自负,而且肯定不是检查结果的唯一方法。
答案 3 :(得分:0)
其中一种方法是使用zip等标准算法压缩源数据。如果在解密后你可以解压缩结果 - 它被解密了。压缩几乎通常是在加密之前通过加密程序完成的 - 因为这是执行者需要为每次试验重复并在其上浪费时间的另一步,因为加密数据几乎肯定是不可压缩的(使用链式算法压缩后大小不会减少) )。
答案 4 :(得分:0)
如果没有更明确定义的方案,我只能指向cryptanalysis methods。我会说,通常认为验证结果是密码分析的一个简单部分。与解密甚至已知的密码相比,彻底的验证检查只需要很少的CPU。
答案 5 :(得分:-1)
某种程度上这与编程问题无关,它更具有数学性。我在大学里上了一些加密数学课。
如果没有大量的数据点,你无法确认。 当然,如果你的结果是有意义的,并且明确的是用普通英语(或任何使用的语言)有意义,但要回答你的问题。
如果你能够解密,你也应该能够加密。 因此,使用反向解密过程对结果进行加密,如果得到相同的结果,则可能是金色的...如果没有可能出错的话。