检查更新#1
此逻辑是验证过程的候选者,由简单的HTTP请求完成:
问题:这是一个安全漏洞吗?说坏人捕获完整的HTTP请求,他可以从这2个信息中提取密码吗?
代码详情,如果需要:
private static Cipher getCipher(String key, int mode) throws Exception{
byte[] rawKey = getRawKey(key.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(rawKey, "AES");
Key key2 = skeySpec;
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
cipher.init(mode, key2);
return cipher;
}
private static byte[] getRawKey(byte[] seed) throws Exception {
/* BEFORE:
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed);
kgen.init(128, sr); // 192 and 256 bits may not be available
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
*/
byte[] raw = MD5Util.getMD5HashRaw(seed);
return raw;
}
(注意:我使用密码哈希的原因是代码在平台之间兼容(客户端是Android设备),而注释版本不是)
简答:
提出的逻辑甚至不被认为是安全的身份验证机制 (为什么?查看迈克尔的回答)
决定使用Kerberos (而不是https,因为我不熟悉+设置似乎很复杂):
它不是真正的Kerberos版本(如v4或v5),它只是我自己的实现,所以我们称之为“与Kerberos类似”(我知道,我知道:不要“滚动你自己的加密”!!! ),
以下是一些细节:
只能通过以下方式进行一次身份验证:
再次保护“回复攻击”并非100%保证,但我认为这是“安全的”:
我只需要再次验证[new_request_creation_timestamp]一些数学(显然[TGT]也需要有效):
**我希望以下变量几乎相等
delta1 = [TGT_creation_time_stamp] - [authenticator_creation_timestamp]
delta2 = now() - [new_request_creation_timestamp]
(我实际上允许它们之间有5秒的差异,但是从我的测试来看,它只需要10-20毫克,
**因此,初始增量(在对Authenticator创建OK响应时计算)应该会在下一次互动时保持不变。
我确实发现这种新方法非常值得信赖,但如果你有意见或看到逻辑上的BUG,请分享..谢谢
答案 0 :(得分:3)
是的,这是一种弱安全机制。
任何捕获发送到服务器的信息的人都可以轻松地重播它以进行身份验证(重放攻击)。
它很容易受到脱机密码猜测 - 任何捕获发送到服务器的信息的人都可以非常快速地测试密码列表,找到用户选择的密码(通过使用每个密码加密观察到的用户名)密码依次)。哈希甚至可以预先计算,进一步加快攻击速度。
基于密码的身份验证协议应该能够抵御重放攻击和脱机密码猜测攻击。
只需使用HTTPS(TLS)连接到您的服务器并以明文形式发送用户名和密码通常是更好的解决方案。
响应您的更新1:
答案 1 :(得分:1)
我的理解是:您正在向服务器发送Username + Encrypted Username
。
答:
由于您要发送Username
和encrypted Username
,即UserName + AES(UserName + MD5 Hashed Password)
如果有人知道或发现您提供了用户名,并且还从您的数据到服务器获取用户名:No worries
。你站在那里AES
。如果您对AES加密有疑问,请检查this。您的数据是安全的。
答案 2 :(得分:1)
我认为这本身并不存在安全漏洞,因为即使知道明文消息和加密消息,实际上也无法获得AES密钥。但我仍然不建议使用MD5存储密码哈希。