互联网古早时期,有很多大型网站都被爆库过,包括腾讯网(qq的爸爸),网易,csdn等等,当时这些网站的密码甚至是明文保存,后续才有了加盐(salt)后,取MD5值这样的二次加密的方式。同时,也出现了类似谷歌二次验证
「Google Authenticator」这样的二次验证方式,类似的还有微软Authenticator
APP、腾讯的QQ安全中心(计算动态码使用自己的算法),能访问到我写的这篇文章的您,一定是了解这个东西的。今天就重点讲一讲怎么将谷歌二次验证功能迁移到QQ
robot里面,不安装APP来实现相应的功能。
准备工作
- qq机器人🤖️程序,推荐使用 go-cqhttp
- google authenticator/谷歌二次验证算法类,PHPGangsta/GoogleAuthenticator
QQ机器人实现原理讲解
流程示意图
用户使用路径
- 用户访问网站/APP时,需要使用二次验证结果
- 给QQ机器人(电报机器人/微信机器人等等)发送触发关键词,如:ga xx_site
- qqrobot识别到需要使用谷歌二次验证码了,读取本地或者数据库内xx_site初始的动态密钥
- 使用php GoogleAuthenticator class计算结果
- 将计算的动态ga二次验证码以qq消息的方式发送给用户
- 用户使用ga code,访问网站或者APP
实现ga二次验证核心代码
实现功能清单
- 添加谷歌二次验证码
- 删除ga二次验证
- 获取Google Authenticator / 微软 Authenticator 等APP,扫码添加二次验证的二维码功能「恢复使用验证APP时需要」
- ga code计算
// print_r($array);
$s = str_ireplace(array('ga',' '), '', $array["message"]);
$arr = explode(",", $s);
$content = "";
$imagepath = '';
$type = 0;
// 加入验证码有效时间
$sec = date('s');
$sec = $sec > 30 ? 60 - $sec : 30 - $sec;
if($sec == 0){
$sec = 30;
}
//添加key
if(count($arr) == 3){
if($arr[0] == "add"){
if(file_put_contents("config/ga/" . $arr[1] . ".json", json_encode(array("account" => $arr[1], "key" => $arr[2])))){
$config = json_decode(file_get_contents("config/ga/" . $arr[1] . ".json"), true);
$ga = new PHPGangsta_GoogleAuthenticator();
//要计算的key
if(isset($config["key"]) && isset($config["account"])){
$secret = $config["key"];
$oneCode = $ga->getCode($secret);
$content = "添加成功,CODE:" . $oneCode;
$type = 1;
}
}
}
}
if(count($arr) == 2){
//删除key
if($arr[0] == "del"){
if(is_file("config/ga/" . $arr[1] . ".json")){
if(unlink("config/ga/" . $arr[1] . ".json")){
$content = "删除成功";
$type = 1;
}
}
}
//生成QR
if($arr[0] == "qr"){
$config = json_decode(file_get_contents("config/ga/" . $arr[1] . ".json"), true);
//要计算的key
if(isset($config["key"]) && isset($config["account"])){
// echo "Key: ".$secret."\n\n";
$url = 'otpauth://totp/' . $config["account"] . '?secret=' . $config["key"];
$content = "[CQ:image,file=https://xiao.nu/apis/qr/?size=24&level=L&t=" . time() . "&data=" . urlencode($url) . ",type=show,id=40000]";
$type = 2;
}
}
}
//发送code
if(is_file("config/ga/" . $s . ".json")){
$config = json_decode(file_get_contents("config/ga/" . $s . ".json"), true);
$ga = new PHPGangsta_GoogleAuthenticator();
//要计算的key
if(isset($config["key"]) && isset($config["account"])){
$secret = $config["key"];
// echo "Key: ".$secret."\n\n";
$oneCode = $ga->getCode($secret); //服务端计算"一次性验证码"
$content = $oneCode;
$type = 1;
}
}
$user_id = $array["user_id"];
if($type > 0){
$wdata = array(
"user_id" => $user_id,
"message" => $content . "-" . $sec,
"group_id" => '',
'auto_escape' => "false"
);
// var_dump($wdata);
// die();
// 使用 cq-http 接口发送文本消息
postData("http://localhost:" . $Port . "/SendPrivatecontent", $wdata);
}else{
die();
}
}
以上为通篇的内容,如果自行尝试的时候有什么问题的话,可以在文末留言。