php curl模拟单点登录
这里说的模拟登录,也就是抓站的基础部分, 模拟登录,获取登录后的状态,然后模拟人的访问流程,获取访问结果,分析保存之……
首先,抓站利器,httpwatch,也可以用firefox下的firebug或者chrome下自带的开发者工具,其实我原来一直都是用firefox或者chrome的,但是听说httpwatch很好,就拿来试用一下,结果用的还真是很舒服,不错。其次就是Snoopy.class.php,我用PHP,这个PHP类真是好用到极致了,用来抓站so easy。但是这个类用来抓一般的基于http的站是没问题的,如果要是https的就麻烦了,这个类在抓https的站时,采用的不是php本身的curl了,使用的是Linux/Unix下的原生CURL,所以这个类在windows下用着很麻烦,需要自己装一个windows下能用的curl,并且配置好环境。在sae下直接就是不行的了,如果是用Linux/Unix的话,就很方便了~~指定好curl的路径就可以了。我也有一个https的模拟登录签到的脚本,使用的是php的curl,没有使用Snoopy。
由于新浪采用了单点登录,所以一般的登录方法是不行的了,不是直接构造用户名密码POST到一个login action页面完事。先使用httpwatch抓取一下登录的流程吧。
整个登录的流程是这样的:
1)、输入用户名密码,点击登录(在用户名输入完onblur的时候会有一个自动检测邮箱合法性的过程,我们模拟时候可以忽略)。
2)、访问一个页面,获取到几个特殊的值,包括servertime,pcid,nonce,这几个值用来干什么的呢,我们再分析一下JS就可以发现了,是用来加密用户名和密码的。
3)、将加密后的用户名、密码以及一些其它信息,提交到SSO的login去申请ticket。(ticket就是SSO登录中用到的票据啦)
4)、认证成功,访问几个其它站点种下Cookie,(相当于把票给人家看门的看看,告诉他我有访问你内部的权限了)。
5)、返回爱问首页。
主要需要做的就是如何实现用户名和密码的加密,因为客户端是用js实现的,但是我们是写在脚本里的,无法调用js,所以,只能通过PHP来模拟一下js加密的实现过程了。
新浪的JS采用的应该是Dean Edwards的packer算法,其实不用管什么算来,拿来之后在Google一下js解密,放进去就是还原后的代码了。
在还原后,大概看了看,就明白了一个流程,用户名和密码都分别进行了加密,最重要的部分,就是加密的这块了。用户名用base64加密,密码用hex_sha1加密后加密再加盐再加密。我们现在需要做的,就是用PHP来实现这两个加密方法。(其实通过分析后发现,用户名采用base64加密,并未加盐,所以每次加密后的数据都是一样的,我们也没必要去实现base64的加密方法了。)
//用户名加密 d["su"] = sinaSSOEncoder.base64.encode(bi(a)); //密码加密 b = sinaSSOEncoder.hex_sha1("" + sinaSSOEncoder.hex_sha1(sinaSSOEncoder.hex_sha1(b)) + k.servertime + k.nonce) var sinaSSOEncoder = sinaSSOEncoder || {}; (function() { var n = 0; var o = 8; this.hex_sha1 = function(s) { return A(p(z(s), s.length * o)) }; var p = function(x, f) { x[f >> 5] |= 0x80 << (24 - f % 32); x[((f + 64 >> 9) << 4) + 15] = f; var w = Array(80); var a = 1732584193; var b = -271733879; var c = -1732584194; var d = 271733878; var e = -1009589776; for (var i = 0; i < x.length; i += 16) { var g = a; var h = b; var k = c; var l = d; var m = e; for (var j = 0; j < 80; j++) { if (j < 16) w[j] = x[i + j]; else w[j] = v(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1); var t = u(u(v(a, 5), q(j, b, c, d)), u(u(e, w[j]), r(j))); e = d; d = c; c = v(b, 30); b = a; a = t } a = u(a, g); b = u(b, h); c = u(c, k); d = u(d, l); e = u(e, m) } return Array(a, b, c, d, e) }; var q = function(t, b, c, d) { if (t < 20) return (b & c) | ((~b) & d); if (t < 40) return b ^ c ^ d; if (t < 60) return (b & c) | (b & d) | (c & d); return b ^ c ^ d }; var r = function(t) { return (t < 20) ? 1518500249: (t < 40) ? 1859775393:(t < 60) ? -1894007588 : -899497514 } var u = function(x, y) { var a = (x & 0xFFFF) + (y & 0xFFFF); var b = (x >> 16) + (y >> 16) + (a >> 16); return (b << 16) | (a & 0xFFFF) }; var v = function(a, b) { return (a << b) | (a >>> (32 - b)) }; var z = function(a) { var b = Array(); var c = (1 << o) - 1; for (var i = 0; i < a.length * o; i += o) b[i >> 5] |= (a.charCodeAt(i / o) & c) << (24 - i % 32); return b }; var A = function(a) { var b = n ? "0123456789ABCDEF": "0123456789abcdef"; var c = ""; for (var i = 0; i < a.length * 4; i++) { c += b.charAt((a[i >> 2] >> ((3 - i % 4) * 8 + 4)) & 0xF) + b.charAt((a[i >> 2] >> ((3 - i % 4) * 8)) & 0xF) } return c }; this.base64 = { encode: function(a) { a = "" + a; if (a == "") return ""; var b = ''; var c, chr2, chr3 = ''; var d, enc2, enc3, enc4 = ''; var i = 0; do { c = a.charCodeAt(i++); chr2 = a.charCodeAt(i++); chr3 = a.charCodeAt(i++); d = c >> 2; enc2 = ((c & 3) << 4) | (chr2 >> 4); enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); enc4 = chr3 & 63; if (isNaN(chr2)) { enc3 = enc4 = 64 } else if (isNaN(chr3)) { enc4 = 64 } b = b + this._keys.charAt(d) + this._keys.charAt(enc2) + this._keys.charAt(enc3) + this._keys.charAt(enc4); c = chr2 = chr3 = ''; d = enc2 = enc3 = enc4 = '' } while (i < a.length); return b }, _keys: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=' } }).call(sinaSSOEncoder);
后通过努力,把这个JS的对象封装成了一个PHP的类,具体的代码我就不贴出来了,好歹我也是浪人,自己就不危害自己啦,大家自己研究下,很简单的。
其中最难的亮点就是js中的 >>> 无符号右移 和 charCodeAt(i),PHP中没有这两个对应的实现,需要自己来写。
我把这两个难点贴出来供大家参考吧,其实这两个算法我也是参考的别人的,中间发现有一个算法是错的,浪费了我好长时间。。。。。
/** * 无符号32位右移 ;模拟实现JS的>>>,无符号右移。实现原理,化为二进制,先右移,后补零。 * @param mixed $x 要进行操作的数字,如果是字符串,必须是十进制形式 * @param string $bits 右移位数 * @return mixed 结果,如果超出整型范围将返回浮点数 */ function shr32($x, $bits){ // 位移量超出范围的两种情况 if($bits <= 0){ return $x; } if($bits >= 32){ return 0; } //转换成代表二进制数字的字符串 $bin = decbin($x); $l = strlen($bin); //字符串长度超出则截取底32位,长度不够,则填充高位为0到32位 if($l > 32){ $bin = substr($bin, $l - 32, 32); }elseif($l < 32){ $bin = str_pad($bin, 32, '0', STR_PAD_LEFT); } //取出要移动的位数,并在左边填充0 return bindec(str_pad(substr($bin, 0, 32 - $bits), 32, '0', STR_PAD_LEFT)); } //模拟实现JS的chaCodeAt() function getUnicodeFromOneUTF8($word) { //获取其字符的内部数组表示,所以本文件应用utf-8编码! if (is_array( $word)) $arr = $word; else $arr = str_split($word); //此时,$arr应类似array(228, 189, 160) //定义一个空字符串存储 $bin_str = ''; //转成数字再转成二进制字符串,最后联合起来。 foreach ($arr as $value) $bin_str .= decbin(ord($value)); //此时,$bin_str应类似111001001011110110100000,如果是汉字"你" //正则截取 $bin_str = preg_replace('/^.{4}(.{4}).{2}(.{6}).{2}(.{6})$/','$1$2$3', $bin_str); //此时, $bin_str应类似0100111101100000,如果是汉字"你" return bindec($bin_str); //返回类似20320,汉字"你" //return dechex(bindec($bin_str)); //如想返回十六进制4f60,用这句 }
是这两个算法了,还有一个无符号左移的,这里没用到,也贴下来,记录。
例子:
<?php /** * 无符号32位左移 * @param mixed $x 要进行操作的数字,如果是字符串,必须是十进制形式 * @param string $bits 左移位数 * @return mixed 结果,如果超出整型范围将返回浮点数 */ function shl32 ($x, $bits){ // 位移量超出范围的两种情况 if($bits <= 0){ return $x; } if($bits >= 32){ return 0; } //转换成代表二进制数字的字符串 $bin = decbin($x); $l = strlen($bin); //字符串长度超出则截取底32位,长度不够,则填充高位为0到32位 if($l > 32){ $bin = substr($bin, $l - 32, 32); }elseif($l < 32){ $bin = str_pad($bin, 32, '0', STR_PAD_LEFT); } //取出要移动的位数,并在右边填充0 return bindec(str_pad(substr($bin, $bits), 32, '0', STR_PAD_RIGHT)); }
有一个需要注意的是PHP和JS中的三元判断符的使用,PHP中是从右向左,JS中是从左向右。所以这个使用if…else…替代比较好。
还有一个就是JS的数组和PHP的数组问题,自己想办法解决吧。
解决了这个,剩下就没难题了,跟普通的抓站一样了。
构造好需要的POST数据,提交。
然后,获取返回的ticket,然后再模拟访问其它几个页面,把ticket给人家看门的看一眼,下次带Cookie直接访问里面就好了。
以上就是php curl模拟单点登录 PHP实现JS加密函数 的内容,更多相关内容请关注PHP中文网(www.php.cn)!

PHP仍然流行的原因是其易用性、灵活性和强大的生态系统。1)易用性和简单语法使其成为初学者的首选。2)与web开发紧密结合,处理HTTP请求和数据库交互出色。3)庞大的生态系统提供了丰富的工具和库。4)活跃的社区和开源性质使其适应新需求和技术趋势。

PHP和Python都是高层次的编程语言,广泛应用于Web开发、数据处理和自动化任务。1.PHP常用于构建动态网站和内容管理系统,而Python常用于构建Web框架和数据科学。2.PHP使用echo输出内容,Python使用print。3.两者都支持面向对象编程,但语法和关键字不同。4.PHP支持弱类型转换,Python则更严格。5.PHP性能优化包括使用OPcache和异步编程,Python则使用cProfile和异步编程。

PHP主要是过程式编程,但也支持面向对象编程(OOP);Python支持多种范式,包括OOP、函数式和过程式编程。PHP适合web开发,Python适用于多种应用,如数据分析和机器学习。

PHP起源于1994年,由RasmusLerdorf开发,最初用于跟踪网站访问者,逐渐演变为服务器端脚本语言,广泛应用于网页开发。Python由GuidovanRossum于1980年代末开发,1991年首次发布,强调代码可读性和简洁性,适用于科学计算、数据分析等领域。

PHP适合网页开发和快速原型开发,Python适用于数据科学和机器学习。1.PHP用于动态网页开发,语法简单,适合快速开发。2.Python语法简洁,适用于多领域,库生态系统强大。

PHP在现代化进程中仍然重要,因为它支持大量网站和应用,并通过框架适应开发需求。1.PHP7提升了性能并引入了新功能。2.现代框架如Laravel、Symfony和CodeIgniter简化开发,提高代码质量。3.性能优化和最佳实践进一步提升应用效率。

PHPhassignificantlyimpactedwebdevelopmentandextendsbeyondit.1)ItpowersmajorplatformslikeWordPressandexcelsindatabaseinteractions.2)PHP'sadaptabilityallowsittoscaleforlargeapplicationsusingframeworkslikeLaravel.3)Beyondweb,PHPisusedincommand-linescrip

PHP类型提示提升代码质量和可读性。1)标量类型提示:自PHP7.0起,允许在函数参数中指定基本数据类型,如int、float等。2)返回类型提示:确保函数返回值类型的一致性。3)联合类型提示:自PHP8.0起,允许在函数参数或返回值中指定多个类型。4)可空类型提示:允许包含null值,处理可能返回空值的函数。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SecLists
SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

PhpStorm Mac 版本
最新(2018.2.1 )专业的PHP集成开发工具

Atom编辑器mac版下载
最流行的的开源编辑器

ZendStudio 13.5.1 Mac
功能强大的PHP集成开发环境