Я хочу обновить кеш Google AMP, поэтому мне нужно подписать URL-адрес, как описано здесь.
Моя основная проблема: я изо всех сил борюсь с тем, как мне получить свои сертификаты/ключи и как их включить в мой код ниже. Я просто не могу найти никаких инструкций по покрытию для Windows и IIS.
Я читал эти сообщения:
- Использование /update-cache запросов для обновления страниц AMP
- Как я могу подписать файл с помощью RSA и SHA256 с.NET?
Я не хочу использовать хранилище сертификатов компьютеров, как описано во втором сообщении. Я бы предпочел использовать файлы на диске для открытых и закрытых ключей. На моем производственном сервере IIS я экспортировал свой сертификат в файл.pfx, из которого я извлек секретный ключ и сертификат, используя инструкции в нижней части этого сайта. Сервер.key содержит -----BEGIN RSA PRIVATE KEY-----
, который, если я использую это для загрузки в переменную privateCert
в коде ниже, вызывает ошибку Cannot find the requested object.
То, что я получил от моего поставщика SSL: www_example_com.crt
, www_example_com.p7b
, certificate code
(см. Ниже).
Шаги, которые я сделал:
- Я создал
test-public-key.cer
, открывwww_example.com.crt
и используя мастерCopy to file
чтобы скопировать его в кодированный base64 файл.cer. - Я сохранил
certificate code
полученный мной от поставщика SSL, в качестве файлаtest-private-key.cer
.
Когда я запускаю следующий код, я получаю ошибку
В экземпляре объекта не задана ссылка на объект.
on line key.FromXmlString(privateCert.PrivateKey.ToXmlString(True))
Dim publicCert As X509Certificate2 = New X509Certificate2("C:\temp\_certificates\test-public-key.cer")
Dim privateCert As X509Certificate2 = New X509Certificate2("C:\temp\_certificates\test-private-key.cer")
'Round-trip the key to XML and back, there might be a better way but this works
Dim key As RSACryptoServiceProvider = New RSACryptoServiceProvider
key.FromXmlString(privateCert.PrivateKey.ToXmlString(True))
'Create some data to sign
Dim data() As Byte = System.Text.Encoding.Unicode.GetBytes(signatureUrl)
'Sign the data
Dim sig() As Byte = key.SignData(data, CryptoConfig.MapNameToOID("SHA256"))
Dim AMPURLSignature As String = EncodeTo64(sig.ToString)
'Lastly, the verification can be done directly with the certificate public key without need for the reconstruction as we did with the private key:
key = CType(publicCert.PublicKey.Key, RSACryptoServiceProvider)
If Not key.VerifyData(data, CryptoConfig.MapNameToOID("SHA256"), sig) Then
Throw New CryptographicException
End If
Функция EncodeTo64
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
certificate code
-----BEGIN CERTIFICATE-----
MIIF (...) DXuJ
-----END CERTIFICATE-----
ОБНОВЛЕНИЕ 1
Мне удалось создать файл mysite.pfx, выполнив шаги экспорта на этой странице. В мастере я постарался выбрать "Да, экспортировать закрытый ключ", и я добавил пароль. Остальные шаги я выполнил дословно.
Затем я также запускал следующие команды: openssl pkcs12 -in mysite.pfx -nocerts -out private-key-VPS.pem
penssl pkcs12 -in mysite.pfx -clcerts -nokeys -out certificate-VPS.pem
Я закончил с private-key-VPS.pem
и private-key-VPS.pem
certificate-VPS.pem
Я знаю, что шаги для получения mysite.pfx немного отличаются от того, что описал @CodeFuller, но пока что так хорошо?
Затем я добавил код:
Dim certificate As X509Certificate2 = New X509Certificate2("C:\temp\_certificates\prodserverV2\mysite.pfx", "mypwd")
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)
Но там я получаю 4 ошибки:
GetRSAPrivateKey 'не является членом' X509Certificate2 '.
"SignData" не является членом "RSA".
'HashAlgorithmName' не объявляется. Он может быть недоступен из-за его уровня защиты.
"RSASignaturePadding" не объявляется. Он может быть недоступен из-за его уровня защиты.
ОБНОВЛЕНИЕ 2
Спасибо @CodeFuller! Я нацелился на рамки 4.6.1 и теперь, похоже, еще на один шаг. Я получаю такой URL: https://www-mysite-com.cdn.ampproject.org/update-cache/c/s/www.mysite.com/articles/270/newarticle1/amp?amp_action=flush&_ts=1522939248&_url_signature=U30zdGVtLkJ5uGVbRQ==
. Как я могу проверить, действительно ли это URL? Я проверяю раздел "Генерировать ключ RSA" на этой странице, но я смущен, так как я на самом деле уже просто закодировал эти шаги или нет? Как я могу проверить, действителен ли URL-адрес, который я сейчас закончил?
ОБНОВЛЕНИЕ 3
Хорошо, я попробовал ваш новый код. Все еще получите URL signature verification error
. Я попытался с URL-адресом /amp
моей статьи и без части /amp
в моем URL-адресе. Оба результата приводят к той же ошибке проверки подлинности подписи URL.
Я заметил, что когда я печатаю конечный URL-адрес моего веб-сайта (см. Код ниже), 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=1523094395&_url_signature=U3lzdGVrLkn5dGVbXQ==
Обратите внимание, что там, где параметры должны быть amp_ts
и amp_url_signature
, теперь они _ts
и _url_signature
соответственно.
Я пробовал редактировать URL-адрес, прежде чем совершать звонок в Google, вручную переименовывая параметры _ts
и _url_signature
в amp_ts
и amp_url_signature
. Но я предполагаю, что это приведет к различию между сигнатурой и фактическим URL. Может быть, что-то мой код подрывает символ &
и поэтому, когда я переименую их вручную позже, это всегда приводит к проверке подписи? Вы видите, что я могу исправить в своем коде?
BTW: Я попытался заменить &
%26
на код перед тем, как подписать URL-адрес, но затем я получаю ошибку Google 404:
Запрошенный URL/update-cache/c/s/www.toptrouwen.nl/artikelen/132/het-uitwisselen-van-de-trouwringen-hoe-voorkom-je-bloopers/amp?amp_action=flush%26amp_ts=1523094395% 26 amp_url_signature=U3lzdGVrLkJ1dGVbXQ== не найден на этом сервере. Это все, что мы знаем.
Мой код:
Dim ampBaseUrl As String = "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?amp_action=flush&_ts=" + tStamp
Dim rsa As RSA = certificate.GetRSAPrivateKey()
Dim data() As Byte = System.Text.Encoding.ASCII.GetBytes(signatureUrl)
Dim sig() As Byte = rsa.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1)
Dim AMPURLSignature As String = EncodeTo64(sig.ToString)
Dim url As String = ampBaseUrl + signatureUrl + "&_url_signature=" + AMPURLSignature
ltStatus.Text = "AMP URL:<a target='_blank' href='" + url + "'>" + url + "</a>"
Кроме того, я уверен, что эта страница существует в кеше Google AMP, так как я вижу и запрашиваю ее в результатах поиска Google на своем мобильном устройстве.
ОБНОВЛЕНИЕ 4
Я приближаюсь, думаю, а также получаю дополнительную помощь, см. Здесь: https://github.com/ampproject/amphtml/issues/14483#issuecomment-380549060
Теперь я пытаюсь сделать так, чтобы другие могли также проверить: вместо того, чтобы зависеть от моего SSL, я теперь выполнил следующие команды, чтобы получить открытый и закрытый ключ
openssl genrsa 2048 > private-key.pem
openssl rsa -in private-key.pem -pubout >public-key.pem
Теперь у меня есть файлы private-key.pem
и public-key.pem
Я переименую public-key.pem
в apikey.pub
и apikey.pub
на https://example.com/.well-known/amphtml/apikey.pub
Я хочу использовать самый простой подход, рекомендуемый @CodeFuller, и создать файл .pfx
который затем можно загрузить в переменную типа X509Certificate2
. Когда я запускаю эту команду: openssl pkcs12 -export -out keys.pfx -inkey private-key.pem -in public-key.pem
Я получаю сообщение об ошибке: unable to load certificates
Но на этот раз у меня нет файла .crt
, только public-key.pem
. Как я могу получить файл .pfx
? Я уже проверил здесь.