假设有两台服务器,分别为服务器A和服务器B。如何保证服务器A能够识别服务器B的请求,而不是其它服务器的请求。并且保证A所处理的请求是B发送的,不是别人伪造的请求。
1.在服务A中建立一个名为process.jsp的文件,用于处理服务器B向A的请求。从B发送给A的请求参数都是以POST方式提交。
2.随机生成一个32位由小写字母和数字组成的字符串作为私钥,它将作为进行签名的一部分。
3.每一次从B服务器传送到A的数据都加入一个唯一的标识字段(如request_id,将该ID放入两台服务器的数据库中,便于以后的确认工作)
4.为防止数据被篡改,或者是攻击者伪造数据,需要对从B发送到A的数据进行签名。签名过程如下:
(1)将请求的参数按key值升序排序,参数之间用&进行连接。
如请求字符串为userName=XXXX,password=123456。
那么其正确请求格式为
按照步骤(1)生成的字符串为:password=123456&userName=XXXX
(2)将第2步中生成的32位字符串连接到(1)的后面进行md5运算
即sign=md5(password=123456&userName=XXXX+第2步中生成的32位私钥)
(3)将(2)中生成的32位md5值作为POST的一个字段发送给服务器A(假设参数名为signValue)。
5.在process.jsp中对服务器B的请求进行处理,首先进行请求参数的验证。步骤如下:
(1)将POST中所有的字段取出,将除signValue之外的所有字段进行签名认证,请求参数之间用&连接。
如POST中取到的字段有
userName=XXXX,password=123456,signValue=XXXXXXXXXXXXXXXXXX
根据(1)生成的字符串为 password=123456&userName=XXXX
(2)将第2步中生成的32位私钥连接到(1)后,计算其md5值,生成一个在A服务器的md5值(假设将该md5值保存到serverSign中)
serverSign=md5(password=123456&userName=XXXX+第2步中生成的32位私钥)
(3)如果serverSign的值与POST中signValue字段中存放的value相同,则认证成功。否则数据在传输过程中发生了改变,有可能是数据被篡改或者该请求是非法请求,认证失败。认证失败则不进行后面的操作。
8.如果process.jsp中通过了第7步的验证,判断唯一标识(假设为request_id)是否已经在A服务器的数据库中。如果已经存在,有可能是重复的请求或者是恶意攻击。则不进行后面的操作。
只要第2步中的32位私钥只有A服务器和B服务器知道,那么B服务器向A服务器的请求将会是安全的(这里所指的安全是服务器A不会处理非正常的请求)。