Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 什么加密方案满足十进制明文的要求&;密文和保留长度?_C++_Encryption_Cryptography_Aes - Fatal编程技术网

C++ 什么加密方案满足十进制明文的要求&;密文和保留长度?

C++ 什么加密方案满足十进制明文的要求&;密文和保留长度?,c++,encryption,cryptography,aes,C++,Encryption,Cryptography,Aes,我需要一个加密方案,其中明文和密文完全由十进制数字组成 此外,明文和密文的长度必须相同 此外,底层加密算法应为行业标准。 我不介意它是对称的(比如AES)还是非对称的(比如RSA)——但它必须是一个公认的算法,我可以得到FIPS-140认可的库。(否则它将无法通过安全审查阶段) 使用AES OFB可以保留十六进制输入的长度(即每个字节有256个可能值:0x00-->0xFF)。然而,这对我的方法不起作用,因为明文和密文必须完全是十进制的 注:“完全十进制”可能有两种解释——这两种解释都符合我的要

我需要一个加密方案,其中明文和密文完全由十进制数字组成

此外,明文和密文的长度必须相同

此外,底层加密算法应为行业标准。 我不介意它是对称的(比如AES)还是非对称的(比如RSA)——但它必须是一个公认的算法,我可以得到FIPS-140认可的库。(否则它将无法通过安全审查阶段)

使用AES OFB可以保留十六进制输入的长度(即每个字节有256个可能值:0x00-->0xFF)。然而,这对我的方法不起作用,因为明文和密文必须完全是十进制的

注:“完全十进制”可能有两种解释——这两种解释都符合我的要求:

  • 输入和输出字节是字符“0”-->“9”(即字节值:0x30->0x39)
  • 输入和输出字节的值为100(十进制):0x00-->0x99(即BCD)
  • 更多信息: 最大明文和密文长度可能为10位十进制数字。 (即,如果使用“0”-->“9”,则为10个字节;如果使用BCD,则为5个字节)

    考虑以下示例以了解AES失败的原因: 输入字符串是8位数字。 最大8位数字为:9999999 十六进制表示:0x5f5e0ff

    可以将其视为4个字节:

    如果我使用AES OFB,我将得到4字节的输出

    可能的最高4字节密文输出为

    将其转换回整数得到:4294967295 即10位数字

    ==>两位数太长


    最后一件事-任何键/IV所需的长度都没有限制。

    您可以使用八进制格式,它使用数字0-7,三个数字组成一个字节。这不是最节省空间的解决方案,但它又快又简单

    例如:

    Text: Hello world!
    Hexadecimal: 48 65 6C 6C 6F 20 77 6F 72 6C 64 21
    Octal: 110 145 154 154 157 040 167 157 162 154 144 041
    

    (为了清晰起见,添加了空格以分隔字节)

    我不认为可以满足您的要求(无论如何都很容易),尽管可以非常接近

    AES(与大多数加密算法一样)是为处理八位字节(即8位字节)而编写的,它将产生8位字节。一旦完成它的工作,将结果转换为仅使用十进制数字或BCD值是不可能的。因此,您唯一的选择是将输入从十进制或BCD数字转换为尽可能完全填充八位字节的内容。然后可以对其进行加密,最后对输出重新编码,使其仅使用十进制或BCD数字

    当您转换ASCII数字以填充八位字节时,它会稍微“压缩”输入。然后加密将产生与输入相同大小的输出。然后将其编码为仅使用十进制数字,这会将其扩展回原始大小

    问题是,10和100都不是一个可以很容易地精确放入一个字节的数字。从1到100的数字可以用7位编码。所以,你基本上把它们当作一个比特流,一次把它们放入7位,但一次把它们取出8位,得到要加密的字节

    这样可以更好地利用空间,但仍然不够完美。7位可以对0到127之间的值进行编码,而不仅仅是0到99之间的值,因此即使使用所有8位,也不会使用这8位的所有可能组合。同样,在结果中,一个字节将变成三个十进制数字(0到255),这显然浪费了一些空间。因此,您的输出将略大于输入


    为了更接近这一点,您可以在加密输入之前使用类似于Huffman或LZ*压缩(或两者兼有)的方法对其进行压缩。然后,您将执行大致相同的操作:加密字节,并使用0到9或0到99的值对字节进行编码。这将更好地利用您加密的字节中的位,因此在转换过程中只会浪费很少的空间,但对改进输出端的编码没有任何作用。

    仅使用10位作为输入/输出是完全不安全的。它是不安全的,在实际应用中很可能会被破解,所以考虑使用至少39个数字(128位等效),如果你只使用10个数字,那么在使用AES时没有任何意义,在这种情况下,你有机会发明你自己的(不安全)算法。 唯一的办法是使用流密码。使用256位密钥“SecureKey”和初始化向量IV,这在每个赛季开始时应该是不同的。 将该数字转换为77位(十进制)数字,并在每个数字的模10上使用“加法带溢出”

    比如说

     AES(IV,KEY) =      4534670 //and lot more
     secret_message =   01235
                              + and mod 10 
     ---------------------------------------------
     ciphertext     =   46571 // and you still have 70 for next message
    
    当流密码->AES(IV,密钥)中的数字用完时,增加IV并重复IV=IV+1

    请记住,您绝对不应该两次使用相同的IV,因此您应该制定一些计划来防止这种情况

    另一个关注点是生成流。如果您生成的数字高于10^77,您应该放弃该数字增加IV,然后使用新IV重试。否则,您很可能会有偏差的数字和漏洞


    这个方案很可能存在缺陷,或者在您的实现中也会存在缺陷

    我不是密码专家,但我想到一个明显的问题:您是否可以使用一次性密码?然后,您可以在解码系统中包含一大块真正随机的位,并使用随机数据以可逆的方式转换十进制数字

    如果这是可以接受的,我们只需要弄清楚解码器如何知道在随机性块中的何处,以获得解码任何特定消息的密钥。如果你能用密文发送一个明文时间戳,那么很容易:将时间戳转换成一个数字,比如说从一个纪元日期起的秒数,用随机性块的长度对该数字进行模化,然后在
    For every decimal digit in the plaintext
      Repeat
        Take 4 bits from the keystream
      Until the bits form a number less than 10
      Add this number to the plaintext digit, modulo 10