更新Google AMP缓存URL签名验证错误 [英] Update Google AMP cache URL signature verification error
问题描述
我正在尝试更新Google AMP缓存中的Google AMP页面,但收到URL签名验证错误.
I'm trying to update my Google AMP pages in the Google AMP Cache, but get an URL signature verification error.
我的代码:
Dim tStamp As String = GetUnixTimeStampFromDateTime(DateTime.Now).ToString
Dim ampBaseUrl As String = "https://www-example-com.cdn.ampproject.org"
Dim signatureUrl As String = "/update-cache/c/s/www.example.com/articles/278/myarticle/amp?amp_action=flush&_ts=" + tStamp
Dim rsa As RSA = certificate.GetRSAPrivateKey()
Dim data() As Byte = System.Text.Encoding.Unicode.GetBytes(signatureUrl)
Dim sig() As Byte = rsa.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1)
Dim AMPURLSignature As String = EncodeTo64(sig.ToString)
编码功能:
Public Shared Function EncodeTo64(ByVal toEncode As String) As String
Dim toEncodeAsBytes As Byte() = System.Text.ASCIIEncoding.ASCII.GetBytes(toEncode)
Dim returnValue As String = System.Convert.ToBase64String(toEncodeAsBytes)
Return returnValue
End Function
我尝试使用此URL .
现在,我收到403错误:
Now, I get a 403 error:
您的客户端无权获取URL/update-cache/c/s/www.example.com/articles/278/myarticle/amp?amp_action=flush&_ts=1523016476&_url_signature=U2lzdGVtLkJ5dGVbdQ. URL签名验证错误.这就是我们所知道的.
Your client does not have permission to get URL /update-cache/c/s/www.example.com/articles/278/myarticle/amp?amp_action=flush&_ts=1523016476&_url_signature=U2lzdGVtLkJ5dGVbdQ. URL signature verification error. That’s all we know.
我发现Google示例代码不够清晰: https://developers.google .com/amp/cache/update-cache
I find the Google example code not clear enough: https://developers.google.com/amp/cache/update-cache
我的问题是关于签名URL的:
My questions are around the signature URL:
- 我使用文章AMP URL还是常规URL?
- 我是否需要在我的签名URL中包含查询字符串参数
amp_action
和amp_ts
?还是在签署URL后稍后再添加这些内容? - 我应该将上面的
ampBaseUrl
放在我的signatureUrl
变量之前,还是不需要?
- do I use the article AMP URL or the regular URL?
- do I need to include the querystring parameters
amp_action
andamp_ts
in my signature URL? Or do I append these later after I've signed the URL? - should I prepend the
ampBaseUrl
above to mysignatureUrl
variable or is this not needed?
更新1
根据@CodeFuller的建议,我检查了URL,并收到一条Verified OK
消息.我也已经完成了步骤2:
Based on @CodeFuller's recommendations, I checked the URL and am getting a Verified OK
message. I've also taken care of step 2:
- APIkeys match: https://www.toptrouwen.nl/.well-known/amphtml/apikey.pub matches https://www-toptrouwen-nl.cdn.ampproject.org/r/s/www.toptrouwen.nl/.well-known/amphtml/apikey.pub
- Serving apikey.pub from my server as text/plain
- serving apikey.pub over https and publicly
- Added disallow in robots: User-agent: * Disallow: /.well-known/amphtml/apikey.pub
更新2
是的,通过新代码,我还将获得Verified OK
验证.
Yes, with the new code I also get Verified OK
on verification.
生成此URL:
https://www-toptrouwen-nl.cdn.ampproject.org/update-cache/c/s/www.toptrouwen.nl/artikelen/132/het-uitwisselen-van-de-trouwringen-hoe-voorkom-je-bloopers/amp?amp_action=flush&_ts=1523138180&_url_signature=tKPO3k624ybwxoEynqN8oI3/UDxhq1TF8jX9aKeVyL0IWLUODXuMB7ansP0t1+/5Lm2V7RYZbUWxt2Whh7+LFEmfQFGJJE/iPtoBVsqrdb5356QwiIrDHOzY+3z5dASZxYlAwlfzUFdonGyDsh/UlCjjvvNahFEWzHOpB5JQxJQ1Wn0kGLQUF1v2u47abbae6cNQBm3YB/0Z1FLfTJLM1oOEOSDh9vQH1SqO/6SoYtUhSQjSrYdl/g5O0QJ7A9pKUxOPfgVJM0l8Sgb66cVeWWoWq0WIFe24RPXUMl9tIFFZ1TY2R+ZpIMvpEAPDjCsdGPo7KTWqGb4qfoTBINJmtQ==
This URL is generated:
https://www-toptrouwen-nl.cdn.ampproject.org/update-cache/c/s/www.toptrouwen.nl/artikelen/132/het-uitwisselen-van-de-trouwringen-hoe-voorkom-je-bloopers/amp?amp_action=flush&_ts=1523138180&_url_signature=tKPO3k624ybwxoEynqN8oI3/UDxhq1TF8jX9aKeVyL0IWLUODXuMB7ansP0t1+/5Lm2V7RYZbUWxt2Whh7+LFEmfQFGJJE/iPtoBVsqrdb5356QwiIrDHOzY+3z5dASZxYlAwlfzUFdonGyDsh/UlCjjvvNahFEWzHOpB5JQxJQ1Wn0kGLQUF1v2u47abbae6cNQBm3YB/0Z1FLfTJLM1oOEOSDh9vQH1SqO/6SoYtUhSQjSrYdl/g5O0QJ7A9pKUxOPfgVJM0l8Sgb66cVeWWoWq0WIFe24RPXUMl9tIFFZ1TY2R+ZpIMvpEAPDjCsdGPo7KTWqGb4qfoTBINJmtQ==
然后我得到错误Required query parameter 'amp_url_signature' missing.
(与以前的问题有关,其中amp_
参数被破坏.
Then I get error Required query parameter 'amp_url_signature' missing.
(related to earlier issue where amp_
parameters get botched.
然后我将URL参数重命名为其正确的名称:https://www-toptrouwen-nl.cdn.ampproject.org/update-cache/c/s/www.toptrouwen.nl/artikelen/132/het-uitwisselen-van-de-trouwringen-hoe-voorkom-je-bloopers/amp?amp_action=flush&_ts=1523138180&_url_signature=tKPO3k624ybwxoEynqN8oI3/UDxhq1TF8jX9aKeVyL0IWLUODXuMB7ansP0t1+/5Lm2V7RYZbUWxt2Whh7+LFEmfQFGJJE/iPtoBVsqrdb5356QwiIrDHOzY+3z5dASZxYlAwlfzUFdonGyDsh/UlCjjvvNahFEWzHOpB5JQxJQ1Wn0kGLQUF1v2u47abbae6cNQBm3YB/0Z1FLfTJLM1oOEOSDh9vQH1SqO/6SoYtUhSQjSrYdl/g5O0QJ7A9pKUxOPfgVJM0l8Sgb66cVeWWoWq0WIFe24RPXUMl9tIFFZ1TY2R+ZpIMvpEAPDjCsdGPo7KTWqGb4qfoTBINJmtQ==
I then renamed URL parameters to their correct names: https://www-toptrouwen-nl.cdn.ampproject.org/update-cache/c/s/www.toptrouwen.nl/artikelen/132/het-uitwisselen-van-de-trouwringen-hoe-voorkom-je-bloopers/amp?amp_action=flush&_ts=1523138180&_url_signature=tKPO3k624ybwxoEynqN8oI3/UDxhq1TF8jX9aKeVyL0IWLUODXuMB7ansP0t1+/5Lm2V7RYZbUWxt2Whh7+LFEmfQFGJJE/iPtoBVsqrdb5356QwiIrDHOzY+3z5dASZxYlAwlfzUFdonGyDsh/UlCjjvvNahFEWzHOpB5JQxJQ1Wn0kGLQUF1v2u47abbae6cNQBm3YB/0Z1FLfTJLM1oOEOSDh9vQH1SqO/6SoYtUhSQjSrYdl/g5O0QJ7A9pKUxOPfgVJM0l8Sgb66cVeWWoWq0WIFe24RPXUMl9tIFFZ1TY2R+ZpIMvpEAPDjCsdGPo7KTWqGb4qfoTBINJmtQ==
然后我得到:404 Failed to decode amp_url_signature
,我认为这是因为URL中包含+
和\
个字符.删除这些错误后,我再次收到错误URL signature verification error
.
Then I get: 404 Failed to decode amp_url_signature
, I thought this was because there are +
and \
characters in the URL. When I remove those I get the error URL signature verification error
again.
我不认为UTC时间戳当前是问题,因为我之前已经看到,如果时间戳不正确,Google会抛出错误.
I don't think the UTC timestamp is currently an issue, because I've seen before that Google will throw an error if the timestamp is incorrect.
推荐答案
URL signature verification error
的两个最常见原因:
-
签名计算不正确.
Incorrect calculation of the signature.
因此,要做的第一件事就是验证签名实际上是有效的.将签名的URL和结果签名保存到某些文件中:
So the first thing to is to verify that signature is actually valid. Save signed URL and result signature to some files:
Dim signatureUrl As String = "/update-cache/c/s/www.example.com/articles/278/myarticle/amp?amp_action=flush&_ts=" + tStamp
' ...
Dim sig() As Byte = rsa.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1)
File.WriteAllText("url.txt", signatureUrl)
File.WriteAllBytes("signature.bin", sig)
然后使用openssl工具验证签名:
Then verify the signature with openssl tool:
openssl.exe dgst -sha256 -signature signature.bin -verify publickey.pem url.txt
openssl.exe dgst -sha256 -signature signature.bin -verify publickey.pem url.txt
如果输出为
验证正常
然后您的签名就可以了,您应该在其他地方搜索问题(请参阅第2项).
then your signature is OK and you should search the problem in other place (see item #2).
如果输出为
验证失败
然后您应该重新检查签名计算的例程.
then you should recheck the routine of signature calculation.
publickey.pem是PEM格式的公钥.它应该以以下行开头:
publickey.pem in command above is the public key in PEM format. It should start with the following line:
-----BEGIN PUBLIC KEY-----
如果您有证书文件(以-----BEGIN CERTIFICATE-----
开头),则可以使用以下命令为其获取PEM :
If you have certificate file (starting with -----BEGIN CERTIFICATE-----
), you could get PEM for it with the following command:
openssl.exe x509 -pubkey -noout -in publickey.cer> publickey.pem
openssl.exe x509 -pubkey -noout -in publickey.cer > publickey.pem
如果签名已成功验证,则应检查是否可以通过Web访问公钥. 更新AMP内容指出以下要求:
If signature was verified successfully, then you should check whether your public key is accessible over the Web. Update AMP Content states following requirement:
要进行签名验证,必须将RSA公钥提供给AMP文档域中的固定位置(要生成密钥,请参阅生成RSA密钥).例如:
For signature verification, you must serve the public RSA key at a fixed location on the AMP document's domain (to generate the key, see Generate the RSA key). For example:
https://example.com/.well-known/amphtml/apikey .pub
-
公钥不能被机械化.
The public key must not be roboted.
URL必须是HTTPS.
The URL must be HTTPS.
域必须是您要更新的确切域,而不是子域或超级域.
The domain must be the exact domain that you want to update, not a sub or super domain.
您必须以PEM格式发布密钥,并以内容类型文本/纯文本"提供密钥.
You must publish the key in PEM format and serve the key with the content-type "text/plain".
因此,如果您的AMP基本URL为https://www.test.com
,请检查以下URL是否可访问您的公钥:https://www.test.com/.well-known/amphtml/apikey.pub
So if your AMP base URL is https://www.test.com
, check that your public key is accessible at following URL: https://www.test.com/.well-known/amphtml/apikey.pub
以下是您其他问题的答案:
Here are answers to your other questions:
我是否需要在我的签名URL中包含查询字符串参数amp_action和amp_ts?还是在签署URL之后稍后再添加这些内容?
do I need to include the querystring parameters amp_action and amp_ts in my signature URL? Or do I append these later after I've signed the URL?
是的,您应该在要计算签名的URL中包含amp_action
和amp_ts
.
Yes, you should include amp_action
and amp_ts
into the URL for which signature is calculated.
我应该在上面的ampBaseUrl之前添加我的signatureUrl变量,还是不需要?
should I prepend the ampBaseUrl above to my signatureUrl variable or is this not needed?
如更新AMP内容所述:
AMP缓存主机名(cdn.ampproject.org)从 签名,以允许向多个AMP提交相同的签名请求 缓存运算符.
The AMP Cache hostname (cdn.ampproject.org) is excluded from the signature to allow submitting the same signed request to multiple AMP Cache operators.
因此,您不应在计算签名的URL中包含ampBaseUrl
.
So you should not include ampBaseUrl
into the URL for which signature is calculated.
更新
我在将签名附加到URL的代码中发现了另一个错误:
I have found another error in the code where you append signature to the URL:
Dim AMPURLSignature As String = EncodeTo64(sig.ToString)
sig.ToString
将导致将"System.Byte[]"
字符串传递给EncodeTo64
,而不是实际的签名字节.结果,不正确的签名被附加到更新缓存URL.将上面的调用替换为以下内容(不再需要EncodeTo64
):
sig.ToString
will result to passing of "System.Byte[]"
string to EncodeTo64
, instead of actual signature bytes. As result incorrect signature was appended to update cache URL. Replace above call with the following (EncodeTo64
is not required anymore):
Dim AMPURLSignature As String = System.Convert.ToBase64String(sig)
另一个可能的问题是,您使用的时间戳不能满足满足以下条件:
Another possible problem is that timestamp you use does not satisfy following requirement:
该值应该是当前时间(以秒为单位),该时间必须在之内 在当前时间之前或之后1分钟.
The value should be the current time in seconds, which must be within 1 minute before or after the current time.
您将DateTime.Now
传递给GetUnixTimeStampFromDateTime()
,但这应该是UTC时间,而不是本地时间.尝试将tStamp
计算替换为:
You pass DateTime.Now
to GetUnixTimeStampFromDateTime()
but it should be UTC time, not local time. Try replacing tStamp
calculation with:
Dim tStamp As String = CInt((DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds).ToString
还要确保在生成update-cache
URL后立即调用它,以便与时间戳相比,当前时间在1分钟间隔内.而且您的系统时间应该准确.
Also make sure you call update-cache
URL just after it was generated, so that current time is within 1 minute interval comparing to timestamp. And your sytem time should be precise.
请在上述修复后重新检查签名验证是否通过.
Please recheck whether signature verification passes after above fixes.
更新2 (关于签名中的+
和/
字符)
UPDATE 2 (Regarding +
and /
characters in signature)
AMP缓存更新签名应该采用的是base4编码的变体:
AMP cache update signature should go in variation of base4 encoding:
使用 base64的网络安全变体对二进制RSA签名进行编码 >
Encode the binary RSA signature using the web-safe variant of base64
因此,另一个必需的解决方案是将+
和/
字符替换为-
和_
.
So another required fix is to replace +
and /
charcters with -
and _
.
更改后续通话
Dim AMPURLSignature As String = System.Convert.ToBase64String(sig)
具有:
Dim AMPURLSignature As String = ToWebSafeBase64(sig)
' ...
Private Function ToWebSafeBase64([data]() As Byte) As String
Dim base64 = System.Convert.ToBase64String(data)
base64 = base64.Replace("+", "-")
base64 = base64.Replace("/", "_")
Return base64
End Function
更新3
以下是应产生正确的update-cache
URL的最终代码(基于可用文档):
Here is the final code that should produce correct update-cache
URL (based on available documentation):
Module MainModule
Sub Main()
Dim tStamp As String = CInt((DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds).ToString
Dim ampBaseUrl = "https://www-toptrouwen-nl.cdn.ampproject.org"
Dim signatureUrl As String = "/update-cache/c/s/www.toptrouwen.nl/artikelen/132/het-uitwisselen-van-de-trouwringen-hoe-voorkom-je-bloopers?amp_action=flush&_ts=" + tStamp
Dim data() As Byte = System.Text.Encoding.ASCII.GetBytes(signatureUrl)
Dim certificate = New X509Certificate2("d:\temp\keys\keys.pfx", "12345")
Dim rsa As RSA = certificate.GetRSAPrivateKey()
Dim sig() As Byte = rsa.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1)
Dim ampUrlSignature As String = ToWebSafeBase64(sig)
Dim url As String = ampBaseUrl + signatureUrl + "&_url_signature=" + ampUrlSignature
Console.WriteLine(url)
End Sub
Private Function ToWebSafeBase64([data]() As Byte) As String
Dim base64 = System.Convert.ToBase64String(data)
base64 = base64.Replace("+", "-")
base64 = base64.Replace("/", "_")
Return base64
End Function
End Module
它产生以下URL:
已使用opensll工具成功验证了此签名,但是获取此URL仍返回URL signature verification error.
.但是现在在我们这边一切似乎都很好.我在github上发现了相关问题.以下是来自AMP项目贡献者的声明:
This signature is verified successfully with opensll tool however getting this URL still returns URL signature verification error.
. However now everything seems fine on our side. I have found related issue on github. There is following statement from AMP project contributor:
首先,我确定AMP缓存不处理HTTP刷新 正确获取更新缓存验证密钥:如果您发出 更新缓存请求,然后交换/.well-known/amphtml/apikey.pub 使用其他密钥,我们将无限期地使用旧密钥材料. 更糟的是,还会永久缓存404响应:-(
First of all, I determined that AMP Cache does not handle HTTP refresh correctly for update-cache verification keys: if you issue an update-cache request and then swap /.well-known/amphtml/apikey.pub with a different key, we keep using the old key material indefinitely. To make things worse, 404 responses are also cached forever :-(
我提交了内部错误报告,但可能需要一些时间才能完成 解决将其投入生产的问题.同时,我可以刷新无效的密钥 手动.只需在GitHub或上给我发送私人消息 amphtml.slack.com.很抱歉没有早发现这一点.
I filed an internal bug report, but it might take some time for the fix to roll out to production. Meanwhile, I can flush invalid keys manually. Just send me a private message either on GitHub or on amphtml.slack.com. Apologies for not discovering this sooner.
似乎是当前错误的根本原因.您尝试过在https://www.toptrouwen.nl/.well-known/amphtml/apikey.pub
没有可用的公共密钥时更新缓存(当我第一次检查它时,它导致404错误). Google已缓存了此结果,现在即使证书可用,它也并未实际使用.
Seems like it's a root cause of current error. You have tried updating the cache while there was no public key available at https://www.toptrouwen.nl/.well-known/amphtml/apikey.pub
(When I checked it first time it was resulted to 404 error). Google has cached this result and now even when certificate is avaiable it's not actually used.
目前看来,唯一可行的解决方法是与codewiz联系,并要求他清除缓存的密钥错误.在AMP系统使用有效的公共密钥之前,无法进行签名验证.
Seems like the only possible workaround for this moment is to contact codewiz and ask him to flush the cached key error. Until AMP system uses valid public key, signature verification is not possible.
这篇关于更新Google AMP缓存URL签名验证错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!