Kerberos认证模型(c语言实现)

文章目录

  • Kerberos认证模型
    • 原理概述
      • 认证流程
        • 首先,用户使用客户端(用户自己的机器)上的程序进行登录:
        • 随后,客户端认证(客户端(Client)从认证服务器(AS)获取票据的票据(TGT)):
        • 然后,服务授权(client从TGS获取票据(client-to-server ticket)):
        • 最后,服务请求(client从SS获取服务):
    • 总体结构设计
    • 数据结构设计
    • 编译运行结果
      • 认证成功
    • 验证用例
      • 认证失败案例
    • 代码资源

Kerberos认证模型

原理概述

Kerberos是一种计算机网络认证协议,它允许某实体在非安全网络环境下通信,向另一个实体以一种安全的方式证明自己的身份。它也指由麻省理工实现此协议,并发布的一套免费软件。它的设计主要针对客户-服务器模型,并提供了一系列交互认证——用户和服务器都能验证对方的身份。Kerberos协议可以保护网络实体免受窃听和重复攻击。

Kerberos协议基于对称密码学,并需要一个值得信赖的第三方。Kerberos协议的扩展可以为认证的某些阶段提供公钥密码学支持。

认证流程

首先,用户使用客户端(用户自己的机器)上的程序进行登录:

  • 用户输入用户ID和密码到客户端。
  • 客户端程序运行一个单向函数(大多数为杂凑)把密码转换成密钥,这个就是客户端(用户)的“用户密钥”(user’s secret key)。

随后,客户端认证(客户端(Client)从认证服务器(AS)获取票据的票据(TGT)):

  • Client向AS发送1条明文消息,申请基于该用户所应享有的服务,例如“用户Sunny想请求服务”(Sunny是用户ID)。(注意:用户不向AS发送“用户密钥”(user’s secret key),也不发送密码)该AS能够从本地数据库中查询到该申请用户的密码,并通过相同途径转换成相同的“用户密钥”(user’s secret key)。

  • AS检查该用户ID是否在于本地数据库中,如果用户存在则返回2条消息:

    • 消息A:Client/TGS会话密钥(Client/TGS Session Key)(该Session Key用在将来Client与TGS的通信(会话)上),通过用户密钥(user’s secret key)进行加密
    • 消息B:票据授权票据(TGT)(TGT包括:消息A中的“Client/TGS会话密钥”(Client/TGS Session Key),用户ID,用户网址,TGT有效期),通过TGS密钥(TGS’s secret key)进行加密
  • 一旦Client收到消息A和消息B,Client首先尝试用自己的“用户密钥”(user’s secret key)解密消息A,如果用户输入的密码与AS数据库中的密码不符,则不能成功解密消息A。输入正确的密码并通过随之生成的"user’s secret key"才能解密消息A,从而得到“Client/TGS会话密钥”(Client/TGS Session Key)。(注意:Client不能解密消息B,因为B是用TGS密钥(TGS’s secret key)加密的)。拥有了“Client/TGS会话密钥”(Client/TGS Session Key),Client就足以通过TGS进行认证了。

然后,服务授权(client从TGS获取票据(client-to-server ticket)):

  • 当client需要申请特定服务时,其向TGS发送以下2条消息:

    • 消息c:即消息B的内容(TGS’s secret key加密后的TGT),和想获取的服务的服务ID(注意:不是用户ID)
    • 消息d:认证符(Authenticator)(Authenticator包括:用户ID,时间戳),Client/TGS会话密钥(Client/TGS Session Key)进行加密
  • 收到消息c和消息d后,TGS首先检查KDC数据库中是否存在所需的服务,查找到之后,TGS用自己的“TGS密钥”(TGS’s secret key)解密消息c中的消息B(也就是TGT),从而得到之前生成的“Client/TGS会话密钥”(Client/TGS Session Key)。TGS再用这个Session Key解密消息d得到包含用户ID和时间戳的Authenticator,并对TGT和Authenticator进行验证,验证通过之后返回2条消息:

    • 消息E:client-server票据(client-to-server ticket)(该ticket包括:Client/SS会话密钥 (Client/Server Session Key),用户ID,用户网址,有效期),通过提供该服务的服务器密钥(service’s secret key)进行加密
    • 消息F:Client/SS会话密钥( Client/Server Session Key)(该Session Key用在将来Client与Server Service的通信(会话)上),通过Client/TGS会话密钥(Client/TGS Session Key)进行加密
  • Client收到这些消息后,用“Client/TGS会话密钥”(Client/TGS Session Key)解密消息F,得到“Client/SS会话密钥”(Client/Server Session Key)。(注意:Client不能解密消息E,因为E是用“服务器密钥”(service’s secret key)加密的)。

最后,服务请求(client从SS获取服务):

  • 当获得“Client/SS会话密钥”(Client/Server Session Key)之后,Client就能够使用服务器提供的服务了。Client向指定服务器SS发出2条消息:

    • 消息e:即上一步中的消息E“client-server票据”(client-to-server ticket),通过服务器密钥(service’s secret key)进行加密
    • 消息g:新的Authenticator(包括:用户ID,时间戳),通过Client/SS会话密钥(Client/Server Session Key)进行加密
  • SS用自己的密钥(service’s secret key)解密消息e从而得到TGS提供的Client/SS会话密钥(Client/Server Session Key)。再用这个会话密钥解密消息g得到Authenticator,(同TGS一样)对Ticket和Authenticator进行验证,验证通过则返回1条消息(确认函:确证身份真实,乐于提供服务):

    • 消息H:新时间戳(新时间戳是:Client发送的时间戳加1,v5已经取消这一做法),通过Client/SS会话密钥(Client/Server Session Key)进行加密
  • Client通过Client/SS会话密钥(Client/Server Session Key)解密消息H,得到新时间戳并验证其是否正确。验证通过的话则客户端可以信赖服务器,并向服务器(SS)发送服务请求。

  • 服务器(SS)向客户端提供相应的服务。

总体结构设计

各个进程函数结构设计

  • Client
// Step1 发送用户名到AS
void SendToAS(char *clientID);
// Step2 从AS接收消息A和消息B
void ReceiveFromAS(MsgA *msgA, MsgB *msgB);
// Step3 解密消息A得到K_CT会话密钥
char* DecryptMsgA(MsgA msgA, char *userPassword);
void CreatMsgC(MsgC *msgC, char *serviceID, MsgB msgB);
void CreatMsgD(MsgD *msgD, char *K_CT, char *clientID);
// Step4 发送消息C和D到TGS
void SendToTGS(MsgC *msgC, MsgD *msgD);
// Step5 从TGS接收消息
void ReceiveFromTGS(MsgE *msgE, MsgF *msgF);
// Step6 解密消息F得到K_CS
char* DecryptMsgF(MsgF msgF, char *K_CT);
void CreateMsgG(MsgG *msgG, char *username, char *K_CS);
// Step7 发送消息E和G到SS
void SendToSS(MsgE msgE, MsgG msgG);
// Step8 从SS接收消息
void ReceiveFromSS(MsgH *msgH);
// Step9 认证
void AuthenticateSS(char *oldTs, char *newTs);
  • AS
ClientInfo isExist(char *clientID);
// Step1 收到用户名并检查
ClientInfo ReceiveFromClient();
// Step2 用Hash密码加密K_TGS生成消息A
void CreatMsgA(MsgA *msgA, char *userPassword, char *K_CT);
// Step3 用K_TGS加密消息B
void CreatMsgB(MsgB *msgB, char *K_CT, ClientInfo clientInfo, char *K_TGS);
// Step4 发送消息
void SendToClient(MsgA msgA, MsgB msgB);
  • TGS
// Step1 接收消息C和D
void ReceiveFromClient(MsgC *msgC, MsgD *msgD);
// Step2 解密消息B
void DecryptMsgB(MsgB msgB, char *K_TGS, MsgB *De_msgB);
// Step3 解密消息D
void DecryptMsgD(MsgD msgD, char *K_CT, MsgD *De_msgD);
// Step4 认证
bool AuthenticateClient(MsgB De_msgB, MsgD De_msgD);
void CreateMsgE(MsgE *msgE, char *serviceID, MsgB De_msgB, char *K_CS, char *K_SS);
void CreateMsgF(MsgF *msgF, char *K_CS,  char *K_CT);
// Step5 发送消息
void SendToClient(MsgE msgE, MsgF msgF);
  • SS
// Step1 接收消息C和D
void ReceiveFromClient(MsgE *msgE, MsgG *msgG);
// Step2 解密消息E得到K_CS
char* DecryptMsgE(MsgE msgE, char *K_SS);
// Step3 解密消息G
void DecryptMsgG(MsgG msgG, char *K_CS, MsgG *De_msgG);
void CreateMsgH(MsgH *msgH, MsgG De_msgG, char *K_CS);
// Step4 发送消息
void SendToClient(MsgH msgH);

数据结构设计

// 用户信息
typedef struct clientInfo
{
     
    char *clientID;     // 用户ID
    char *clientPass;   // 用户口令
    char *clientAddr;   // 网络地址
} ClientInfo;

typedef struct MsgA
{
     
    char *K_CT;         // Client/TGS 会话密钥
} MsgA;

typedef struct MsgB
{
     
    char *clientID;
    char *clientAddr;
    char *vaildity;
    char *K_CT;
} MsgB;

typedef struct MsgC
{
     
    char *serviceID;    // 服务ID
    MsgB msgB;
} MsgC;

typedef struct MsgD
{
     
    char *clientID;
    char *timestamp;    // 时间戳
} MsgD;

typedef struct MsgE
{
     
    char *serviceID;
    // ST
    char *clientID;
    char *clientAddr;
    char *vaildity;
    char *K_CS;         // Client/SS 会话密钥
} MsgE;

typedef struct MsgF
{
     
    char *K_CS; 
} MsgF;

typedef struct MsgG
{
     
    char *clientID;
    char *timestamp;    
} MsgG;

typedef struct MsgH
{
     
    char *clientID;
    char *ts;           // 更新时间戳
} MsgH;

编译运行结果

认证成功

Kerberos认证模型(c语言实现)_第1张图片
在这里插入图片描述
Kerberos认证模型(c语言实现)_第2张图片
Kerberos认证模型(c语言实现)_第3张图片

验证用例

认证失败案例

Kerberos认证模型(c语言实现)_第4张图片
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

原因:

  • 输入的口令不正确,导致在解密消息A时,无法获取正确的(Client/TGS会话密钥
  • 而消息d是通过 Client/TGS会话密钥 加密的,发送到 TGSTGS 就解密出不正确的明文,所以认证失败

代码资源

https://download.csdn.net/download/sinat_20019511/15728539

你可能感兴趣的:(c,Kerberos,信息安全,加密解密)