使用 PHP 从 Microsoft Teams 自定义机器人验证 HMAC

2024-02-11

我正在尝试使用 PHP 验证 Microsoft Teams 自定义机器人,遵循 Microsoft指示 https://learn.microsoft.com/en-us/microsoftteams/platform/concepts/custom-bot并阅读 C# 示例代码。

微软说明步骤:
1. 根据消息的请求正文生成 hmac。大多数平台上都有标准库。 Microsoft Teams 使用标准 SHA256 HMAC 加密。您需要将正文转换为字节 UTF8 格式的数组。
2. 要计算哈希值,请提供共享密钥的字节数组。
3. 使用 UTF8 编码将哈希值转换为字符串。
4. 将生成的哈希的字符串值与 HTTP 请求中提供的值进行比较。

我写了一个小的 php 脚本来在本地测试这个:

        <?php
        //Function to generate C# byte[] equivalent
        function unpak_str($val){
            $b = unpack('C*', $val);
            foreach ($b as $key => $value)
                $byte_a .= $value;

           return $byte_a;
          }

        //multi test outputs
        function hasher($values=[], &$output){
            //my secret share
            $secret="ejWiKHgsKY1ZfpJwJ+wIiN4+bgsFad/lkpu9/MWNXgM=";
            //diferent test
            $secret_64=base64_decode($secret);
            $secret_b=unpak_str($secret);
            $secret_b_64=unpak_str(base64_decode($secret));

            foreach($values as $msg){
                $hs = hash_hmac("sha256",$msg,$secret, true);
                $hs_64 = hash_hmac("sha256",$msg,$secret_64, true);
                $hs_b = hash_hmac("sha256",$msg,$secret_b, true);
                $hs_b_64 = hash_hmac("sha256",$msg,$secret_b_64, true);

                $output.=base64_encode($hs)." <BR>";
                $output.=base64_encode($hs_64)." <BR>";
                $output.=base64_encode($hs_b)." <BR>";
                $output.=base64_encode($hs_b_64)." <BR>";
             }
          }

    //Get data
    $data=file_get_contents('php://input');

    //real data request content for test
    $data ='{type":"message","id":"1512376018086","timestamp":"2017-12-04T08:26:58.237Z","localTimestamp":"2017-12-04T09:26:58.237+01:00","serviceUrl":"https://smba.trafficmanager.net/emea-client-ss.msg/","channelId":"msteams","from":{"id":"29:1aq6GCrC6lM9dv3YkAYi1gxTPiLnojGFgVr0_Th-2x6DhqmHAOhFwQHFzSyDy5RruXY4_FZjJebKHU7bpxfHpXA","name":"ROBERTO ALONSO FERNANDEZ","aadObjectId":"1e0dc7a0-9d5e-488b-bcf2-7e39c84076b8"},"conversation":{"isGroup":true,"id":"19:[email protected] /cdn-cgi/l/email-protection;messageid=1512376018086","name":null},"recipient":null,"textFormat":"plain","attachmentLayout":null,"membersAdded":[],"membersRemoved":[],"topicName":null,"historyDisclosed":null,"locale":null,"text":"<at>PandoBot</at> fff","speak":null,"inputHint":null,"summary":null,"suggestedActions":null,"attachments":[{"contentType":"text/html","contentUrl":null,"content":"<div><span itemscope=\"\" itemtype=\"http://schema.skype.com/Mention\" itemid=\"0\">PandoBot</span> fff</div>","name":null,"thumbnailUrl":null}],"entities":[{"type":"clientInfo","locale":"es-ES","country":"ES","platform":"iOS"}],"channelData":{"teamsChannelId":"19:[email protected] /cdn-cgi/l/email-protection","teamsTeamId":"19:[email protected] /cdn-cgi/l/email-protection","channel":{"id":"19:[email protected] /cdn-cgi/l/email-protection"},"team":{"id":"19:[email protected] /cdn-cgi/l/email-protection"},"tenant":{"id":"9744600e-3e04-492e-baa1-25ec245c6f10"}},"action":null,"replyToId":null,"value":null,"name":null,"relatesTo":null,"code":null}';


    //generate HMAC hash with diferent $data formats
    $test = [$data, unpak_str($data), base64_encode($data), unpak_str(base64_encode($data))];
    hasher($test, $output);


    //microsoft provided HMAC
    $output.="<HR>EW2993goL1q7nGhytIb3jKmV6luXLz15Bq2aYwuCeiE="; 


    echo $output;
    /*
    Calculates: 
    0HsKoHza/QBvdz+nZw9tOti/eSWjyMMt/U77bfDqiE8=
    3jSq3I0HNQkjB9QfnnsxC1c3pF5PjqweHlSVcicrShY=
    bTQcGVTHX8/Gh4xovnN0WiJUiNaOQwvUZnwyFfiCaJE=
    qHBT2Y2ITyoxz2gmBbG8P1CrClvETus6dTffET3bAR8=
    8BcrXEQDDi77qgxCZLYyb/6ez8p9Qg2ZhTyZPWkdn/g=
    +8RSU5SSJKxqRLKkI+NkTE01xwu6PwPkKKMuvyyUvlo=
    PdL5ZpEwcN6Fe5kfX7zeAZLJvt0uLNTzu7lhuoOcr2o=
    s6M5pYruEgWeNMEOFfQRjVKQqtPBVaW3TJb2MzObF2c=
    xOTLhddbAwczQVneuTDQhPzmoIXGQljpf27c+hlhQII=
    aUMm5b2sKfmwGZOglfiu228fWqoLlwjc7z1QRdIbakE=
    5a7bAj9tzqhP9l85OvfVasURW0GSV5rykRutFFPO2fk=
    kwg6P2LoDL9rc3SSwJxQeoYJzZYlh+FHFefe38UokBM=
    eHeAzI7TV6vYDzxTxwyKWxMeVKFiFlIffWRiIMAk6fk=
    ZCyj2UppacQOTXogLPMFLDeMArQg03rhhlIwhynDvng=
    uQYK+7u9fppb62zXqtVYfkNK9wVawB3g+BlTyu4dc74=
    vjOFA3fqpwUx/VO9dQv3XviNhpjTNQsUwaJIwH4JjdY=
    ------------ MS PROVIDED HMAC ---------------
    EW2993goL1q7nGhytIb3jKmV6luXLz15Bq2aYwuCeiE=
     */

我的哈希匹配为零...


最后,经过多次尝试,这让我发疯,并决定启动一个具有新秘密的新机器人。现在工作正常。我是人类,而 MS Teams 不...我想这是我复制/粘贴的错,但这是一件非常奇怪的事情,另一方面旧机器人失败了很多次,没有响应,最新的没有

适用于 Microsoft Teams 自定义机器人的 PHP 中的完整示例验证 HMAC:

        <?php

        //The secret share with Microsoft Teams
        $secret="jond3021g9imMkrt8txF5AVPIwPFouNV/I72cQFii18=";

        //get headers
        $a = getallheaders();
        $provided_hmac=substr($a['Authorization'],5);

        //Get data from request
        $data=file_get_contents('php://input');

        //json decode into array
        $json=json_decode($data, true);

        //hashing
        $hash = hash_hmac("sha256",$data,base64_decode($secret), true);
        $calculated_hmac = base64_encode($hash);

        //start log var
        $log = "\n========".date("Y-m-d H:i:s")."========\n".$provided_hmac."\n".$calculated_hmac."\n";

        try{
            //compare hashs
            if(!hash_equals($provided_hmac,$calculated_hmac))
                throw new Exception("No hash matching");
            //response text
            $txt="Hi {$json["from"]["name"]} welcome to your custom bot";
            echo '{
                "type": "message",
                "text": "'.$txt.'"
                 }';
            $log .= "Sended: {$txt}";
        }catch (Exception $e){
            $log .= $e->getMessage();
        }
        //write log
        $fp = fopen("log.txt","a");
        fwrite($fp, $log . PHP_EOL);
        fclose($fp);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 PHP 从 Microsoft Teams 自定义机器人验证 HMAC 的相关文章

  • 精简 PHP 和 GET 参数

    我使用 Slim PHP 作为 RESTful API 的框架 如何在 Slim PHP 中从 URL 获取 GET 参数 例如 如果我想使用以下内容 http api example com dataset schools zip 999
  • PDO 库比本机 MySQL 函数更快吗?

    我已经阅读了几个与此相关的问题 但我担心它们可能已经过时 因为自这些问题得到解答以来 更新版本的 PDO 库已经发布 我编写了一个 MySQL 类 它构建查询并转义参数 然后根据查询返回结果 目前这个类正在使用内置的mysql函数 我很清楚
  • 通过 AJAX jquery 更改表格背景颜色?

    设想 当我的网页加载时 自动搜索单元格已由用户输入并且具有价值 如果已输入 表格背景颜色将为红色 否则为绿色 假设该表尚未输入 桌子背景绿色是这样的 和表的源代码 table width 1023 height 200 border 1 t
  • 在 PHP 中验证约 400MB 的大型 XML 文件

    我有一个很大的 XML 文件 大约 400MB 在开始处理之前我需要确保它的格式正确 我尝试的第一件事是类似于下面的内容 这很棒 因为我可以找出 XML 是否格式不正确以及 XML 的哪些部分 不好 doc simplexml load s
  • PHP 中的 SQL 语句与 phpmyadmin 中的 SQL 语句的行为不同

    I have form store sql INSERT INTO myodyssey myaccount id email username password VALUES NULL email unixmiah formtest woo
  • 如何在MySQL选择查询中编写正则表达式?

    我尝试过这个表达 b word w b i比较一个word对照其他单词列表来查找重复项 我用了preg math all 效果很好 我想做同样的事情 但这次检查从 mysql 数据库检索到的单词 这是我写的 SELECT FROM tabl
  • 用于添加和删除客户名称的 Web 表单出现问题

    我正在尝试创建一个 Web 表单 其中列出了所有客户 然后为您提供一个文本字段 旁边有一个按钮 您可以在其中添加客户 然后它应该显示客户列表 旁边有删除按钮 您可以单击该按钮从数据库中删除客户 我正在让它发挥作用 对于初学者来说 它会回显
  • 使用 LIKE 和撇号的 Mysql 查询问题

    所以我有一个有趣的问题 我从未遇到过 并且似乎找不到太多有关纠正该问题的信息 我有一个庞大的数据库 里面有大量的数据 相当于 10 年的数据 并试图对其进行搜索 现在搜索功能运行良好 但最近有人让我注意到一个 错误 如果你愿意的话 我尝试对
  • PHP中是否可以使用filter_var过滤带小数点的整数?

    我需要像这样过滤值100 50在 PHP 中使用filter var 现在我这样使用 filter var POST amount FILTER SANITIZE NUMBER INT 它给我的结果是10050 我怎么解决这个问题 提前致谢
  • 在 while 循环之外使用变量(作用域)

    关于 PHP 范围的小问题 我似乎无法在 while 循环之外调用变量 report 我尝试过各种事情 包括return 这不起作用 这里唯一起作用的两个函数是如果我echo变量 report在循环内 或者如果我print它 我不想这样做
  • PHP 计数器在 while 循环中递增

    我在一个 while 循环中增加计数器时遇到问题 基本上我只想在数据库中获取的两个图像链接之间交替 但我的计数器不会增加 我不确定为什么有人可以提供帮助 while row stmt gt fetch PDO FETCH ASSOC img
  • 从本地 html/javascript 网站插入 mySQL 数据库

    我正在尝试做什么 我的程序的目的是插入数据local HTML JS网站变成online 非本地 mySQL数据库 到目前为止我尝试过的 我试图用来实现此目的的原始方法是让我的本地网站使用 javascript 通过在线发布数据PHP文件
  • 一个表单包含两个提交按钮,每个按钮都有不同的操作

    我花了几个小时试图找到问题的解决方案 但似乎找不到正确的解决方案 提前感谢你的帮助 我有一个 html 表单
  • PHP 中的多行字符串文字

    考虑 xml l xml vv echo xml 这将回响vv 为什么以及如何为诸如此类的事情执行多行字符串文字简单XML https en wikipedia org wiki SimpleXML etc Well xml l vv Wo
  • 我可以在 Laravel 5.2 中创建一个继承自 User 的新类吗?

    我对 Laravel 还很陌生 使用的是迄今为止的最新版本 5 2 因此我遇到了以下困境 我知道 Laravel 附带了一个User开箱即用的类 但我想开发一个系统 在其中我可以有另外两种类型的用户 称为Researcher and Adm
  • 如何在 php 中为每个其他函数调用自动调用函数

    Class test function test1 echo inside test1 function test2 echo test2 function test3 echo test3 obj new test obj gt test
  • 使用mysql数据按高低价格排序

    这是我所拥有的以及我想做的 我的 MySql 数据库中有 12 个项目 4 个产品为 4 99 4 个产品为 3 99 4 个产品为 2 99 我意识到我可以像这样查询数据库 它会给我一个该价格的产品列表
  • 向 yahoo 和 hotmail 用户发送电子邮件?

    我正在使用 php 和 mysql 每次用户在我的网站上注册时 我都会使用 php mail 发送一封电子邮件进行身份验证 最近我发现 很多Yahoo和Hotmail用户还没有激活他们的帐户 假设 1000 个用户中 只有 200 个被激活
  • 为什么 strtotime('a') 返回时间?

    我正在 PHP 5 3 中循环遍历 CSV 文件并检查日期 我一直在使用 strtotime 它运行良好 除了我有一个包含 1 或 2 个字符代码的字段 任何单个字符代码上的 strtotime 似乎都像我要求 now 一样 但如果代码是
  • 如何从 php 中的 .doc 文件获取页面数,以下代码适用于 .docx 而不是 .doc

    此代码工作 docx 格式文档 但我需要 doc 格式文档计数 php 中的页数 function CountPagesDocx filename zip new ZipArchive if zip gt open filename tru

随机推荐