当前位置:A5D软件园网络学院网络编程NET专区 → 网络学院内容

分析单点登录(流程图与数据安全)

订阅:
减小字体 增大字体 作者:佚名  来源:本站整理  发布时间:2008-6-12 17:14:39

原文:[原创]单点登陆(SSO)组件的设计与实现一
  
   最新修改:完善SSO安全问题.08-6-11
  
   去年公司也曾经做过一个单点登录模块,两个站点,同事是基于cookie和session来实现的,在那个模块中并没有单独的用户认证中心,每个子站都有自己的登录系统,在判断用户是否登录时,首先是通过判断cookie是否存在来判断用户登录与否.如果cookie值存在则写入session,保存登录票据.
  
   一般基于cookie的程序,在某种程度上来说最大的问题就是安全,因为它是以文件形式存储在客户端的.所以一般非常重要的信息,例如用户登录信息,用户银行卡信息都不会采用cookie来存储.尽管cookie可以加密,但个人总觉的不放心.为此本人一直在寻找一种安全级别高点的单点登录方案.
  
   前不久,本人看到了这篇文章::[原创]单点登陆(SSO)组件的设计与实现一 ,发现它是基于session的,当时特别奇怪,因为平时我们知道session是不能跨应用程序的,后来仔细分析下才知道原理:
  
   按照程序的思想,我改下了实现的流程图,个人好理解些:
  
  
  如果原博主看到了这张图,还望评价下是否符合原文思想呢?本人对这方面的经验还不是特别多,只能理解到此啦,望大家指教.
  
   本人除了更改单点登录的流程图外还想探讨下基于cookie以及基于session两种方式实现的区别及好处:
  
   在上面的解决方案中,联盟站点想要实现单点登录,就一定要与认证中心交互,这样就要在WEB中传递用户登录信息,一般都包括用户名和用户登录密码.这是我们最关心的问题,因为密码这种非常重要的信息在WEB中传递也是相当
  危险的,主要是有非法用户去截获传递信息来篡改用户信息。
  
   上面的解决方案原博主实现的非常好,这里我就引用下原文吧:
  
  11 本系统的安全性
  11.1 登录请求的格式
  联盟站点向认证中心发送的登录请求格式如下:
  
  站点信息+登录请求编号+时间戳+空用户信息+对站点信息和登录清秋号的签名信息。
  除了签名信息之外的全部信息均为明文传送,但因为重要的数据均经过数字签名,结果是站点信息和登录请求编号是不能被篡改的,保证了认证中心收到的登录请求的真实性。
  
  11.2 登录答复的格式
  认证中心发给联盟站点的登录答复格式如下
  
  登录用户信息+登录请求编号+时间戳+对用户信息和登录请求号和时间戳的签名信息
  其中登录用户信息是经过非对称加密的。请求号和时间戳因为经过签名,故也不能篡改,这样就可以保证联盟站点收到的登录答复的真实性和完整性。并且非正常联盟站点无法解密用户信息,也无法从中获取好处。
  
   这里的数字签名是采用了RSA数字签名算法加密的。
   Code
  RSA签名#region RSA签名
   //RSA签名
   public bool SignatureFormatter(string p_strKeyPrivate, string m_strHashbyteSignature, ref string m_strEncryptedSignatureData)
   {
  
   byte[] HashbyteSignature;
   byte[] EncryptedSignatureData;
  
   HashbyteSignature = Convert.FromBase64String(m_strHashbyteSignature);
   System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider();
  
   RSA.FromXMLString(p_strKeyPrivate);
   System.Security.Cryptography.RSAPKCS1SignatureFormatter RSAFormatter = new System.Security.Cryptography.RSAPKCS1SignatureFormatter(RSA);
   //设置签名的算法为MD5
   RSAFormatter.SetHashAlgorithm("MD5");
   //执行签名
   EncryptedSignatureData = RSAFormatter.CreateSignature(HashbyteSignature);
  
   m_strEncryptedSignatureData = Convert.ToBase64String(EncryptedSignatureData);
  
   return true;
  
   }
   #endregion
  
   RSA 签名验证#region RSA 签名验证
   public bool SignatureDeformatter(string p_strKeyPublic, string p_strHashbyteDeformatter, string p_strDeformatterData)
   {
  
   byte[] DeformatterData;
   byte[] HashbyteDeformatter;
  
   HashbyteDeformatter = Convert.FromBase64String(p_strHashbyteDeformatter);
   System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider();
  
   RSA.FromXMLString(p_strKeyPublic);
   System.Security.Cryptography.RSAPKCS1SignatureDeformatter RSADeformatter = new System.Security.Cryptography.RSAPKCS1SignatureDeformatter(RSA);
   //指定解密的时候HASH算法为MD5
   RSADeformatter.SetHashAlgorithm("MD5");
  
   DeformatterData = Convert.FromBase64String(p_strDeformatterData);
  
   if (RSADeformatter.VerifySignature(HashbyteDeformatter, DeformatterData))
   {
   return true;
   }
   else
   {
   return false;
   }
  
   }
  
  
   #endregion
  
  
   #endregion
   这种方式并不能防止非法用户去截获认证中心的答复信息,如果非法用法提前截获认证中心的答复信息,则他可以利用截获的答复信息用于登录,但是不能篡改信息,因为经过RSA数字签名。这个缺点也是这个方案安全上唯一的。基于cookie也同样存在这样的安全问题。基于cookie的方式将更多的处理交给客户端处理可以减轻服务器压力,这点要好于基于session方式。
  
   非常谢谢名们园友们这么费劲的看我的分析文章,大多朋友都提出安全问题,如上.@ Microshaoft,非常谢谢这位朋友的指点,他的想法和我后来的想法差不多.
  
   我的思路:子站用户在向认证中心发出登录请求时,附加上一个随机数或者是用户IP,附加信息都要经过加密及签名.然后认证中心返回答复信息,经过较验,如果附加信息相符则说明是合法用户.
  
   .@ Microshaoft的思路:
  
   认证中心颁发加密(对称、非对称、先用非对称加密交换对称密钥)的临时Token串,重定向的方式可以发给其他域名的站点
  其他域名的站点解密(验签)Token,自己维持状态(cookie session url等)
  
   如果把这两种方法结合起来(附加信息返回时经过特殊加密,再返回解密密钥) ,客户端根据临时Token串解密附加信息,然后再验证附加信息,这样做应该就不会有安全问题了.
 

赞助商连接