客户端到服务器的身份验证在C ++中使用套接字 [英] Client to Server Authentication in C++ using sockets

查看:96
本文介绍了客户端到服务器的身份验证在C ++中使用套接字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我采取一个登录/认证系统为我的小服务器 - 客户端程序。我不知道如何去了解这一点,我希望能得到堆栈溢出一些伟大的秘诀/咨询一如既往。这是我想象我会做到这一点。

I'm implementing a login/authentication system for my little server-client program. I'm wondering how to go about this, and I was hoping to get some great tips/advice from Stack Overflow as always. This is how I imagine I'll do it.


  • 客户端连接到服务器。

  • 服务器发送一个令牌的客户端(基于时间可能和其他)

  • 客户端返回用户名和SHA1加密的口令,与令牌一起。

  • 服务器接收他们,并验证用户在服务器端的数据库中的凭据。

  • 令牌现在验证,用户使用令牌登录。

这是在做这件事的所有安全的方式?我计算客户端还发送一个序列密钥或一些这样的,以形成一个串/令牌对,从而另一客户端不能伪造同理(尽管由服务器侧生成的标记)。

Is this at all a secure way of doing it? I figured the client also sends a serial key or some such to form a serial / token pair, so that another client cannot fake the same token (though the token is generated by the server-side).

实施细节不是必需的,因为我能够做的实现。

Implementation details aren't required, as I am capable of doing the implementation.

我的问题,而是两个问题:

My question would, rather, two questions:


  • 有哪些途径可实现与插座一个登录/认证系统

  • 有哪些途径来保护我的客户端到服务器的连接

  • 修改:我忘了问,因为这是一个C ++的问题,是否有可以协助加密/验证
  • 的库?
  • What ways are there to achieve a login/authentication system with sockets
  • What ways are there to secure my client-to-server connection
  • EDIT: I forgot to ask, as this is a C++ question, are there any libraries that can assist in encryption/authentication?

安全性对我来说是一个问题,所以我想确保我这样做是正确的。

Security is an issue for me, so I want to be sure I do it right.

也许一些背景信息。这是一个游戏服务器,一个人用他的账户登录,并采取了大厅,在那里,他可以选择一个世界服务器上播放。世界服务器是在同一网络中运行(可能)在不同的机器上一个单独的进程。

Maybe some background information. It's a game server, a person logs in with his account and is taken to a 'Lobby', where he can pick a 'World Server' to play on. The world server is a separate process running (possibly) on a different machine in the same network.

出于这个原因,我想在这个会话的概念,产生在用户登录和会话,登录服务器中继届世界服务器的用户挑选,让世界服务器知道用户实际上登录。

For that reason, I want to have a concept of a session in this, the user logs in and a session is generated, the login server relays the session to the world server the user picks, so that world server knows that the user is actually logged in.

我认为客户将不得不在会议确认世界服务器和所有,而是以后我会担心。

I reckon the client will have to confirm the session to the world server and all that, but I'll worry about that later.

真诚的,
杰西

推荐答案

您一般做的的要在链路发送密码可言,甚至没有加密。通常的方法是一个挑战 - 响应协议

You generally do not want to send the password over the link at all, not even with encryption. The usual method is a challenge-response protocol.


  1. 客户端连接到服务器,在用户名发送(不过的的密码)

  2. 服务器发送出独特的随机数响应

  3. 客户端加密,使用密码的哈希作为关键
  4. 随机数
  5. 客户端发送加密的随机数与服务器

  6. 服务器加密的用户密码的哈希值正确
  7. 随机数
  8. 服务器比较两个加密的随机数

  1. The client connects to the server, sending in the user-name (but not password)
  2. The server responds by sending out unique random number
  3. The client encrypts that random number using the hash of their password as the key
  4. The client sends the encrypted random number to the server
  5. The server encrypts the random number with the correct hash of the user's password
  6. The server compares the two encrypted random numbers

这有几个优点。首先,它意味着密码永不熄灭过任何形式的联系。其次,它是免疫重放攻击 - 当攻击者记录了谈话,他们就无法重放客户端的答复后进行登录,因为随机数会发生变化。

This has a couple of advantages. First, it means the password never goes over the link in any form. Second, it's immune to a replay attack -- if an attacker records the conversation, they can't replay the client's replies later to log in, because the random number will have changed.

安全连接(即加密内容)是有点简单。通常情况下,这两个中的一个(并不重要其中大部分)选取一个随机数,与其他的公共密钥对其进行加密,并将其发送到另一方。其他的解密,而且他们使用的对称加密一键加密会话的其余部分。

Securing the connection (i.e., encrypting the content) is a little simpler. Typically, one of the two (doesn't really matter much which) picks a random number, encrypts it with the other's public key, and sends it to the other. The other decrypts it, and they encrypt the rest of the session using that as a key for symmetric encryption.

图书馆: Beecrypt 并的 OpenSSL的有几个明显的几种。除非你有一个相当具体的理由不这样做,TLS是什么,你可能需要使用(它比我先前提到,包括双向认证相当多的,所以不仅在服务器知道谁是客户端是,但客户也知道谁是服务器,所以它的合理验证它没有连接到别人谁可能只是收集他的信用卡号码,并运行它)。

Libraries: Beecrypt and OpenSSL are a couple of obvious ones. Unless you have a fairly specific reason to do otherwise, TLS is what you probably want to use (it does quite a bit more than what I've outlined above, including two-way authentication, so not only does the server know who the client is, but the client also knows who the server is, so it's reasonably verified that it's not connected to somebody else who might just collect his credit card number and run with it).

编辑:

要加密无一切的开销,验证每一个数据包,你可以做这样的事情:

To authenticate each packet without the overhead of encrypting everything, you could do something like this:


  1. 服务器与挑战
  2. 将其公钥发送
  3. 客户端产生一个随机数,与该服务器的公共密钥对其进行加密,并用其响应
  4. 将其发送回
  5. 数是用于反模式加密第一号

  6. 客户端包括与它发送的每个数据包
  7. 一个反模式的结果
  1. The server sends its public key with the challenge
  2. The client generates a random number, encrypts it with the server's public key, and sends it back with its response
  3. The number is the first number used for counter-mode encryption
  4. The client includes one counter-mode result with each packet it sends

计数器模式意味着你刚刚产生连续的数字,反过来,每个加密使用正确的键。在这种情况下,密钥将是客户的密码的哈希值。这意味着每个数据包包含一个唯一的随机数,无论是客户机和服务器可以生成,但没有其他人可以。通过使用计数器模式加密,每个分组都有一个唯一的随机数。通过从一个随机数开始,每个会话将具有随机数的唯一的序列

Counter mode means you just generate consecutive numbers, and encrypt each in turn, using the right key. In this case, the key would be the hash of the client's password. What this means is that each packet will contain a unique random number that both the client and the server can generate, but nobody else can. By using the counter-mode encryption, each packet will have a unique random number. By starting from a random number, each session will have a unique sequence of random numbers.

要尽量减少开销,您可以发送只是每个数据包的结果的一部分 - 例如,如果在计数器模式下使用AES,它会为每个用户加密数16个字节的结果。仅包含(说)两个字节的与每个数据包,所以你只需要加密数字每8个数据包一次。从理论上讲,这减少安全 - 攻击者可以只是尝试了所有包6553​​6可能的值,但如果你认为以后(说)两个坏尝试连接已被攻破,攻击者获得正确的价值的机会成为pretty小(当然,你可以pretty多挑你愿意通过控制不良企图你允许你在每一个数据包包括数量和认证的大小与生活的机会)。

To minimize overhead, you could send just a part of the result with each packet -- e.g., if you use AES in counter mode, it'll generate 16 bytes of result for each number you encrypt. Include only (say) two bytes of that with each packet, so you only have to encrypt a number once every 8 packets. In theory, this cuts security -- an attacker could just try all 65536 possible values for a packet, but if you assume the connection has been compromised after (say) two bad attempts, the chances of an attacker getting the right value become pretty small (and, of course, you can pretty much pick the chances you're willing to live with by controlling the number of bad attempts you allow and the size of authentication you include in each packet).

这篇关于客户端到服务器的身份验证在C ++中使用套接字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆