用多步的密匙交换
一般的验证是需要传递用户名和密码的。
但是怎样才能保证传递的过程中密码不被泄露??
可能会有人说,对密码进行加密不就完了?
但是实际上,除了密码不被泄露外,还需要保证没有截取欺骗等安全问题。
RSA等非对称加密,可以另第三方无法得到客户的密码。
但是第三方则可以直接发送加密过的数据,达到欺骗服务器的目的。
下面是我设计的一个解决方案,(绝对原创,但是原理简单,不保证有人之前已经用这个了。)
现在用三重DES:
第一步:
客户端,用户输入
clientUsername,clientPassword
客户端,往服务器端发送clientUsername
第二步:
服务器,接收到clientUsername后,
查找databaseUsername
如果没有找到 -> Exception -> 设计一个方案告诉客户找不到用户名,终止
第三步:
服务器,得到databasePassword,
生成一个字符串serverStr1,serverStr2,并且储存起来
(其实放在session中还是其他地方,随便,但是不要放到客户端去,例如不要使用ViewState)
用databasePassword作为Key,对serverStr1进行加密,
得到serverStr1Encrypted=TDES(serverStr1,databasePassword)
用serverStr1作为Key,对serverStr2进行加密,
得到serverStr2Encrypted=TDES(serverStr2,serverStr1)
把serverStr1Encrypted,serverStr2Encrypted传到客户端
第四步:
客户端,得到serverStr1Encrypted,serverStr2Encrypted
用clientPassword作为Key,对serverStr1Encrypted进行解密,
得到clientStr1=~TDES(serverStr1Encrypted,clientPassword)
用clientStr1作为Key,对serverStr2Encrypted进行截密,
得到clientStr2=~TDES(serverStr1Encrypted,clientPassword)
如果其中一次解迷发生错误,-> Exception -> 那么告诉客户密码不对,终止
如果密码是对应的话,那么serverStr1和clientStr1是对应的。serverStr2和clientStr2对应。
这个过程目的就是使用password作为Key,然后在两者间安全地交换密匙str2
使用clientStr2作为Key,对clientPassword进行加密,
得到clientPasswordEncrypted=TDES(clientPassword,clientStr2)
第五步:
把clientPasswordEncrypted送到服务器端
第六步:
服务器,得到clientPasswordEncrypted
根据会话状态,
测试:
clientPasswordEncrypted==TDES(databasePassword,serverStr2);
如果其中一次解迷发生错误,-> Exception -> 那么告诉客户密码不对,终止
如果相等?LoginAs(databaseUsername);
这个方法也不是100%安全。首先是DES本身的问题。这个则不作为讨论范围。
然后最突出的问题在第五步。
如果在clientPasswordEncrypted发送过程中,被第三方终止了,
然后第三方冒认客户,把clientPasswordEncrypted传过去,就可以达到欺骗的目的。
为了防止这个,需要在第六步,需要在会话方面进行进可能多的会话验证。
例如判断IP等方法。(物理因素往往比数字因数好)
然后更多的方法是进行密匙交换,(当中的DESKey当然是随机的,只对会话其效果的)
第三步,
服务器另外创建serverDESKey,作为让客户进行信息加密之用
传给客户的则是serverDESKeyEncrypted=TDES(serverDESKey,serverStr1)
第四步,
客户端另外创建clientDESKey,作为让服务器进行信息加密之用
clientDESKeyEncrypted=TDES(clientDESKey,clientStr1)
然后在第五步和clientPasswordEncrypted同时交给服务器。
那么即使发生欺骗,
第三方没有办法得到两个DESKey,
没有办法发送合法的请求,也没有办法把得到信息进行解密。
这个过程。核心仍然是会话初始密匙clientStr1=serverStr1