gpt4 book ai didi

java - 回顾基于 RMI 的身份验证方法

转载 作者:行者123 更新时间:2023-11-30 07:50:20 25 4
gpt4 key购买 nike

我正在做一个项目,其中要访问服务,客户端需要通过 RMI 进行自身身份验证(客户端有用户名和密码)。我想在不使用 SSL 的情况下实现这一目标(因此,修改和嗅探是主要威胁)。

这是客户端每次访问服务时发送的“ token ”。

class Token {
String username;
byte[] encryptedText;
}

加密文本变量包含密码和时间戳的组合,该组合使用密码本身作为 key 通过 AES-256 CBC 进行加密。例如:

encryptedText[0] = AES(20) //encrypt length of password 
encryptedText[1] = AES(30) //encrypt length of TimeStamp
encryptedText[2-21] = AES(password) //encrypted password
encryptedText[22-51] = AES(timestamp) //encrypted timestamp

服务器收到此 token 后会检索用户名的密码,并尝试使用密码作为 key 解密加密文本。如果结果不是密码和最近时间戳的组合,则这是一次错误的尝试。

我知道这是不可扩展的,因为每次请求服务时,都必须获取记录,但这安全吗?

据我所知:-

  • 防止嗅探(加密)
  • 防止修改攻击(不会导致正确的身份验证)
  • 防止重放攻击(非最新时间戳表示身份验证失败)

最佳答案

我假设 AES() 不仅仅意味着分组密码的伪随机排列,还意味着具有操作模式和填充的分组密码。

可以通过 padding oracle attack 恢复密码是否可以区分不良填充和良好填充。这很有可能,因为当出现 BadPaddingException 时,响应可能会提前完成,无法进行进一步的计算。

主要的两个问题是你

  • 不验证密文本身并且
  • 用于加密明文的密码包含在明文中(可以恢复)。

这个伪加密代码比较好:

// salt and masterHash can be cached for multiple requests
salt = SecureRandom().nextBytes(8 bytes)

// adjust iterations (65336) according to appropriate performance:
masterHash = pbkdf2(password, salt, 65336)

iv = SecureRandom().nextBytes(16 bytes)
sessionKey = SecureRandom().nextBytes(16 bytes)
encKey = hmacSha256(masterHash, "enc") // crop according to intended AES key size
macKey = hmacSha256(masterHash, "mac")
ciphertext = AES(encKey, iv, sessionKey + ts.length + ts)
tag = hmacSha256(macKey, username + salt + iv + ciphertext)
return salt + iv + ciphertext + tag

这里 + 表示串联,AES 表示 CBC 模式下的 AES 和 PKCS#7 填充。

接收方必须先导出macKey,然后计算tag,然后检查传输的tag是否与计算的匹配标签。如果是,则解密密文。如果有效,则可以使用 sessionKey 进行进一步的通信。

攻击者唯一能做的就是通过操纵传输的请求来阻止您向服务器进行身份验证,以便在服务器上产生失败的身份验证。

关于java - 回顾基于 RMI 的身份验证方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33398700/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com