如何以 PEM 格式发布密钥并使用 php 提供内容类型为 "text/plain" 的密钥?

How to publish the key in PEM format and serve the key with the content-type "text/plain" using php?

“我正在使用 Google AMP 缓存。首先,我使用 PHP 生成一对密钥(私钥。pem/public-key.pub)。我用过下面的代码:

<?php 


$pkGenerate = openssl_pkey_new(array(
    'private_key_bits' => 2048,
    'private_key_type' => OPENSSL_KEYTYPE_RSA
));


openssl_pkey_export($pkGenerate,$pkGeneratePrivate); 


$pkGenerateDetails = openssl_pkey_get_details($pkGenerate);
$pkGeneratePublic = $pkGenerateDetails['key'];

openssl_pkey_free($pkGenerate);

$pkImport = openssl_pkey_get_private($pkGeneratePrivate); 

$pkImportDetails = openssl_pkey_get_details($pkImport); 
$pkImportPublic = $pkImportDetails['key'];

file_put_contents('private-key.pem', $pkGeneratePrivate); 
file_put_contents($_SERVER['DOCUMENT_ROOT'].'/.well-known/amphtml/apikey.pub', $pkImportPublic); 

然后验证签名并使用以下代码使 AMP google 缓存 URL:

function urlsafe_b64encode($string) {
    return str_replace(array('+','/','='),array('-','_',''), base64_encode($string));
}

$timestamp=time();
$ampBaseUrl = "https://www-example-com.cdn.ampproject.org";
$signatureUrl = '/update-cache/c/s/example.com/google-seo-articles/ten-signs-your-seo-company-is-not-a-shark/?amp_action=flush&amp_ts='.$timestamp;

// opening the private key
$pkeyid = openssl_pkey_get_private("file://private-key.pem");
// generating the signature
openssl_sign($signatureUrl, $signature, $pkeyid, OPENSSL_ALGO_SHA256);
openssl_free_key($pkeyid);
// urlsafe base64 encoding
$signature = urlsafe_b64encode($signature);
// final url for updating
$ampUrl = $ampBaseUrl.$signatureUrl."&amp_url_signature=".$signature;
$ampUrl = str_replace("&", "&amp", $ampUrl);
echo $ampUrl."\n";

输出:

https://www-example-com.cdn.ampproject.org/update-cache/c/s/example.com/google-seo-articles/ten-signs-your-seo-company-is-not-a-shark/?amp_action=flush&amp_ts=1564374402&amp_url_signature=Wtnae4vEz5cn0El8bKBh6xLSiqhy2YmMEwyp3tbR5OzD7Ym4-MCE926p1IuJBMSUjmoaRZpBHDvvG-sdgtTQijYpHJ9QiNRvR4w_b92ZeeInQ5qxVW93gZzVq6ODlwPP8aphkT6635ny9bgHWblQTz0Np0XA9my-roVaRqAPRH1NgBRyQFcJAoLNhBITy4ta94mn4qModJRVCwjPxich_N1ZLLXgPtp4KBZl2sYWTnROhJ-OujFDHA-2E7_DT-hMte7WjP_lBQLffkmwCTTTI2lrXaYwzSWx9MJYDqmnC1o0rGH3PW4y6R6xQ2jRVK9vaNSQTixVylBmMQFPbzVKVQ

当我用浏览器检查输出时 google return 错误 403 和 Invalid public key due to ingestion error: Invalid Content

我研究过错误 403,我认为我的问题与内容类型 public 键有关。

Google AMP缓存guideline写入

You must publish the key in PEM format and serve the key with the content-type "text/plain". 

我已经用下面的 curl

检查了我的内容类型 public 键
curl -H 'Accept-Encoding: gzip' -i https://www.example.com/.well-known/amphtml/apikey.pub

输出:

HTTP/1.1 200 OK
Date: Mon, 29 Jul 2019 04:38:58 GMT
Content-Type: application/x-mspublisher
Content-Length: 451
Connection: keep-alive
Set-Cookie: __cfduid=dc3c0780a997f6ddf625019d3cf579a991564375138; expires=Tue, 28-Jul-20 04:38:58 GMT; path=/; domain=.example.com;HttpOnly
Last-Modified: Sun, 28 Jul 2019 17:48:39 GMT
Accept-Ranges: bytes
Vary: User-Agent
X-Turbo-Charged-By: LiteSpeed
Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
Server: cloudflare
CF-RAY: 4fdc68069ff5e0fa-IAD

它显示内容类型:application/x-mspublisher!

所以,我想将 Content-Type: application/x-mspublisher 更改为 plain/text。

如有错误请指正

提前致谢。

您为已发布的 apikey 使用的扩展名是“.pub”,它很可能链接到 mimetype application/x-mspublisher(MS Publisher)。您可以将文件名的扩展名更改为 .txt,这是最简单的解决方案。您还可以执行以下操作:

  • 在您的网络服务器配置中更改 .pem(或 .pub)文件的 mimetype 定义。根据您的 OS (Linux/Windows/etc.),这可以在 /etc/mime.types 中完成,或者在 Windows 上使用 IIS 管理控制台时使用 IIS。

  • 使用 .htaccess (apache) 或 web.config (IIS) 更改文件的 mimetype。

使用 .htaccess 时,您可以在文件中添加以下规则:

AddType text/plain pub 

使用 IIS 时,您可以在 Web.Config 中添加以下行。请确保在添加新声明之前删除之前的声明:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <staticContent>
            <remove fileExtension=".pub" />
            <mimeMap fileExtension=".pub" mimeType="text/plain" />
        </staticContent>
    </system.webServer>
</configuration>

提示:使用此行 file_put_contents('private-key.pem', $pkGeneratePrivate); 取决于您的代码在 webroot 中 运行 的位置,您可能将私钥存储在可公开访问的位置。您可能想将其更改为 webroot 之外的位置。