PAP认证方式原理和实现
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 0
std::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<RAD_PSWDSEG_LEN; ++i)
pwStr[i] ^= md5Output[i]; memcpy(inStr, pwStr, RAD_PSWDSEG_LEN);
pwStr += RAD_PSWDSEG_LEN;
} aOutPasswd = EndcodePwd(localPwd, passEncodeLen);
return RET_OK;
}
解密:
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.
PAP认证方式原理和实现的更多相关文章
- Git认证方式https和ssh的原理及比较
常见的代码托管平台GitHub.GitLab和BitBucket等,基本都会使用Git作为版本控制工具.平台一般都提供两种认证方式https和ssh.了解该过程能够更加自由的配置和使用,本文就来简单聊 ...
- oracle 认证方式
Oracle登录的时候有两种认证方式,一种是“操作系统认证”,一种是“口令文件认证”.1.当采取操作系统认证的时候,在本地用任何用户都可以以sysdba登陆:(默认方式)2.当采取口令文件认证的时候, ...
- 比RBAC更好的权限认证方式(Auth类认证)
Auth 类已经在ThinkPHP代码仓库中存在很久了,但是因为一直没有出过它的教程, 很少人知道它, 它其实比RBAC更方便 . RBAC是按节点进行认证的,如果要控制比节点更细的权限就有点困难了, ...
- Java 实现 SSH 协议的客户端登录认证方式--转载
背景 在开篇之前,让我们先对 SSH 协议有个宏观的大致了解,这样更有利于我们对本文的加深了解.首先要提到的就是计算机网络协议,所谓计算机网络协议,简单的说就是定义了一套标准和规则,使得不同计算机之间 ...
- 阿里云API网关(11)API的三种安全认证方式
网关指南: https://help.aliyun.com/document_detail/29487.html?spm=5176.doc48835.6.550.23Oqbl 网关控制台: https ...
- oracle登陆认证方式
转自:http://blog.itpub.net/14359/viewspace-683064/ 案例: 1,发现此时操作系统认证不成功: C:\Users\Administrator.WIN-201 ...
- OAuth认证协议原理分析及同步消息到Twitter和Facebook使用方法
OAuth有什么用?为什么要使用OAuth? twitter或豆瓣用户一定会发现,有时候,在别的网站,点登录后转到 twitter登录,之后转回原网站,你会发现你已经登录此网站了,这种网站就是这个效果 ...
- thinkphp Auth认证类 比RBAC更好的权限认证方式(Auth类认证)
thinkphp Auth认证类 比RBAC更好的权限认证方式(Auth类认证) Auth 类已经在ThinkPHP代码仓库中存在很久了,但是因为一直没有出过它的教程, 很少人知道它, 它其实比 ...
- thinkphp 比RBAC更好的权限认证方式(Auth类认证)
Auth 类已经在ThinkPHP代码仓库中存在很久了,但是因为一直没有出过它的教程, 很少人知道它, 它其实比RBAC更方便 . RBAC是按节点进行认证的,如果要控制比节点更细的权限就有点困难了, ...
随机推荐
- HTML 学习笔记 JavaScript(call方法详解)
http://www.cnblogs.com/f-dream/p/4950918.html
- Python元组
Python的元组与列表类似,不同之处在于元组的元素不能修改. 元组使用小括号,列表使用方括号. 元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可. 如下实例: tup1 = ('physi ...
- Android Studio 常见异常解决办法
Error:Failed to crunch file D:\Englis_installation_directory\AndroidStudio\AndroidWorkSpace\YoukAndr ...
- springmvc:jsp fmt标签格式化Date时间,格式化后可以用于页面展示
java后台的对象时间参数是date类型,在前端想格式化,又是放在input输入框中的 先引入jstl标签库 <%@taglib uri="http://java.sun.com/js ...
- git的基本介绍和使用
前言:从事iOS开发一年多以来,一直使用svn管理源代码.对svn的特点和弊端已经深有体会.前些天双十二前后,项目工期紧张到爆,起早贪黑的加班,可谓披星戴月,这还不止,回到家中还要疯狂的敲代码.那么问 ...
- c# 本周时间查询
var now = DateTime.Now();int weeknow = Convert.ToInt32(now.DayOfWeek); //因为是以星期一为第一天,所以要判断weeknow等于0 ...
- JAVA实现带图片的列表——JList
JList:显示对象列表并且允许用户选择一个或多个项的组件. JList的构造方法: 1.根据数组创建列表: JList(Object[] listData) 构造一个 JList,使其显示指定数组中 ...
- strchr()函数 和 strrchr() 函数
strchr 定义于头文件 <string.h>char *strchr( const char *str, int ch );寻找ch(按照如同(char)ch的方式转换成char后)在 ...
- zookeeper原理解析-序列化
1)底层通信数据封装与操作 BinaryInputArchive& BinaryOutputArchive底层通信数据封装与操作 BinaryInputArchiv ...
- MySQL索引原理及慢查询优化
原文:http://tech.meituan.com/mysql-index.html 一个慢查询引发的思考 select count(*) from task where status=2 and ...