2012-09-29 2 views
0

이 게시물 Create Google Chrome Crx file with PHP 이 내 ZIP 파일로 .crx 파일을 만들었습니다. 하지만 실행하려고 할 때 나는 $ signtrue = 0 의 길이를 가지고 있는데 왜 ... 내 .pem 파일이 발견되었고 유효하며 내 .pub 키 파일도 있지만 그걸로 돌아 간다. 나 signture의 길이가 제로 ....CRX 파일의 CRX_ZREO_SIGNTURE_LENGTH 오류가

$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); 

UPDATE :

기존 이메일 코드는 다음과 같습니다 :

<?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); 

가 잘 작동하지 않는 것 같은데 ... 질문 이유는 무엇입니까? ... CLI를 사용하여 컴파일하면 문제없이 작동합니다 ...

+0

질문의 문구를보고 편집 도구를 편하게 사용하십시오. 코드가 제대로 보이지 않으므로 다른 사람들이 읽을 필요가 있기 때문에 코드를 들여 씁니다. 또한 스마일리에 대한 도움 요청은 무례한 것으로 간주됩니다. 왜냐하면 당신은 단지 코드를 던지고 "작동하지 않습니다". 그것은 일반적으로 여기에 도움을 얻을 정도로 충분하지 않습니다. – hakre

+0

고마워, 나는 내 게시물을 업데이 트했습니다 ... 그 과목에서 도움을 청하는 나의 처음 .btw, 이것은 아카이브 .zip 파일에서 .crx를 만들려고 할 때 일어납니다. 원본을 첨부했습니다. 원본 코드와의 링크. –

+0

원본 코드는 매우 안전하지 않습니다. 좀 더 견고하게 만들기 위해 추가 검사를 추가 할 수있는 방법을 알려줄 답변을 추가했습니다. – hakre

답변

2

그대로 표기가 남지 않습니다. 정확히이 잘못되었습니다.

그러나 오류 검사가 많지 않음을 알 수 있습니다. 필자는 - 잘 쓰여진 코드에서는 일반적으로 - 반환 값에 대한 테스트를 먼저 추가하는 것이 좋습니다. 또한 일부 문제점을 보려면 오류보고를 사용 가능하게하고 오류 로그를 추적해야 할 수도 있습니다.

는의 코드를 조금 검토하고 주석을 추가 할 수 있습니다. 그것은 단지 몇 가지 지침이 완전하지 않습니다. 상단에이 세 가지 라인으로 시작 :

$fp = fopen("/public_html/apps/chrome/nsii.pem", "r"); 
$priv_key = fread($fp, filesize($fp)); 
fclose($fp); 

이미 (적어도 나중에 사용) 알고, 편리한 기능 file_get_contents있다. file_get_contents를 사용하는

$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) 
    ); 
} 

다음이 실제로 파일을 여는 성공적으로 작동 않았 음을 확인한다 : 내가 좀 더 라인의 코드가 더 말할 수 있도록 추가, 그 세 줄을 교체 할 수 있습니다. 그렇지 않은 경우, UnexpectedValueException에 무슨 일이 일어 났는지 알려주는 오류 메시지가 표시됩니다. 예외의 이름은 그다지 중요하지 않습니다. 우선 Exception을 던져서 진행하십시오.

여기에 예외를 던지면 실제로 실패 할 경우를 대비하여 메시지가 표시됩니다.

위에서 알 수 있듯이 함수의 반환 값을 확인하고 오류 조건을 확인해야합니다. 매뉴얼에서 사용하는 PHP 함수를보고 어떤 반환 값이 문서화되어 있고 그 의미가 무엇인지 살펴보십시오. 종종 여기에 file_get_contents과 같은 오류가 있습니다.

그런 다음 길이가 0 인 $signature에 특히 관심이 있습니다. 우리는 약간의 오류 정보를 반환 값을 확인하고 얻을 수 있는지의 각 기능에 대해 살펴 보자

$keyResource = openssl_pkey_get_private($privateKey); 

openssl_get_privatekey 실제로 openssl_pkey_get_private의 별칭입니다, 그래서 이것은 이미 여기 변경됩니다. 또한 변수 이름의 이름을 바꾸어 말하면서 공간이 충분 해지며 복잡한 약어가 필요하지 않습니다.

여기에도 반환 값이 있으며 오류 발생시 false입니다. 오류가 아닌 조건에서는 키 자원이므로 그에 따라 반환 값의 이름을 지정했습니다. 의 다시 에러 체크를 추가하자

if (false === $keyResource) { 
    throw new UnexpectedValueException("Unable to parse and prepare private key"); 
} 

그래서 다음 줄, 첫번째 변화까지 :

openssl_sign(file_get_contents("$name.zip"), $signature, $pkeyid, 'sha1'); 

는 분명히 더 zip 파일의 file_get_contents에 대한 오류 점검이 없습니다. 대신, 우리는이 안전하도록 코드를 좀 더 라인이 필요합니다

$zipFile  = "$name.zip"; 
$zipContents = file_get_contents($zipFile); 
if (false === $zipContents) { 
    throw new ... 
} 

을 그리고 이것은 단지 데이터를로드하기위한이었다 같이 openssl_sign 호출을 채택 할 필요가 :

$signatureAlgorithm = OPENSSL_ALGO_SHA1; 
$result = openssl_sign($zipContents, $signature, $keyResource, $signatureAlgorithm); 
if (!$result) { 
    throw new ... 
} 

어쩌면 최초의 차이를 매뉴얼에서 상수가 사용되었다고 말하면서 'SHA1' 문자열을 사용했다는 것입니다. 어쩌면 그것이 동일한 가치를 지녔다고 말할 수는 없지만 여기서 문서화 된 상수를 사용했습니다. (문서가 항상 옳은 것은 아닐 수도 있습니다. 그러나 어떤 일이 일어나고 있는지 전혀 모른다면 먼저 docs 그리고 나서보십시오).

이 함수의 반환 값은 오류 조건을 다시 확인합니다. 해당 함수에서 코드가 실패했을 수 있다고 가정하면 실패했는지, 잘못되었는지 만 알 수 있습니다.

PHP 설명서에 오류 문자열을 반환 할 수있는 openssl_error_string이라는 함수가 있음을 보여줍니다 (peu-a-peu). 그것은 다른 후 하나를 반환하기 때문에, 당신은 온통 (첫번째 가장 최근에) 얻을 루프에 필요,이 공통 for loop 수행 할 수 있습니다 :

for ($buffer = ''; $string = openssl_error_string(); $buffer .= $string, "\n"); 

그래서 우리는 예외에 해당을 추가 할 수 있습니다. 아마도 이것을 일종의 기능 안에 넣고, 필요한 것을 해줄 수도 있습니다.

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); 
} 

그래서 코드는 오류 조건을 확인하고 다른 기능은/라이브러리가에 대한 정보를 얻을 수있는 고장 및 방법 신호를 여러 가지 방법이 있음을 보여 장소에 대한 완벽한 예입니다.

코드를 안전한 방법으로 작성하면 모든 사전 및 사후 조건 검사가 있으므로 결과 값을 확인할뿐만 아니라 값을 사용하기 전에 값을 확인한다는 의미입니다. 하나의 예제는 zip 파일의 파일 이름입니다. 파일을 열기 전에 존재하고 읽기 확인 :

$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이 정보를 통보 있기 때문에 맨 위에 조금있을 수 있습니다,이 경우에는 단지 예를 들어, 실패에 대한 설계는 (물론 우리가 할 수 즉 하지 그러나 때로는 그 사전 조건이 더 가치있는 검사, 경우에 파일을 읽을

코드를 지금까지 한 번에 검토를 위해, 정상에 매개 변수를 이동 :.

$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); 
} 

는에 변수를 갖는 top을 사용하면 입력 매개 변수를 검토 할 수 있습니다. 다음 코드를 미리 확인하고 더 나은 개요를 제공하십시오.

처리 과정에서 반환 값을 확인하면 문제를 가장 일찍 발견 할 수 있습니다.

openssll 오류를 읽으면 문제를 해결하는 데 유용한 정보를 얻을 수 있습니다.

거의 모든 정보는 PHP 설명서에서 찾을 수 있습니다. 이 대답은 구체적인 문제를 해결하지 못할 수도 있지만 문제 자체 및 코드 관련 문제를보다 잘 해결하는 데 필요한 도구를 제공해야합니다.

코드의 일부 비용 만 들지만 코드가 훨씬 잘 작동합니다. 새 서버로 스크립트를 복사한다고 상상해보십시오. 아마도 상황이 다르고 눈이 멀어지는 것을 원하지 않을 것입니다.

해피 디버깅. 보시다시피 코드의 첫 번째 부분 만 다루었으므로 코드를 실행하지 않았다는 것을 알아야합니다. 따라서이 예제는 최선의 의도로 수행되지만 시나리오에 대해 즉시 작동한다는 보장은 없습니다. 그러나 나는 그것이 내가 보여주고 싶었던 것을 볼 수 있다고 생각한다. 코드의 나머지 부분에 대해 유사한 검사를 적용하면 솔루션의 절반 인 정확히 무엇이 잘못되었는지 알 수 있어야합니다.

+0

내 코드를 참조하십시오 ... 나는 그를 업데이트했습니다 ... 내 변경 사항없이 origniall 코드입니다 ...이 버전에서도 작동하지 않는 것 같습니다 –

+0

어떤 오류가 openssl에서 돌아오고 있습니까? PHP가''$ name.zip '''을 찾아서 읽을 수 있습니까? 그리고 그것은 여러분의 코드를 살펴볼 때 두 가지 질문 일뿐입니다. 그걸 알아 내야 해. 내 대답이 그 길을 따라 당신을 도울 수 있기를 바랍니다. – hakre

관련 문제