您将如何在Java中实现安全的静态登录凭据系统?
我们最近进行了安全审计,并暴露了此处系统中的一些弱点.由此产生的任务之一是我们需要更新我们的合作伙伴凭证系统以使其更安全.
“旧的”处理方式是生成(坏)密码,将其提供给具有ID的伙伴,然后他们将通过https发送该ID和该密码的Base 64编码副本以及所有XML请求.然后我们解码它们并验证它们. 这些密码不会改变(因为那时我们的合作伙伴必须进行编码/配置更改才能更改它们,并且与多个环境中的数百个合作伙伴协调密码到期将是一场噩梦)并且它们不必由人类输入或人类可读的.如果我们的合作伙伴有更好但仍然相对简单的实施,我愿意改变这一点. 基本上它归结为两件事:我需要一个更安全的Java密码生成系统,并确保它们以安全的方式传输. 我找到了一些手动密码生成器,但没有什么真正脱颖而出作为标准的方法来做到这一点(也许是有充分理由的).传输它们可能比通过https进行简单的Base 64编码更安全. 你会对密码生成器做些什么,你认为现有的传输方法是否足够安全? 编辑:XML包含在SOAP消息中,凭据位于标头中,而不在XML本身中.此外,由于在我们设置密码时,密码是每个合作伙伴的一次性操作,因此我们不太担心发电机的效率. 解决方法
密码生成
就编码密码进行传输而言,唯一真正增加安全性的编码就是加密.使用Base-64或十六进制不是为了安全,而是为了能够以XML等文本格式包含它. 熵用于衡量密码质量.因此,选择每个位随机“硬币翻转”将为您提供最优质的密码.您希望密码与其他加密密钥一样强,因此我建议至少使用128位熵. 有两种简单的方法,具体取决于您希望如何将密码编码为文本(从安全角度来看,这无关紧要). 对于Base-64,请使用以下内容: SecureRandom rnd = new SecureRandom(); /* Byte array length is multiple of LCM(log2(64),8) / 8 = 3. */ byte[] password = new byte[18]; rnd.nextBytes(password); String encoded = Base64.encode(password); 以下内容不要求您提供Base-64编码器.结果编码不是那么紧凑(26个字符而不是24个),密码没有那么多的熵. (但是130位已经很多了,相当于人类选择的至少30个字符的密码.) SecureRandom rnd = new SecureRandom(); /* Bit length is multiple of log2(32) = 5. */ String encoded = new BigInteger(130,rnd).toString(32); 创建新的SecureRandom对象的计算成本很高,因此如果要经常生成密码,您可能需要创建一个实例并保留它. 更好的方法 将密码嵌入XML本身似乎是个错误. 首先,在处理发送给您的任何文档之前,您似乎想要验证发件人.假设我讨厌你的胆量,并开始向你发送巨大的XML文件来执行拒绝服务攻击.您是否只想解析XML以发现我不是合法的合作伙伴?如果servlet刚刚拒绝了来自未经身份验证的用户的请求,那会不会更好? 其次,您的合法合作伙伴的密码在通过HTTPS传输时受到保护,但现在它们很可能存储在您系统的“明确”位置.这是不好的安全. 更好的方法是在合作伙伴向您发送带有HTTP请求标头中的凭据的文档时对其进行身份验证.如果您只允许HTTPS,则可以完全取出文档中的密码,并将其放入HTTP “Basic” authentication标题中.它在传输过程中由SSL保护,并且不以明文形式存储在您的系统上(您只存储单向哈希以进行身份??验证). HTTP基本身份验证很简单,受到广泛支持,并且您和您的合作伙伴比SSL客户端证书更容易实现. 保护文档内容 如果文档本身的内容是敏感的,它们确实应该由发件人加密,并由您以加密形式存储.执行此操作的最佳方法是使用公钥加密,但这将是另一个问题的主题. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |