`
jef
  • 浏览: 117304 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

三种保证URL地址可信的加密方式

阅读更多

近日接到一个需求,要求一台资源服务器不仅在可以暴露在公网环境下的同时,还要保证只接受并处理可信的http访问请求。

 

需求场景如图:

为了访问资源文件,用户需要首先访问某一台Frontend Server进行用户身份认证———所有的用户信息均由Frontend Server保存,Frontend Server认证通过后返回真实的重定向地址,用户再根据重定向地址访问Resource Server获取资源文件。

具体的使用场景正如上面所述,下面是我的思考过程...

 

为了保证资源服务器收到的是一个可信的重定向地址,在安全性上有三点考虑:

 

  1. 重定向地址必须是可信的,即不可以被伪造,必须是由某一台Frontend Server返回的重定向地址。
  2. 为了防止盗链或资源被采集,每个Frontend Server返回的重定向地址应具有时效性。这个可以通过在链接地址上增加时间戳实现,但前提是该时间戳不可以被伪造。
  3. 最后,在必要的情况下,还可以不去响应某一台Frontend Server返回的重定向地址,即认为某一台Frontend Server的重定向地址不可信、该Frontend Server不可信。这要求Resource Server能够及时标示一台Frontend Server为不可信服务器,并且该Frontend  Sever服务器还不可伪造剩余可信服务器返回的重定向地址。

 

以上三点也可以总结为:防止公网用户伪造URL地址,防止不可信Frontend Server伪造地址,防止过期URL地址访问。

由于Resource Server需要允许所有的公网用户访问,所以不能对Ip进行限制,并且一般情况下Resouce Server也不会与Frontend Server直接通信,因此只能通过URL的验证方式。Frontend Server在生成每个URL的过程中中应包括Resource Server为每一个Frontend Server分配的账户fsId、密钥fsKey以及记录当前URL生成时间的时间戳fstime。fsid必须明文传输,fsKey做为加密运算的一个常量不可以明文传输。

可以想到的有如下三种:

1.使用自定的加密函数生成加密签名字符串。
加密函数将所有需要明文传输的参数以及当前Frontend Server使用的密钥fsKey做为参数并通过MD5转换后生成加密签名字符串,md5(encode(params,fsid, fskey, fstime))。
重定向地址链接:

http://res.com/fsid=***&fstime=***&params=***&signmsg=md5(encode(params,fsid,fskey, fstime))

Resource Server收到该请求后

  • 根据fstime判断该请求是否过期,过期请求直接返回。
  • 根据fsid判断该Frontend Server是否可信,如可信再根据fsid获得服务器端保存的fskey。
  • 使用相同的参数加密签名过程,Resource Server根据params,fsid, fskey, fstime生成签名字符串。
  • 比较重定向地址传来的签名字符串signmsg与本地生成的签名字符串是否相同,相同则认为是可信请求,否则为非法请求。

2.使用对称加密算法保证HTTP通信可信。
Resource Server为每一台Frontend Server分配不同的Des密钥(fskey),Frontend Server使用对称加密算法对拼接后的传递参数进行加密des(params|fstime)
重定向地址链接:
http://res.com/fsid=***&desmsg= des(params|fstime)
Resource Server收到该请求后

  • 首先根据fsid判断该Frontend Server是否可信,如可信再根据fsid获得每个Frontend Server使用的Des密钥fskey。
  • 使用密钥对desmsg信息解密,解密失败直接返回。
  • 根据解密后的fstime判断是否过期,过期直接返回。

3.同时使用非对称,对称加密算法保证HTTP通信可信。
Frontend Server随机生成key做为对称加密算法的公钥des(params|fskey|fstime),并使用Resource Server提供的公钥对key进行非对称加密rsa(key)
重定向地址链接:
http://res.com/fsid=***&rsamsg=rsa(key)&desmsg= des(params|fskey|fstime)
Resource Server收到该请求后

  • 首先根据fsid判断该Frontend Server是否可信,如可信再根据服务器端保存的非对称加密私钥解密rsa(key)。
  • 根据key解密des(params|fskey|fstime)。
  • 通过fsid获得服务器端保存的fskey,对比解密后的fskey,如果不相同则认为是Frontend Server伪造的非法请求。
  • 根据fstime判断是否过期,过期直接返回。


以上三种方法第一种会暴露所有的明文传递参数,第二种貌似最方便但却有被攻破的危险,第三种有可能又会产生效率的问题。

由于没有进行过相关方面的开发,以上也是对平时了解有限的一些资料的总结,难免考虑不周。各位有更好的方法和建议吗?

 

 

分享到:
评论
15 楼 iamlotus 2009-11-24  
这就是CA要解决的问题啦,加密解决了防篡改的问题,CA的引入则解决了防伪造的问题。所以建一个CA是技术上最完美的方案,不过代价也最昂贵。
14 楼 jef 2009-11-24  
cszhz 写道
可是试试SSO(app sever都支持的),你这种case 根本不需要有额外的coding

sso不太适合大量部署吧,而且又会引起很多效率上的开销。
13 楼 cszhz 2009-11-24  
可是试试SSO(app sever都支持的),你这种case 根本不需要有额外的coding
12 楼 daquan198163 2009-11-23  
有个叫HDIV的框架,应该能满足你的要求。
11 楼 jef 2009-11-23  
<p>恩,是这个意思吧,重定向地址前半部分是明文传递的参数,后半部分是使用非对称加密算法加密的参数摘要。<br><br><em><span style="text-decoration: underline;"><span style="color: #0000ff;">http://res.com/fsid=***&amp;fstime=***&amp;params=***&amp;fskey=***&amp;signmsg=RSA(SHA-1(fsid,fskey,fstime,params))</span></span></em><br><br>这个办法很不错,安全性更高了,多谢!</p>
<p> </p>
10 楼 hcqenjoy 2009-11-23  
引用
3.同时使用非对称,对称加密算法保证HTTP通信可信。
Frontend Server随机生成key做为对称加密算法的公钥des(params|fskey|fstime),并使用Resource Server提供的公钥对key进行非对称加密rsa(key)
重定向地址链接:
http://res.com/fsid=***&rsamsg=rsa(key)&desmsg= des(params|fskey|fstime)
Resource Server收到该请求后

首先根据fsid判断该Frontend Server是否可信,如可信再根据服务器端保存的非对称加密私钥解密rsa(key)。
根据key解密des(params|fskey|fstime)。
通过fsid获得服务器端保存的fskey,对比解密后的fskey,如果不相同则认为是Frontend Server伪造的非法请求。
根据fstime判断是否过期,过期直接返回。




这个采用数字签名就可以 即(params|fskey|fstime)做摘要如SHA-1 然后用Frontend Server的私钥对摘要做加密 将(params|fskey|fstime) 和加密值发送给接收端
接收端 用Frontend Server的公钥解密出摘要值 与 (params|fskey|fstime)的摘要值对比 符合即通过

定期更换两台服务器的公私钥 可以防止密钥的泄漏

数字签名是很成熟的安全方案
9 楼 jef 2009-11-23  
ebeach:
是有点像单点场景,不过前置服务器和后端服务器肯定不能频繁的交互,否则应用在互联网环境下对效率的开销太大。

bengxia 写道
感觉跟CAS在原理上很相似。但有一个安全假设存在隐患,就是client在frontend server认证后返回重定向地址的过程是安全可靠的,这点要看实际情况。

对用户来说,需要收到一个安全的重定向地址。对Resource Server来说需要处理一个可信的访问请求。
8 楼 jef 2009-11-23  
谢谢大家的回帖,看来要保证网络通信的绝对安全也不是件易事。
参照grandboy的说法,应该选择一种适合的方案解决一定密级要求下的网络安全。所以解决方案也可以分为两种,一种是适合于金融交易系统,要求在任何情况下都能保证网络通信绝对安全的场景,但在这种情况下可能需要较高的成本投入。
另一种情况是适合于普通互联网应用环境,可以低成本投入,高效率运行,并能保证一定密级要求的次优解决方案。具体说就是:

1,理论上不保证每个时间点的绝对通信安全。
2,可以被破解,但破解行为必须付出一定程度的时间成本。破解的时间成本也可以参考一些资料估算得出。
3,在破解行为必须付出的时间成本内Frontend Server和Resource Server可通过定时任务交换最新的fskey。这个可以通过对Frontend Server和Resource Server之间的特定调用接口进行IP和口令限制保证通信安全。

也就是说破解行为所需要的时间周期远高于Frontend Server和Resource Server的fskey更新周期,这些条件达成时,感觉应该也算是在次优方案下保证了网络通信的绝对安全。
7 楼 bengxia 2009-11-23  
感觉跟CAS在原理上很相似。但有一个安全假设存在隐患,就是client在frontend server认证后返回重定向地址的过程是安全可靠的,这点要看实际情况。
6 楼 ebeach 2009-11-23  
<p> 如果前置服务器和后端服务器是可通讯的话,那就是个典型的单点场景了。<br><img src="http://dl.iteye.com/upload/attachment/171354/f93209ab-3a2c-3243-b83b-3b3f77d35b45.png" alt=""><br><br></p>
<p> </p>
5 楼 grandboy 2009-11-22  
javafound 写道
  这防不了攻击,
在传输层就先解决合法客户机和服务器的双向身份认证的问题吧,
要么用https,或建个VPN,把安全的业务分开,是不是更简洁些呢.


https协议并不能防止中间人攻击。

另外,如果想很好的解决这个问题,最好的是引入企业CA。 如果事先配置一些参数(密钥等)的方式能被接受,这样也就可以了。一般非对称的加密在没有密钥的情况,都是很难破解的,尤其是密钥长度够长的情况下。摘要算法因为会产生碰撞,所以适当的避免一下就可以了。一般的密级要求也不用考虑这种情况。

适当的需求配合适当的密级手段,有益的事情只是在“适度”的范围内才是有益的。
4 楼 javafound 2009-11-22  
  这防不了攻击,
在传输层就先解决合法客户机和服务器的双向身份认证的问题吧,
要么用https,或建个VPN,把安全的业务分开,是不是更简洁些呢.
3 楼 case0079 2009-11-22  
整理一下再说。
1.USER必须携带FS的签名访问RS
2.签名具有时效性。
3。RS可以否定FS。
引用

由于RS必须能解析出USER连接中的FSID和时间。因此URL中的加密数据必须是对称的。

USER访问FS则可以用不对称加密。

为了防止对称算法被破解,可以通过设置N种算法N个KEY来解决。FS和RS通过统一的规则调用这些算法加解密URL。




修正一下。



USER向FS请求HTTP://FS/URL.
FS需要标识别自己以及时间,因此得到HTTP://RS/URL?fsId=''&time='',用私匙加密后得到URLS,发送给USER
USER向RS请求URLS。RS用FS的公匙解密后得到HTTP://RS/URL?fid=''&tm=''
结束




2 楼 jef 2009-11-22  
是这样,以上三种方法都需要预先为每一台Frontend Server分配fsid和fskey。fsid是Frontend Server的标示可以在URL参数中明文传输,fskey仅做为加密算法的一个加密常数参量是不允许明文传输的。

所以第一种情况它可以伪造明文参数,但因为没有fskey所以无法伪造参数签名。

第二种情况fskey就相当于对称加密算法的密钥,是提前分配好的,每次交互的时候不会传递该密钥。

第三种情况使用rsa保护随机生成的des密钥,同时des也会对fskey进行加密处理。

最后,Resouce Server收到请求后都会根据fsid找到服务器端保存的fskey,然后再生成签名字符串比较(第一种情况),或者对加密数据进行解密后进行fskey的比较。

所以这里最关键的是fskey,一定要保证fskey不被窃取。

但对于第二种方法由于des公钥是提前分配好,并且可能是长期固定的,所以加密数据有可能被破解,知道了fskey后便可以伪造请求。

第三种同理,虽然使用了动态的des公钥,但是des加密后的数据也是可以被破解,并拿到fskey。

无论是第二种情况采用的对称加密方式,还是第三种情况采用的对称加密、非对称加密结合的方式都不能保证绝对安全。

所以最终看来我只能周期性的修改预先分配给每一台Frontend Server的fskey。


1 楼 grandboy 2009-11-22  
第一种方法的突出问题是: 如果明文内容和md5摘要同时都被篡改的情况,你将无法判断是否可信。 因为md5的摘要算法很简单,也很容易被别人猜到到你用的是什么摘要算法。

第二种方法,因为你要使用的对称加密算法,如何传递密钥或者是事先配置好了密钥吗? 如果传递密钥的话,要保证中途不被别人截获,是很困难。

第三种方法,因为采用了RSA非对称加密,不存在第二种方法的密钥被截获的问题,因为公共密钥本来就是可以公开的。但是问题也就随之而来了。公共密钥接收方如何确保接到的公共密钥就是Resource Server发来的公共密钥,而不是别人冒充的呢?至于生成密钥的效率问题,可以把密钥生成之后,缓存,可以根据具体要求进行定期更新。至于加密方法的效率的问题,可以用非对称和对称相结合的方式来解决。

当然这些问题在有些情况下,是可以忽略的,要视情况而定。

相关推荐

Global site tag (gtag.js) - Google Analytics