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