Encryption 如何确定所选密码是否正确?

Encryption 如何确定所选密码是否正确?,encryption,cryptography,Encryption,Cryptography,如果存在一个加密文件,并且有人想要解密它,有几种方法可以尝试。 例如,如果您选择暴力攻击,这很简单:只要尝试所有可能的键,您就会找到正确的键。对于这个问题,这可能需要太长时间并不重要。 但尝试按键意味着以下步骤: 选择键 用密钥解密数据 检查解密是否成功 除了需要知道用于加密的算法这一问题之外,我无法想象人们会怎么做 原因如下:解密数据后,我得到一些“其他”数据。在使用我能理解的语言加密的纯文本文件的情况下,我现在可以检查结果是否是该语言中的文本。 如果是已知的文件类型,我可以检查特定的文件头

如果存在一个加密文件,并且有人想要解密它,有几种方法可以尝试。 例如,如果您选择暴力攻击,这很简单:只要尝试所有可能的键,您就会找到正确的键。对于这个问题,这可能需要太长时间并不重要。 但尝试按键意味着以下步骤:

  • 选择键
  • 用密钥解密数据
  • 检查解密是否成功
  • 除了需要知道用于加密的算法这一问题之外,我无法想象人们会怎么做

    原因如下:解密数据后,我得到一些“其他”数据。在使用我能理解的语言加密的纯文本文件的情况下,我现在可以检查结果是否是该语言中的文本。 如果是已知的文件类型,我可以检查特定的文件头

    但是,由于一个人试图解密某个秘密,如果解密正确,很可能不知道会有什么样的信息


    如果不知道要查找什么,如何检查解密结果是否正确?

    你真的在问这样的问题吗? 如果知道里面有什么,你就不需要解密了,对吧

    不知何故,这与编程问题无关,它更像数学问题。我在大学上了一些加密数学课

    如果没有大量的数据点,你无法确认。 当然,如果你的结果是有意义的和清楚的,它在简单的英语(或任何使用的语言)中是有意义的,但要回答你的问题

    如果你能够解密,你也应该能够加密。
    因此,使用解密的反向过程对结果进行加密,如果得到相同的结果,则可能是金色的……如果不是,则可能有错误。

    其中一种方法是使用一些标准算法(如zip)压缩源数据。如果解密后你可以解压结果-它是正确的解密。压缩通常在加密之前由加密程序完成,因为这是另一个步骤,bruteforcer需要在每次试验中重复并浪费时间,而且加密数据几乎肯定是不可压缩的(使用链式算法压缩后大小不会减小).

    您可以使用类似unix的启发式方法

    file
    

    命令不检查已知的文件类型。如果你解密了没有可识别类型的数据,解密对你没有任何帮助,因为你无法解释它,所以它仍然和加密的一样好。

    没有更明确的定义,我只能指出。我想说,人们普遍认为验证结果是密码分析的一个简单部分。与解密一个已知的密码相比,彻底的验证检查只需要很少的cpu。

    正如您所建议的,人们会期望明文具有某种已知的格式,例如JPEG图像、PDF文件等。其想法是,给定的密文不太可能同时被解密为有效的JPEG图像和有效的PDF文件(但见下文)

    但这其实并不重要。当一个人谈论密码系统是安全的时,他(粗略地)谈论你能够猜出与给定密文对应的明文的几率。所以我选择一个随机消息m并对它进行加密c=E(m).我给你c,如果你猜不出m,那么我们说密码系统是安全的,否则它就坏了

    这只是一个简单的安全定义。还有其他定义要求系统能够(语义安全性):你给我两条消息,我加密其中一条,你将无法知道我选择了哪条消息

    关键是,在这些定义中,我们不关心明文的格式,我们所需要的是您无法猜测加密的明文。因此没有步骤3:-)

    通过不考虑您的步骤3,我们尽可能清楚地说明了安全性问题:我们不讨论猜测您使用的格式(zip、gzip、bzip2等)有多难,而只讨论了与猜测密钥的几率相比破坏系统的几率。您应该将所有的安全性都集中在密钥中,这是一个很好的解决方案——当您唯一的假设是密钥的保密性时,它可以极大地简化事情

    最后,请注意,由于所有密钥都是合法的,因此某些加密方案使您无法验证是否拥有正确的密钥。这是这样一个方案的极端例子:取明文m,选择一个完全随机的密钥k,然后计算密文c=mxor k。这给你一个完全随机的密文,它是完全安全的(唯一完全安全的密码系统,顺便说一句)


    搜索加密密钥时,您无法知道何时找到了正确的密钥。这是因为c可以是与m长度相同的任何文件的加密:如果您使用密钥*k'=c XOR m'加密消息m',您将看到您再次获得相同的密文,因此您无法知道m或m'是否是原始消息

    不用考虑异或,你可以这样想一次性pad:我给你数字42,告诉你这是两个整数的和(负,正,你不知道)。一个整数是消息,另一个是密钥,42是密文。如上所述,猜测键是没有意义的——如果希望消息为100,则声明键为-58;如果希望消息为0,则声明键为42,以此类推。一次pad的工作方式与此完全相同,但取决于位值

    关于在一次性键盘中重复使用密钥:假设我的密钥是7,您可以看到密文10和20,对应于明文3和13。仅从密文,你现在知道明文的区别是10。如果你以某种方式获得了一个纯文本的知识,你现在可以推导出另一个!如果这些数字对应于
    #!/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
    
    openssl enc -aes-256-cbc -in entropy.py -out entropy.py.enc