身份认证和消息合法性验证方案分享

        最近要找一种合适的数据加密与身份认证方案,来保证服务的安全。没啥经验,一翻恶补之后,总算整合出一套方案。

并用Go完成了Demo。本人对安全外行,不过自我感觉应当是个比较有安全感的身份认证方案。

        不想写大段文字来说明,看得懂的,依着代码来瞧瞧吧.


首先,协议包应当包含最少下面几个字段:   

type Proto struct {
	//...
	Timestamp int64  `json:"timestamp"`  //当前时间戳
	Nonce     uint32  `json:"nonce"`	//随机数
	Signature string `json:"signature"` //Hash_hmac("sha1",sortAsc(Token,Timestamp,Nonce))		
	BodyCrc   string `json:"bodycrc"` //Hash_hmac("md5",body)
	UserID    string `json:"userid"`
	Body      string `json:"body"`
	//...
}
然后,用户登录时,是能得到其对应的Token的,并且这个Token在服务端是有有效期限管理的.
App端将用户Token保存在加密后的sqlite库中.


当App端要与服务端通讯时,在App端首先用相关参数时进行哈希.
     Signature = Hash_hmac("sha1",sortAsc(Token,Timestamp,Nonce))
      BodyCrc = Hash_hmac("md5",body)
然后再传给服务端,注意协议包中是无须再传用户的Token的。 

用户的Token在这仅作为hash字符串中的一个参数而已。


服务端收到后,就可以依参数做一系列的验证了。
   关于身份部份,可以做如下检验: 

///
		// 身份合法性验证
		///
		u, err := UserDB.Get(msg.UserID)
		if err != nil {
			s.Stop()
			log.Println("[IOLoop] [UserDB.Get] 用户库中没有找到此用户,断开连接.")
			return
		}

		if UserDB.IsBlacklistsUser(msg.UserID) {
			s.Stop()
			log.Println("[IOLoop] [IsBlacklistsUser] 属列入黑名单的用户,断开连接.")
			return
		}

		// Signature =  Hash_hmac("sha1",sortAsc(Token,Timestamp,Nonce)))
		// 检查token是否正确
		// 防止选择明文攻击
		if token, ret := u.CheckSignature(msg.Timestamp, msg.Nonce); ret {
			if !u.IsTokenExpire(token) {
				s.Stop()
				log.Println("[IOLoop] [IsTokenExpire] 为过期的用户Token,断开连接.")
				return
			}
		} else {
			s.Stop()
			log.Println("[IOLoop] [CheckSignature] 签名不符,属非法用户,断开连接.")
			return
		}

     其中关于Signature的部份,服务端是同样依Timestamp+Nonce再加从相关库找出来的用户Token依相同算法来Hash. 对比

其值是否相同.

 这部份主要用于验证消息包的合法性,或者可以用随用户token一起生成用户的aes密钥,然后用aes将其加密后在服务端将消息内容再解密。   

///
		// 消息包合法性验证
		///
		//如BodyCrc值为空,则不进行检查
		if s.CheckBody(msg.BodyCrc, msg.Body) == false {
			s.Stop()
			log.Println("[IOLoop] [CheckBody] 数字签名不符,消息内容有被改过,断开连接.")
			return
		}

		// 是否为重放攻击
		if s.IsReplayAttack(msg.Timestamp, msg.BodyCrc) {
			s.Stop()
			log.Println("[IOLoop] [IsReplayAttack] 碰到重放攻击,断开连接.")
			return
		}
		///

 还有一些就不列了.


相关的一些结构体:  

type MemStore struct {
	users  map[string]User
	mtlock sync.RWMutex
	//...
}

type Session struct {
	//...
	UserID           string
	MsgLastTimestamp int64  //最末消息包Timestamp
	MsgLastBodyCrc   string //最末消息包BodyCrc
	//...
}

type User struct {
	ID        string
	Token     string
	CreatedAt time.Time //Token生成时间
	ExpiresAt time.Time //Token超期时间
	//...
}

           这套方案我认为还算简单可行。不过相关人士表示不太感冒,认为不够安全(似乎分分钟被破的节奏),要用更安全更复杂的方案。  

好吧,这方面不太懂,不过好歹也花了我点功夫。记一下,不然过段时间就不记得了。 反正用的也都是烂大街的东西。

也没被采用,应当无甚关系。  


BLOG: http://blog.csdn.net/xcl168


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值