(免责声明:我是一个经验丰富的服务器端Java程序员,但几乎没有密码经验。)
目标:
我有一个登录服务器,给定一个login+password对,应该发出一个唯一的auth令牌。使用相同的login+password对多次应该发出新的唯一标记,它们都应该同时有效。令牌是只有登录服务器才能创建的密文。其他人只能从中提取有效载荷。
可能的解决办法:
首先,我想我应该使用RSA来用私钥加密负载。其他人只会用公钥来解密。但是我在某个地方读到RSA密码不能提供完整性和真实性,所以我想我需要添加一个RSA签名,所以看起来:
RSAcipher-with-private-key(payload-length + payload + RSAsignature(payload))然后我发现明文不能大于密钥大小,因此我需要一个对称密码,所以我开始研究AES,偶然发现了GCM。据我所知,GCM解决了A.和I.的问题,所以我不再需要签名了,并想出了如下结论:
RSAcipher-with-private-key(AESkey + GCMiv) + AES-GCM-cipher(payload)因此,其他各方将使用公钥提取AESkey和GCMiv,然后使用它来解密AEScipher块。
我使用的是BouncyCastle java库,因为有人说Java1.8中的AES/GCM是坏的。
这能成功吗,安全吗,我是不是想在这里发明一个轮子?如果是这样的话,我需要什么开箱即用的解决方案?
发布于 2015-11-18 17:03:14
在包含RSA的非对称密码中,我们总是用公钥加密,用私钥解密(永远不会相反)。在问题中,我们想要的是用私钥签名,而不是加密。
这足以解决整个问题,因为在BouncyCastle或Java中公开的RSA签名方案允许对任意长度的数据进行签名。
此外:在现代密码学中,加密的目的是防止对手获取关于加密内容的信息(除了长度之外)。当将一段数据转换为可以使用公钥返回到原始数据的密码时,只有私钥的持有者才能准备密码,这不是加密;这是带有消息恢复的签名。
在该名称中,签名包括持有私钥是准备密码所必需的,私钥允许检查密码。消息恢复包括密码可以转换回原始消息。
具有消息恢复的RSA签名方案(如ISO/IEC 9796-2中的签名方案)比有附录的签名方案(如那些在PKCS#1)有一个优势:签名开销较小(略高于散列大小,而不是模数大小)。例如,当使用RSA-2048和SHA-256时,ISO/IEC 9796-2将一条222个字节的消息嵌入到一个256个字节的密码中,而当PKCS#1需要一个478字节的密码时(该消息的明文为222个字节,其签名为256个字节)。
据我所知,这个问题试图通过将教科书RSA (用于签名和对称密钥的消息恢复)和AES/GCM (用于完整性检查和大部分消息的恢复)混合使用,从而使混合签名方案具有消息恢复功能。这是非常不安全的:对手(假定持有公钥,根据定义)可以从RSA部分确定对称密钥,然后将消息本身更改为任何想要的内容。
同样,现有的问题用标准RSA签名很好地解决了。有附录的适当方案可以直接从BouncyCastle或Java获得。如果将密码的大小减少几百字节,则可以使用消息恢复。虽然ECDSA签名(也是现成的)还将减少签名开销(只有RSA的两倍左右,并具有消息恢复功能),并且大大加快了签名速度,但它的缺点是检查密码比使用RSA要慢得多。
发布于 2015-11-18 17:54:21
这听起来像Kerberos。( https://en.wikipedia.org/wiki/Kerberos_28%协议%29 )
在任何情况下,您都没有提到,但似乎非常重要的是,生成的auth令牌有效期多长,或者如何过期。没有永久/无限期授权这样的东西--如果你不这么认为,你就不应该做安全工作。
因此,由于您需要一种过期或撤销令牌的方法,它们几乎可以是任何随机数。生成一个随机的盐和散列,它会和任何东西一样工作。在这种情况下,您需要的是一个由已知的好用户ID和令牌对组成的数据库,可能还有一个到期日期。
https://crypto.stackexchange.com/questions/30650
复制相似问题