生成 CloudFront 签名 URL 时性能缓慢

2024-05-09

我正在按照此示例使用 PHP 在 CloudFront 上创建签名 URLhttp://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CreateURL_PHP.html http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CreateURL_PHP.html

我一切正常,并为 RTMP 发行版和 HTTP 发行版生成签名 URL。

然而,我注意到生成签名 URL 需要相当长的时间,我想知道在具有数千个请求的生产中使用时会产生什么影响。

我做了一些测试,看来花费很长时间是由于 php-openssl 函数造成的。

这是代码:

<?php

class Cloudfront {

    const KEYPAIRID = 'MYKEYPAIRID';
    const PVTKEYFILE = '/home/keys/myprivatekey.pem';

    public function rsa_sha1_sign($policy) {
        $signature = "";

        // load the private key
        $fp = fopen(self::PVTKEYFILE, "r");
        $priv_key = fread($fp, 8192);
        fclose($fp);
        $pkeyid = openssl_get_privatekey($priv_key);

        // compute signature
        openssl_sign($policy, $signature, $pkeyid);

        // free the key from memory
        openssl_free_key($pkeyid);

        return $signature;
    }

    public function simulated_rsa_sha1_sign($policy) {
        // create a simulated signature
        $signature = "©3•{š(|i~'{µÜr…6—\L¶…ÙiÃÔh@ç÷S„Aóö¯‡d‰‹{¦ºx­òrd)Xcª
            Áh‚°Bgþ èòëÿô Š#CßFe  ÓÒ>v1    R€¥#–þ*¸çGÀýƒ Ј¾F<t)eV7¿ø_ŒQÎiXXU s˜¦Ij:ý
            ÒR ‹ÚQ§ Çm8à  ºâ*+äÇjƒãýO  4 ~ Uöeóy˜¢93_0iy §âE– a÷f¥y¿ÈãÏ`‹ _ì`ß ½õ  ‹*
            ÁM‘çõD  jrüB •d˜¥  èp Òü¿Ö NŒ«éoI X  €v=RÌlŠ¤ /Á û9Yš¾î";

        // load the private key file although is not actually used
        $fp = fopen(self::PVTKEYFILE, "r");
        $priv_key = fread($fp, 8192);
        fclose($fp);

        return $signature;
    }

    public function url_safe_base64_encode($value) {
        $encoded = base64_encode($value);
        // replace unsafe characters +, = and / with the safe characters -, _ and ~
        return str_replace(
                array('+', '=', '/'), array('-', '_', '~'), $encoded);
    }

    public function create_stream_name($stream, $signature, $expires) {
        $result = $stream;
        // if the stream already contains query parameters, attach the new query parameters to the end
        // otherwise, add the query parameters
        $separator = strpos($stream, '?') == FALSE ? '?' : '&';
        $result .= $separator . "Expires=" . $expires . "&Key-Pair-Id=" . self::KEYPAIRID . "&Signature=" . $signature;
        // new lines would break us, so remove them
        return str_replace('\n', '', $result);
    }

    public function get_signed_stream_name($video_path, $expires) {
        // this policy is well known by CloudFront, but you still need to sign it, since it contains your parameters
        $canned_policy = '{"Statement":[{"Resource":"' . $video_path . '","Condition":{"DateLessThan":{"AWS:EpochTime":' . $expires . '}}}]}';
        // sign the original policy, not the encoded version
        $signature = $this->rsa_sha1_sign($canned_policy);
        // make the signature safe to be included in a url
        $encoded_signature = $this->url_safe_base64_encode($signature);

        // combine the above into a stream name
        $stream_name = $this->create_stream_name($video_path, $encoded_signature, $expires);

        return $stream_name;
    }

}

这与 CloudFront 文档中的示例基本相同。然后我创建了一个控制器,我调用 get_signed_stream_name() 来生成签名的 url。我决定做一个 while 循环来看看创建 500 个签名 URL 需要多长时间。

public function signedurl() {
        // Script start
        $start = microtime(true);

        $this->load->helper('cloudfront');
        $this->cloudfront = new Cloudfront();

        $i = 1;
        while ($i <= 500) {
            $expires = time() + rand(300, 900);
            $http_video_path = 'http://mydistribution.cloudfront.net/myvideo.mp4';
            $signed_http_url = $this->cloudfront->get_signed_stream_name($http_video_path, $expires);

            echo '<strong>HTTP Signed URL:</strong> <br />' . $signed_http_url;
            echo '<br /><br />';

            $i++;
        }

        // Script end
        $time_taken = microtime(true) - $start;
        echo $time_taken;
    }

在我的本地计算机上,在 while 循环中生成 500 个签名 URL 大约需要 11 秒。然后我决定改变一下:

$signature = $this->rsa_sha1_sign($canned_policy);

to

$signature = $this->simulated_rsa_sha1_sign($canned_policy);

要查看除了调用 php-openssl 函数 openssl_get_privatekey()、openssl_sign()、openssl_free_key() 之外的所有内容都运行时会发生什么。

我使用 500 个 while 循环运行相同的脚本,花费了 0.090 秒。所以基本上 php-openssl 函数会使脚本变慢很多。这是我应该担心的事情吗?这是正常的,因为我生成这些签名的网址并且需要相当大的处理能力?

我做了几次尝试,这里是每次尝试 3 次所花费的样本时间。

Real code using OpenSSL functions generating 500 signed url calls:
11.135037899
11.6025328636
11.0253090858

500 URLs simulated without using the OpenSSL functions:
0.0828909873962
0.0903220176697
0.0916609764099

另外,我想知道如何创建适用于发行版中任何文件的签名。我可以使用通配符生成可用于该文件夹或发行版下的所有文件的签名。我在某个地方读到这是可能的,但不确定如何使用上面的这些示例。也许如果我可以为每个请求而不是为请求中返回的每个文件创建单个签名,那么强度会降低。

Thanks!


我观察到 Boto(AWS 的 Python SDK)也存在同样的性能问题,它使用rsa计算签名的模块。我认为问题只是归结为 RSA 计算在这种情况下很慢。我认为/希望解决方案在于调整处理私人内容的设置或工作流程。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

生成 CloudFront 签名 URL 时性能缓慢 的相关文章

随机推荐

  • 斯坦福自然语言处理:如何对单个单词进行词形还原?

    我知道如何注释一个句子并获取每个单词的引理 但如果我只想对一个单词进行词形化 我不知道该怎么做single单词 我试过 Annotation tokenAnnotation new Annotation wedding List
  • Javascript Firefox - 如果 @import 存在于样式表中,则无法查询 cssRules - bug 或预期行为?

    如果 import 存在于 css 样式表中 我无法查询 cssRules 是否符合网络标准 或者知道 Firefox 的限制 注意 我正在从同一域导入 css 文件 var style rules document styleSheets
  • Beaglebone Black 的 U-boot 无法构建 - 目标 CPU 不支持 THUMB 指令

    我正在尝试按照 Chris Simmonds 的 掌握嵌入式 Linux 编程 中的说明为 Beagle Bone Black 构建 u boot 我已经构建了交叉工具链 现在正在尝试使用该工具链构建 Das U boot 但由于不支持 T
  • Connect-AzAccount 无提示

    我正在尝试使用以下方式登录 Azure 门户 Connect AzAccount 此代码要求我输入我不想要的提示 我们可以使用一些简单的配置脚本自动登录吗 正如Joy所说 您可以通过凭据使用用户帐户登录 但不会出现任何提示 请确保您的帐户未
  • XAML 自定义文本框光标停留在输入开始处

    我正在致力于为 Windows 8 1 Universal UWP 的 XAML 应用程序创建自定义控件 并不断发现细微差别 我似乎找不到任何有关创建现有控件 如 TextBox 的自定义实现的优秀教程 因此我一直在浏览 Telerik 等
  • 流畅的 NHibernate 和 XML 列

    我正在从头开始构建一个新站点 并正在考虑使用 Fluent NHibernate 作为我的 ORM 我认为它可以轻松处理所有事情 可能除了我的 XML 列 我从来没有使用 NHibernate 构建过网站 尽管我使用过 Hibernate
  • 如何授权 Swagger 使用 MS Graph API

    我们正在为 MS Graph API 构建 Web API 包装器 我想使用 Swagger 来测试我的 API 但我无法正确配置 我不断收到错误请求 但没有其他线索 我无法在这台公司笔记本电脑上安装 Fiddler 或其他工具来帮助我进行
  • 在 Python 3 中动态导入模块的问题

    我遇到的情况是 在我的 Python 3 项目中 在运行时必须包含某些模块 我在用着importlib import module为了这 第二次更新 我确实找到了一种方法来做一些接近我想要的事情 一些额外的代码可能会使我的一些链接稍微偏离一
  • 如何使用 java/vb 脚本调用自定义 ActiveX dll 中的方法

    我使用 VB6 创建了一个 ActiveX dll 并使用打包和部署向导将其打包 生成了一个 cab 文件和一个演示 HTML 页面 此 ActiveX dll 包含一个 simgle 方法 该方法返回字符串且不接受任何参数 我遇到的麻烦是
  • PAM 在 C 中验证用户

    好吧 所以我是一个非常糟糕的编码员 我想知道 如标题所示 如何使用 C 语言通过 PAM 验证 Linux 用户 我唯一真正理解的是包括pam appl h and pam misc h我需要放置的头文件pam start and pam
  • 如何使用 Spring Security 跨多个基于 JVM 的应用程序实现单点登录

    我目前正在尝试跨多个基于 JVM Grails Servlet 的 Web 应用程序实现单点登录解决方案 这些应用程序目前都部署在同一个 servlet 容器 当前是 Tomcat 但不想将我的解决方案仅限于 Tomcat 中 所有 Web
  • 使用 Jest 和 Testbed 测试 Angular 9 服务

    在我的 Angular 9 项目中我添加了jest并删除Jasmine and Karma 我正在测试一项名为CorrectionService依赖于一个名为的服务RemoteService 我想监视RemoteService查看是否调用了
  • C# 中将一个字符串拆分为另一个字符串

    我一直在使用Split 分割字符串的方法 但这似乎仅在您按字符分割字符串时才有效 有没有办法分割一个string 另一个字符串是按参数分割的 我尝试将拆分器转换为字符数组 但没有成功 换句话说 我想分割string THExxQUICKxx
  • 如何使用 facebook API 在 javascript 中获取好友列表

    我不熟悉使用 Facebook Javascript SDK 我的故事是当我访问网站时它会在网页上显示我所有的朋友 照片和姓名 我注册了 Facebook API 和 App ID 我把网站网址设置为http 本地主机 81 http lo
  • 有条件填写 pandas 数据框

    我有一个数据框df列中包含浮点值A 我想添加另一列B这样 B 0 A 0 for i gt 0 B i if np isnan A i then A i else Step3 B i if abs B i 1 A i B i 1 lt 0
  • 将 PHP 变量保存到文本文件

    我想知道如何将 PHP 变量保存到 txt 文件 然后 再次检索它们 Example 有一个输入框 提交后写的东西 输入框将被保存到文本文件中 稍后需要结果 作为变量带回 假设变量是 text I 需要将其保存到文本文件并能够将其检索回来
  • 如何使用 Google Apps 脚本编辑现有的 Google 表单项(问题)

    我有一个谷歌脚本来构建谷歌表单 该脚本使用包含问题和相应选项的电子表格填写表单 表格中显示的问题需要定期更新 我希望通过更改电子表格中的问题来更新表单中的问题 如下所示 I use onOpen 对于脚本 以便每次访问表单时 脚本都会重建最
  • 获取单词中重复次数最多的字母的数量

    我正在尝试计算单词中重复次数最多的字母的数量 function GreatestCount str var count for var i 0 i
  • 如何在 Java 中安装附加包?

    我对 Java 很陌生 我想使用名为的包中的一些功能daj 教程代码有以下几行 import daj import java util import java lang Math import Msg 但第一行和第四行会产生红色下划线 导致
  • 生成 CloudFront 签名 URL 时性能缓慢

    我正在按照此示例使用 PHP 在 CloudFront 上创建签名 URLhttp docs aws amazon com AmazonCloudFront latest DeveloperGuide CreateURL PHP html