博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
PAP认证方式原理和实现
阅读量:6818 次
发布时间:2019-06-26

本文共 3105 字,大约阅读时间需要 10 分钟。

PAP认证协议

基本描述:

  Password Authentication Protocol 口令认证协议

  PAP认证过程非常简单,二次握手机制,使用明文格式发送用户名和密码,发起方为被认证方,可以做无限次的尝试(暴力破解),只在链路建立的阶段进行PAP认证,一旦链路建立成功将不再进行认证检测。

     rfc参考:rfc2865.txt

使用场景:

  PPPOE拨号和Radius认证环境中。

     

加密原理:

       加密时将明文按照16字节分块为p1, p2, ..., pi多个小块。

     

描述
字段 意义
S 共享密钥
RA 128位的请求认证码
p1,p2,...,pi 将明文密码按照16字节分块
c(1),c(2),...,c(i) 加密后的密文串

 

 

 

 

 

 

  最终得到的加密密文串是 c(1)+c(2)+...+c(i)连接起来的串。

解密原理:

      解密时将密文按照16字节分块为c(1), c(2), ..., c(i)多个小块。

     

  最终得到的解密后的明文串是 p1+p2+...+pi连接起来的串。

代码实现:

加密:

#define RAD_PSWDSEG_LEN   16#define RAD_AUTHCATOR_LEN 16#define RET_ERROR -1#define RET_OK     0std::string peerShareSecret_ = "88----89";// ---------------------------------------------------------------------------// int :PasswdXor//// Use for encrypt the password attribute.// ---------------------------------------------------------------------------//int PasswdXor(const char *aPasswd, string &aOutPasswd){    if (aPasswd == NULL) {        return RET_ERROR;    }    char localPwd[RAD_PASSWORD_LEN+1] = {0};    int  pwLen = strlen(aPasswd);    // Pad the password. If the length of the passwd isn't multiples of 16, pad it.    if (pwLen > RAD_PASSWORD_LEN) {        return RET_ERROR;    }    char *pwStr = localPwd;    strcpy(localPwd, aPasswd);    int n = pwLen - (pwLen/RAD_PSWDSEG_LEN) * RAD_PSWDSEG_LEN;    if (n != 0) {        memset(pwStr+pwLen, 0, RAD_PSWDSEG_LEN - n);        pwLen += 16 - n;    }    // Encrypted.    char md5Input[RAD_SECRET_LEN + RAD_AUTHCATOR_LEN] = {0};    char md5Output[RAD_AUTHCATOR_LEN] = {0};    char * inStr = md5Input;    int inlen = peerShareSecret_.length() + RAD_AUTHCATOR_LEN;    strcpy(inStr, peerShareSecret_.c_str());    inStr += peerShareSecret_.length();    memcpy(inStr, (char *)authcator_, RAD_AUTHCATOR_LEN);    int passEncodeLen = pwLen;    for (; pwLen > 0; pwLen -= RAD_PSWDSEG_LEN) {        MD5Calc((unsigned char *)md5Input, inlen, (unsigned char *)md5Output);        int i ;        for (i =0; i

  

解密:

int PasswdDecodeXor(const char *aPasswd, string &aOutPasswd){    if (aPasswd == NULL) {        return RET_ERROR;    }    int pwLen = strlen(aPasswd);    if (pwLen < 32) {        return RET_ERROR;    }    char md5Input[RAD_SECRET_LEN + RAD_AUTHCATOR_LEN] = {0};    char md5Output[RAD_AUTHCATOR_LEN] = {0};    char * inStr = md5Input;    int inlen = peerShareSecret_.length() + RAD_AUTHCATOR_LEN;    strcpy(inStr, peerShareSecret_.c_str());    inStr += peerShareSecret_.length();    memcpy(inStr, (char *)authcator_, RAD_AUTHCATOR_LEN);    aOutPasswd = "";    for(int i = 0; i < pwLen / 32; i++){        char pwStr[RAD_PSWDSEG_LEN + 1] = { 0 };        string hexPass = fromHex(aPasswd+i*32, 32);        memcpy(pwStr, hexPass.data(), 16);        MD5Calc((unsigned char *)md5Input, inlen, (unsigned char *)md5Output);        for (int i = 0; i < RAD_PSWDSEG_LEN; ++i)            pwStr[i] ^= md5Output[i];        pwStr[RAD_PSWDSEG_LEN] = 0x00;        aOutPasswd += pwStr;        if (strlen(pwStr) < RAD_PSWDSEG_LEN) {            break;        } else {            memcpy(inStr, hexPass.data(), 16);        }    }    return  RET_OK;}

Done.

转载于:https://www.cnblogs.com/voipman/p/5345320.html

你可能感兴趣的文章
loadrunner检查点设置失败,日志中SaveCount无法被正常统计出来
查看>>
循环结构进阶
查看>>
bzoj 2809: [Apio2012]dispatching
查看>>
关于数据库查询时报“query block has incorrect number of result columns”
查看>>
记录一款Unity VR视频播放器插件的开发
查看>>
webApi跨域问题
查看>>
读取文件
查看>>
json字符串转换对象的方法1
查看>>
浅谈网站路径分析 转自“蓝鲸网站分析博客”
查看>>
C# Note36: .NET unit testing framework
查看>>
我的博客第一天
查看>>
Aptana studio 3前端开发编辑器推荐
查看>>
RMAN restore fails with ORA-01180: can not create datafile 1 (文档 ID 1265151.1)
查看>>
转 多个版本的数据库在同一服务器上ORA-12557
查看>>
Socket的长连接和短连接
查看>>
java求素数和求一个数的一个正整数的质因数
查看>>
centos6.6 部署 cacti 并采集交换机流量
查看>>
web 开发之js---巧用iframe实现jsp无刷新上传文件
查看>>
WMS相关中英文术语
查看>>
实时监测网络流量
查看>>