首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CRX_ZREO_SIGNTURE_LENGTH文件中的.crx失败

CRX_ZREO_SIGNTURE_LENGTH文件中的.crx失败
EN

Stack Overflow用户
提问于 2012-09-29 14:57:18
回答 1查看 307关注 0票数 0

我找到了这个帖子用PHP创建文件来创建一个.crx文件vith我的ZIP存档。但是当我尝试运行它时,我得到了$signtrue =0的长度,并且没有在“查找”和“有效”中计算出why...my .pem文件,也没有计算出我的.pub密钥文件,但是它仍然返回给我一个零长度的符号.

代码语言:javascript
复制
$fp = fopen("/public_html/apps/chrome/nsii.pem", "r");
$priv_key = fread($fp, filesize($fp));
fclose($fp);

$pkeyid = openssl_get_privatekey($priv_key);
openssl_sign(file_get_contents("$name.zip"), $signature, $pkeyid, 'sha1');
openssl_free_key($pk);

# decode the public key

$key = base64_decode(file_get_contents('extension_public_key.pub'));

$fh = fopen("$name.crx", 'wb');
fwrite($fh, 'Cr24');             // extension file magic number
fwrite($fh, pack('V', 2));       // crx format version
fwrite($fh, pack('V', strlen($key)));            // public key length
fwrite($fh, pack('V', strlen($signature)));      // signature length
fwrite($fh, $key);               // public key
fwrite($fh, $signature);         // signature
fwrite($fh, file_get_contents("$name.zip")); // package contents, zipped
fclose($fh);

更新:

原始代码如下:

代码语言:javascript
复制
<?php
# make a SHA1 signature using our private key
$pk = openssl_pkey_get_private(file_get_contents('/public_html/apps/chrome/nsii.pem'));
openssl_sign(file_get_contents('/public_html/apps/chrome/extGoogle.zip'), $signature, $pk, 'sha1');
openssl_free_key($pk);

# decode the public key
$key = base64_decode(file_get_contents('/public_html/apps/chrome/extension_public_key.pub'));

# .crx package format:
#
#   magic number               char(4)
#   crx format ver             byte(4)
#   pub key lenth              byte(4)
#   signature length           byte(4)
#   public key                 string
#   signature                  string
#   package contents, zipped   string
#
# see http://code.google.com/chrome/extensions/crx.html
#
$fh = fopen('extension.crx', 'wb');
fwrite($fh, 'Cr24');                             // extension file magic number
fwrite($fh, pack('V', 2));                       // crx format version
fwrite($fh, pack('V', strlen($key)));            // public key length
fwrite($fh, pack('V', strlen($signature)));      // signature length
fwrite($fh, $key);                               // public key
fwrite($fh, $signature);                         // signature
fwrite($fh, file_get_contents('/public_html/apps/chrome/extGoogle.zip')); // package contents, zipped
fclose($fh);

well...the的问题是为什么?.如果我用CLI编译它的话.

EN

回答 1

Stack Overflow用户

发布于 2012-09-29 22:01:59

你的问题是-没有留下任何迹象,究竟出了什么问题。

但是,我可以看到没有太多的错误检查。我建议--这对于编写得很好的代码来说是很常见的--您应该首先为返回值添加一些测试。此外,您可能需要启用错误报告并跟踪错误日志以查看其中的一些问题。

  • 关于错误处理和日志记录的章节

让我们回顾一下代码并添加注释。它不是完全的,只是一些指点。从上面的这三行开始:

代码语言:javascript
复制
$fp = fopen("/public_html/apps/chrome/nsii.pem", "r");
$priv_key = fread($fp, filesize($fp));
fclose($fp);

您已经知道(至少以后使用它),有一个方便的函数file_get_contents。它可以替换这三行代码,我添加了更多的行来使代码更清晰:

代码语言:javascript
复制
$privateKeyPemFile = "/public_html/apps/chrome/nsii.pem";
$privateKey = file_get_contents($privateKeyPemFile);
if (false === $privateKey) {
    throw new UnexpectedValueException(
        sprintf("Unable to read private key file %s", $privateKeyPemFile)
    );
}

除了使用file_get_contents之外,这实际上是验证打开文件是否成功工作。如果不是,则抛出一个UnexpectedValueException,其中包含一条告诉发生了什么的错误消息。异常的名称并不重要,您可以先抛出一个Exception,然后继续。

在这里抛出一个异常会告诉消息,以防失败。

如您所见,您需要验证函数的返回值并检查错误条件。请参阅您在手册中使用的PHP函数,并查看哪些返回值已记录在案,以及它们的含义。通常会出现错误情况,就像在file_get_contents中一样。

然后,您将特别关注零长度$signature。让我们看看,对于每个函数,如果我们可以检查返回值并获得一些错误信息:

代码语言:javascript
复制
$keyResource = openssl_pkey_get_private($privateKey);

openssl_get_privatekey实际上是openssl_pkey_get_private的别名,所以这里已经做了修改。另外,我重新命名了变量名,所以更多的是,我们有足够的空间,不需要复杂的缩写。

同样,这里有一个返回值,如果发生错误,它是false。在非错误条件下,它是一个关键资源,因此我相应地命名了返回值.让我们再次添加错误检查:

代码语言:javascript
复制
if (false === $keyResource) {
    throw new UnexpectedValueException("Unable to parse and prepare private key");
}

因此,直到下一行,首先不变:

代码语言:javascript
复制
openssl_sign(file_get_contents("$name.zip"), $signature, $pkeyid, 'sha1');

显然,对于zip文件的file_get_contents没有错误检查。相反,我们需要更多的代码来获得这个安全:

代码语言:javascript
复制
$zipFile     = "$name.zip";
$zipContents = file_get_contents($zipFile);
if (false === $zipContents) { 
    throw new ... 
}

由于这只是为了加载数据,所以需要采用openssl_sign调用:

代码语言:javascript
复制
$signatureAlgorithm = OPENSSL_ALGO_SHA1;
$result = openssl_sign($zipContents, $signature, $keyResource, $signatureAlgorithm);
if (!$result) {
    throw new ...
}

可能第一个不同之处是,您使用了字符串'SHA1',而手册告诉我使用的是常量。也许它具有相同的值,我不能告诉您,我在这里使用了文档常量(可能不是文档总是正确的,但是如果您不知道发生了什么,我首先建议遵循文档,然后再看)。

同样,正在检查函数的返回值以确定错误条件。假设您的代码可能在该函数中失败,我们只知道它失败了,而不是错误的地方。

PHP手册显示,有一个名为openssl_error_string的函数可以返回错误字符串(Peu)。因为它一个接一个地返回,所以需要循环以获得所有(最近的第一个),这可以用一个普通的循环播放来完成。

代码语言:javascript
复制
for ($buffer = ''; $string = openssl_error_string(); $buffer .= $string, "\n");

所以我们可以把它加到例外中。也许这也是有用的,让它在某种功能中,做你需要的。

代码语言:javascript
复制
if (!$result) {
    $buffer = sprintf(
        "Failed to sign zip contents (%d); Openssl error(s):\n", strlen($zipContents)
    );
    for (; $string = openssl_error_string(); $buffer .= $string, "\n");
    throw new UnexpectedValueException($buffer);
}

因此,您的代码是一个很好的例子,可以在哪里检查错误条件,并说明不同的函数/库有不同的方法来表示故障,以及如何获取有关的信息。

如果您以一种安全的方式编写代码,它将进行所有的前后条件检查,这意味着您不仅要检查返回值,而且还要在使用它们之前检查它们。一个例子是the文件的文件名。在打开该文件之前,先检查它是否存在并具有可读性:

代码语言:javascript
复制
$zipFile = "$name.zip";
if (!is_readable($zipFile)) {
    throw new Exception(sprintf("Zipfile is not readable %s", $zipFile));
}
$zipContents = file_get_contents($zipFile);
...

这只是一个为失败设计的例子(在这种情况下,它可能有点过头了,因为file_get_contents也会告诉我们,我们无法读取文件以防万一,但是有时这些预条件检查更有价值。

到目前为止,对代码进行检查,将参数变量移到顶部:

代码语言:javascript
复制
$privateKeyPemFile  = "/public_html/apps/chrome/nsii.pem";
$zipFile            = "$name.zip";
$signatureAlgorithm = OPENSSL_ALGO_SHA1;

$privateKey = file_get_contents($privateKeyPemFile);
if (false === $privateKey) {
    throw new UnexpectedValueException(
        sprintf("Unable to read private key file %s", $privateKeyPemFile)
    );
}

$keyResource = openssl_pkey_get_private($privateKey);
if (false === $keyResource) {
    $buffer = sprintf(
        "Unable to parse and prepare private key (%d) %s; Openssl error(s):\n"
        , strlen($privateKey), $privateKeyPemFile
    );
    for (; $string = openssl_error_string(); $buffer .= $string, "\n") ;
    throw new UnexpectedValueException($buffer);
}

if (!is_readable($zipFile)) {
    throw new Exception(sprintf("Zipfile is not readable %s", $zipFile));
}
$zipContents = file_get_contents($zipFile);
if (false === $zipContents) {
    throw new UnexpectedValueException(
        sprintf("Failed to open zipfile %s", $zipFile)
    );
}

$result = openssl_sign($zipContents, $signature, $keyResource, $signatureAlgorithm);
if (!$result) {
    $buffer = sprintf(
        "Failed to sign zip contents (%d); Openssl error(s):\n"
        , strlen($zipContents)
    );
    for (; $string = openssl_error_string(); $buffer .= $string, "\n") ;
    throw new UnexpectedValueException($buffer);
}

将变量放在顶部,可以让您提前检查输入参数,并为您提供更好的概述。

在处理过程中检查返回值可以让您尽早发现问题。

读取openssll错误将为您提供解决问题的有用信息。

您可以在PHP手册中找到这方面的几乎任何信息。这个答案可能解决不了您的具体问题,但应该为您提供所需的工具,以便更好地解决问题本身和代码可能存在的未来问题。

它只需要花费一些代码行,但您的代码将工作得更好。想象一下,您将脚本复制到一个新的服务器上,那里的情况可能不同,而且您不想盲目地飞。

调试愉快。正如您所看到的,我只介绍了代码的前半部分,您应该知道我没有运行您的代码。因此,这个例子是在最好的意图下完成的,但是不能保证它对您的场景立即起作用。但我认为我想展示的东西是显而易见的。如果您对代码的其余部分应用了类似的检查,那么您应该能够了解到底出了什么问题,这是解决方案的一半。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12653773

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档