飞信短信发送的PHP类(散分)解决方法
程序员文章站
2022-06-09 19:37:11
...
飞信短信发送的PHP类(散分)
飞信发送API网上有很多,但没有多少是我自己满意的。很多网站提供基于Web的API调用方式向用户提供服务,但是作为使用者我心里还是没底。我总是担心自己的密码会被某些人记录,一直想写一个自己用的PHP版本飞信发送程序。
因为本人没有任何逆向基础,同时飞信版本变化不同。从nathan在百度上发布《飞信协议分析》到现在也有3年了,且当时分析的是飞信2006版本。这中间变化太多,也使得我在写PHP版本飞信发送程序是走了很多弯路。
我曾经拜读过superli_198的《让 PHP 程序利用飞信(Fetion)发免费短信》,但是该版本使用的通讯方式目前已经不被飞信支持,且superli_198也没有做新的更新。我也下载过c.young[@]xicabin.com的Openfetion,但是该版本存在明显bug,现在也不能正常使用。无奈只能硬着头皮修改一个C# 版本的飞信发送程序。
在移植C#版本的飞信发送程序到PHP过程中,我遇到了一个关于MD5加密相关的问题,困了很多天。最后在CSDN论坛ycTIN的帮助下,问题得以解决。非常感谢ycTIN。 以下是我完成的PHP版飞信短信发送类,截止到2010年2月17日下午4点该程序一直能正常工作。技术上没有什么难度,发在这里和大家交流。
飞信发送API网上有很多,但没有多少是我自己满意的。很多网站提供基于Web的API调用方式向用户提供服务,但是作为使用者我心里还是没底。我总是担心自己的密码会被某些人记录,一直想写一个自己用的PHP版本飞信发送程序。
因为本人没有任何逆向基础,同时飞信版本变化不同。从nathan在百度上发布《飞信协议分析》到现在也有3年了,且当时分析的是飞信2006版本。这中间变化太多,也使得我在写PHP版本飞信发送程序是走了很多弯路。
我曾经拜读过superli_198的《让 PHP 程序利用飞信(Fetion)发免费短信》,但是该版本使用的通讯方式目前已经不被飞信支持,且superli_198也没有做新的更新。我也下载过c.young[@]xicabin.com的Openfetion,但是该版本存在明显bug,现在也不能正常使用。无奈只能硬着头皮修改一个C# 版本的飞信发送程序。
在移植C#版本的飞信发送程序到PHP过程中,我遇到了一个关于MD5加密相关的问题,困了很多天。最后在CSDN论坛ycTIN的帮助下,问题得以解决。非常感谢ycTIN。 以下是我完成的PHP版飞信短信发送类,截止到2010年2月17日下午4点该程序一直能正常工作。技术上没有什么难度,发在这里和大家交流。
- PHP code
"; /** *使用手机号码和密码向服务器获取对应的飞信号码信息 **/ private $REQUEST_SSI_SIGN = "mobileno=%s&pwd=%s" ; /** *使用飞信号码向SIPC服务器注册,获取临时变量NONCE和SSIC的值 **/ private $REQUEST_SIPC_SIGN_NONCE = "R %s SIP-C/2.0\r\nF: %s\r\nI: 1\r\nQ: 1 R\r\nL: %d\r\n\r\n%s" ; private $REQUEST_SIPC_SIGN_NONCE_BODY = " "; /** *使用飞信号码和加密的密码登录飞信SIPC服务器 **/ private $REQUEST_SIPC_LOGIN = "R %s SIP-C/2.0\r\nF: %s\r\nI: 1\r\nQ: 2 R\r\nA: Digest response=\"%s\",cnonce=\"%s\"\r\nL: %d\r\n\r\n%s"; private $REQUEST_SIPC_LOGIN_BODY = " "; private $REQUEST_SIPC_SENDSMS = "M %s SIP-C/2.0\r\nF: %s\r\nI: 2\r\nQ: 1 M\r\nT: tel:%s\r\nN: SendSMS\r\nL: %d\r\n\r\n%s"; private $REQUEST_SIPC_LOGOUT = "R %s SIP-C/2.0\r\nF: %s\r\nI: 1 \r\nQ: 3 R\r\nX: 0\r\n\r\n"; /** *@param $sender 短信发送者手机号 *@param $passwd 短信发送者密码 *@param $receiver 短信接收者手机号 *@param $msg 短信内容 **/ public function __construct($sender, $passwd, $receiver, $msg){ $this->mobile_no = $sender ; $this->fetion_pwd = $passwd; $this->SMS_RECEIVER = $receiver; $this->SMS_TEXT = $msg; $this->cookie_file = $this->mobile_no . $this->cookie_file ; file_put_contents($this->cookie_file, '') ; $this->FetionGetConfig(); // 从导航网站443端口获取登录信息 $this->FetionSocektInit(); // 初始化到SIPC的8080端口socket连接 $this->FetionGetSIPCNonce(); // 向服务器注册飞信号,获取关键变量值 if($this->FetionLogin()){ // 发送登录认证命令 $this->FetionSendSMS(); // 发送短信发送命令 $this->FetionLogout(); } } /** *从导航地址获取配置信息 **/ private function FetionGetConfig(){ $this->REQUEST_CONFIG = sprintf($this->REQUEST_CONFIG, $this->mobile_no); $this->curl = curl_init(); curl_setopt($this->curl, CURLOPT_URL, $this->url_nav); curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($this->curl, CURLOPT_COOKIEJAR, $this->cookie_file); curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, 1); curl_setopt($this->curl, CURLOPT_POST, 1); curl_setopt($this->curl, CURLOPT_POSTFIELDS, $this->REQUEST_CONFIG); //curl_setopt($this->curl, CURLOPT_PROXY, $this->proxy_http); // 设置代理服务器 $xml_config = curl_exec($this->curl); // 以下是从导航页面返回的XML里取相关信息 file_put_contents("test3.xml", $xml_config) ; $xmlDom = new DOMDocument() ; $xmlDom->loadXML($xml_config); $fetion_server = $xmlDom->getElementsByTagName('servers'); $fetion_server->item(0)->getElementsByTagName('sipc-proxy')->item(0)->nodeValue; $this->SSI_PROXY_SIGN_IN = $fetion_server->item(0)->getElementsByTagName('ssi-app-sign-in')->item(0)->nodeValue; $this->SSI_PROXY_SIGH_OUT = $fetion_server->item(0)->getElementsByTagName('ssi-app-sign-out')->item(0)->nodeValue; $this->SSI_PROXY_SIGN_IN; // 以下获取手机号对应的飞信号 sprintf($this->REQUEST_SSI_SIGN, $this->mobile_no, $this->fetion_pwd) ; curl_setopt($this->curl, CURLOPT_URL, $this->SSI_PROXY_SIGN_IN); curl_setopt($this->curl, CURLOPT_POSTFIELDS, sprintf($this->REQUEST_SSI_SIGN, $this->mobile_no, $this->fetion_pwd)); $Result = curl_exec($this->curl); curl_close($this->curl); file_put_contents("test4.xml", $Result) ; $xmlDom->loadXML($Result); $uri = $xmlDom->getElementsByTagName("user")->item(0)->getAttribute("uri"); //"sip:738713940@fetion.com.cn;p=5914" if(preg_match('/^sip:(\d+)@(\S+);.*$/', $uri, $matches)){ $this->fetion_no = $matches[1] ; $this->domain_fetion = $matches[2] ; } } /** *初始化Fetion通讯Socket **/ private function FetionSocektInit(){ $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); list($ip_fetion, $port_fetion) = split(':', $this->SIPC_PROXY) ; // "221.176.31.4:8080" socket_connect($this->socket, $ip_fetion, $port_fetion) ; } /** *注册飞信号码并获取临时变量NONCE和SSIC **/ private function FetionGetSIPCNonce(){ $REQUEST_SIPC_SIGN_NONCE = sprintf($this->REQUEST_SIPC_SIGN_NONCE, $this->domain_fetion, $this->fetion_no, strlen($this->REQUEST_SIPC_SIGN_NONCE_BODY), $this->REQUEST_SIPC_SIGN_NONCE_BODY) ; $sock_data = socket_write($this->socket, $REQUEST_SIPC_SIGN_NONCE); $buf = '' ; if (false == ($buf = socket_read($this->socket, 1000))) { echo "Line:" . __LINE__ . "socket_read() failed; reason: " . socket_strerror(socket_last_error($this->socket)) . "\n"; } $regex_ssic = '/.*nonce=\"(\\w+)\".*/s' ; if(!preg_match($regex_ssic, $buf, $matches)){ echo "Fetion Error: No nonce found in socket\n"; } $this->NONCE = strtoupper(trim($matches[1])); $regex_ssic = '/ssic\s+(.*)/s'; if (!preg_match($regex_ssic, file_get_contents($this->cookie_file), $matches)) { echo "Fetion Error: No ssic found in cookie\n"; } $this->SSIC = trim($matches[1]); } 相关文章
相关视频