我的任务是编写一个涉及加密的小型Java控制台应用程序。我不熟悉加密,所以我必须先做一些阅读。到目前为止,给出的高级要求是应使用AES-256生成一次性密钥来加密文件。
之后,应使用收件人的公钥(RSA-2048)来加密该AES-256一次性密钥。然后,加密文件和加密的一次性AES-256密钥将被压缩并发送给收件人。
根据我对读取加密和解密的理解,除了算法(RSA,AES等)之外,还有称为模式和填充的东西。例如,以下代码将RSA指定为算法,ECB模式和PKCS1Padding。
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
在加密和解密中必须使用相同的算法,模式和填充。因此,向用户询问他们想要的模式和填充是否合理?
我注意到Cipher cipher = Cipher.getInstance(“RSA”)似乎使用了ECB的默认模式和PKCS1Padding的填充,因此这行代码与上面相同。那么可以假设ECB模式和PKCS1Padding模式将默认用于RSA-2048吗?
答案 0 :(得分:3)
不,对于发送消息,您应该使用较新的OAEP方案,因为带有PKCS#1 v1.5的RSA可能容易受到Bleichenbacher attack的攻击。然而,完全有可能甚至可能请求RSA混合加密的人从未听说过这种攻击。通常,PKCS#1 v1.5填充仍然用作默认值。
除非唯一的用户是密码学的学生(并且知道上面的攻击),否则你绝不应该指望用户为你做出安全决定。一般而言,安全不应过分依赖于教育用户。
就我个人而言,我肯定会向请求者询问填充。您还应该检查他们是否期望对称加密的身份验证(MAC,HMAC,经过身份验证的密码或签名)。如果他/她无法回答问题,他们可能对加密知之甚少。
我目前不会认为您的要求是完整的(尽管"出于学习目的而且#34;可能是一个借口的人)。
"RSA/ECB/PKCS1Padding"
实际上并没有实施ECB模式加密。它应该被称为"RSA/None/PKCS1Padding"
,因为它只能用于加密单个明文块(或者实际上是一个密钥)。这只是Sun / Oracle的命名错误。
还有一种称为RSA-KEM的混合加密模式应该至少与RSA OAEP一样安全,但它尚未在Java SE中实现。
AES-256本身不应该用于生成一次性密钥"。您应该使用KeyGenerator
的实例生成AES-256一次性密钥(这可能有点混淆,因为KeyGenerator
本身不会使用 AES,它会创建键用于 AES)。
答案 1 :(得分:2)
您不希望向用户询问填充或阻止模式。我认为你需要做的是:
生成一个随机的256位密钥(确保使用加密库来执行此操作,并且播种良好)
使用带有密钥的AES256加密文件(如果你想稍微隐藏文件的确切长度,请不要使用ECB,使用CBC和可能的填充)
使用RSA-2048对密钥进行加密(此处从安全角度来看块模式是无关紧要的,因为密钥小于一个块,因为密钥是已知长度的填充。我会使用ECB)
您的协议不保证发送文件的人员或文件的完整性。考虑这一点非常重要,考虑签名。
不幸的是,在实施与加密有关的任何事情时,你极有可能出错。绝对使用Java库,如果您能找到更接近您想要的更高级别的可信库,请考虑使用它们。