更新Google AMP缓存URL签名验证错误 [英] Update Google AMP cache URL signature verification error

查看:151
本文介绍了更新Google AMP缓存URL签名验证错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试更新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&amp_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&amp_ts=1523016476&amp_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&amp_ts=1523016476&amp_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:

  1. 我使用文章AMP URL还是常规URL?
  2. 我是否需要在我的签名URL中包含查询字符串参数amp_actionamp_ts?还是在签署URL后稍后再添加这些内容?
  3. 我应该将上面的ampBaseUrl放在我的signatureUrl变量之前,还是不需要?
  1. do I use the article AMP URL or the regular URL?
  2. 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?
  3. should I prepend the ampBaseUrl above to my signatureUrl 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:

  1. API密钥匹配: https://www.toptrouwen.nl/. well-known/amphtml/apikey.pub 匹配
  1. 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
  2. Serving apikey.pub from my server as text/plain
  3. serving apikey.pub over https and publicly
  4. 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&amp_ts=1523138180&amp_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&amp_ts=1523138180&amp_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的两个最常见原因:

  1. 签名计算不正确.

  1. 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&amp_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_actionamp_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&amp_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 + "&amp_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
    

    GitHub上的示例项目

    它产生以下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_action=flush&amp_ts=1523188941& amp_url_signature = bZJTE4IjlxGhlU79etivzUPpGFoyKvCxqPO1IOPHfzDKQVt-fA8Mte20SeXjTQs24Uy4RD9lmbS2aXlcCTpOYatF2l8PQ-31kR-lKVnuduSZIrg93g2YrvO7x-a6dr19hN74LywgBw4C_JfuocCuGfVvr-mD40tuwkBrsLgmI9E =

    已使用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屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆