CHAP是一种挑战响应式协议。

CHAP全称为:Challenge Handshake Authentication Protocol。

CHAP密码 = 一个字节的标识符 + MD5(一个字节的标识符+明文密码+挑战码)

注:+号只是连接符,两个串之间没有任何多余字符;

如:

挑战码 = cce964fe4807b30ddcda0903413d1a3a560710a2

一个字节的标识符 = 0x97

明文密码 = 20151013

CHAP密码 = "97" + MD5(0x97 + 20151013 + fromHex(cce964fe4807b30ddcda0903413d1a3a560710a2))

CHAP密码 = 9721e6dda93ed253cfdcbc20bab959afed

即调用如下函数时,参数如下:

string reqChallenge = "cce964fe4807b30ddcda0903413d1a3a560710a2";
string challange = fromHex(reqChallenge.c_str(), reqChallenge.length());
string ChapPasswd;
CHAPPasswdXor("20151013", 0x97, challange, ChapPasswd);

 如下是一个CHAP协议的实现算法:

#include <string>
#include "md5.h" #define RAD_PASSWORD_LEN 128
#define RAD_PSWDSEG_LEN 16
#define RAD_AUTHCATOR_LEN 16 std::string Hex(const char* cpSrcStr, int len, bool isUpper = false) {
if (cpSrcStr == NULL) {
return "";
}
std::string ret(len * 2, 0x00);
const char* hex = isUpper ? "0123456789ABCDEF" : "0123456789abcdef";
for (size_t i = 0; i < len; ++i) {
unsigned char v = static_cast<unsigned char>(cpSrcStr[i]);
ret[2*i] = hex[(v >> 4) & 0x0f];
ret[2*i+1] = hex[ v & 0x0f];
}
return ret;
} char asc_bcd(const char *aBcdStr) {
unsigned char digit; digit = (aBcdStr[0] >= 'a' ? ((aBcdStr[0]) - 'a')+10 : (aBcdStr[0] - '0'));
digit *= 16;
digit += (aBcdStr[1] >= 'a' ? ((aBcdStr[1]) - 'a')+10 : (aBcdStr[1] - '0'));
return digit;
} std::string fromHex(const char* from, size_t len) {
std::string ret(len / 2, 0x00);
for (size_t ii = 0; ii < len / 2; ii++)
ret[ii] = asc_bcd(from + ii * 2);
return ret;
} void MD5Calc(const unsigned char *input,
unsigned int inlen, unsigned char *output) {
MD5_CTX context;
MD5Init(&context);
MD5Update(&context, (unsigned char *)input, inlen);
MD5Final(output, &context);
} int CHAPPasswdXor(const char *aPasswd, unsigned char aIdentifier,
const std::string& aChallenge, std::string &aOutPasswd)
{
char localPwd[RAD_PASSWORD_LEN+1] = {0};
int pwLen = strlen(aPasswd); if (pwLen > RAD_PASSWORD_LEN) {
//LOG_INFO("%s:Password is too long.");
return -1;
} char *pwStr = localPwd;
*pwStr++ = aIdentifier;
strcpy(pwStr, aPasswd);
pwStr += pwLen;
// challenge is append if challenge is exist.
memcpy(pwStr, aChallenge.data(), aChallenge.length());
pwLen += aChallenge.length() + 1; // Encrypted.
char md5Output[RAD_AUTHCATOR_LEN+1] = {0};
MD5Calc((unsigned char *)localPwd, pwLen, (unsigned char *)md5Output); // get the CHAP password
pwStr = localPwd;
*pwStr++ = aIdentifier;
memcpy(pwStr, md5Output, RAD_AUTHCATOR_LEN);
aOutPasswd = Hex(localPwd, RAD_PSWDSEG_LEN+1);
return 0;
}

CHAP算法C++实现的更多相关文章

  1. PPP中的PAP和CHAP的区别

    PAP PAP是简单认证,明文传送,客户端直接发送包含用户名/口令的认证请求,服务器端处理并回应. CHAP CHAP是加密认证,先由服务器端给客户端发送一个随机码 challenge,客户端根据 c ...

  2. CHAP认证(双向)

    实验要求:掌握CHAP认证配置 拓扑如下: R1enable 进入特权模式configure terminal    进入全局模式hostname R1 设置主机名 interface s0/0/0 ...

  3. 路由器配置PPP协议 CHAP验证 PAP验证

    路由器配置PPP协议 CHAP验证 PAP验证 来源 https://www.cnblogs.com/tcheng/p/5967485.html PAP是两次握手,明文传输用户密码进行认证:CHAP是 ...

  4. B树——算法导论(25)

    B树 1. 简介 在之前我们学习了红黑树,今天再学习一种树--B树.它与红黑树有许多类似的地方,比如都是平衡搜索树,但它们在功能和结构上却有较大的差别. 从功能上看,B树是为磁盘或其他存储设备设计的, ...

  5. 分布式系列文章——Paxos算法原理与推导

    Paxos算法在分布式领域具有非常重要的地位.但是Paxos算法有两个比较明显的缺点:1.难以理解 2.工程实现更难. 网上有很多讲解Paxos算法的文章,但是质量参差不齐.看了很多关于Paxos的资 ...

  6. 【Machine Learning】KNN算法虹膜图片识别

    K-近邻算法虹膜图片识别实战 作者:白宁超 2017年1月3日18:26:33 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现的深入理解.本系列文章是作者结 ...

  7. 红黑树——算法导论(15)

    1. 什么是红黑树 (1) 简介     上一篇我们介绍了基本动态集合操作时间复杂度均为O(h)的二叉搜索树.但遗憾的是,只有当二叉搜索树高度较低时,这些集合操作才会较快:即当树的高度较高(甚至一种极 ...

  8. 散列表(hash table)——算法导论(13)

    1. 引言 许多应用都需要动态集合结构,它至少需要支持Insert,search和delete字典操作.散列表(hash table)是实现字典操作的一种有效的数据结构. 2. 直接寻址表 在介绍散列 ...

  9. 虚拟dom与diff算法 分析

    好文集合: 深入浅出React(四):虚拟DOM Diff算法解析 全面理解虚拟DOM,实现虚拟DOM

随机推荐

  1. c 开源代码

    阅读优秀代码是提高开发人员修为的一种捷径……1. WebbenchWebbench是一个在linux下使用的非常简单的网站压测工具.它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在 ...

  2. iOS - Availability.h

    >for 'dispatch' application inner to begin note `#include <Availability.h>` These macros ar ...

  3. HDU5671Matrix(矩阵行列交换)

    有一个nn行mm列的矩阵(1 \leq n \leq 1000 ,1 \leq m \leq 1000 )(1≤n≤1000,1≤m≤1000),在这个矩阵上进行qq (1 \leq q \leq 1 ...

  4. ES6之模版字符串

    ES6之模版字符串 最近在项目中使用了ES6的模版字符串,在这里加以总结. 1.之前我们也可以使用JavaScript输出模版字符串,通常是下面这样的: $("#result"). ...

  5. HTML之表格制作

    如何制作一个表格? 如何制作一个表格呢?  观察如下代码: <!DOCTYPE html> <html lang="en"> <head> &l ...

  6. 未签名有元程序集 Unsigned Friend Assemblies

    C#中的访问修饰符internal可以使类型在同程序集中可以被相互访问.但有时会有这样一个要求,我们希望一个程序集中的类型可以被外部的某些程序集访问,如果设置成public的话,就被所有的外部程序集访 ...

  7. GridView数据格式化

    一.动态生成列的格式化 此种GridView中的列是动态生成的,格式化可以通过RowDataBound事件进行.如下边代码,对第十列的值进行格式化. protected void gvUserList ...

  8. IO多路复用及ThreadingTCPServer源码阅读

    IO多路复用 socket模块是阻塞的,通过socket建立的服务端可以接收多个请求,但只能同时处理一个请求,其他请求都被阻塞.可以通过IO多路复用解决这个问题,socketserver内部使用的就是 ...

  9. Android学习笔记——MixLayout

    该工程的功能是实现LinearLayout+TableLayout 以下代码是MainActivity.java中的代码 package com.example.mixlayout; import a ...

  10. string.capwords() 将每个单词首字母大写

    string.capwords() 将每个单词首字母大写 代码: import string s = ' The quick brown fox jumped over the lazy dog. ' ...