I am trying to implement Google AMP update-cache request using this documentation.
My implementation
As suggested in the tutorial, firstly I get the cache information from https://cdn.ampproject.org/caches.json and then I iterate through these caches to perform update.
Simplified code for single cache (as there is just one at the moment anyways):
Main logic
String firstPartUrl = "https://amp--frontend-dpo-styria--publishing-com.cdn.ampproject.org"
String secondPartUrl = "/update-cache/c/s/amp-frontend.dpo.styria-publishing.com/octopus/5267614?amp_action=flush&_ts=1505218616"
secondPartUrl = signRequestUrl(secondPartUrl);
performRequest(firstPartUrl, secondPartUrl);
Signing function
private String signRequestUrl(String requestUrl) throws Exception {
URL url = Resources.getResource("rsa/private-key-pcks8.pem");
String privateKey = Resources.toString(url, Charsets.UTF_8);
String signature = signSHA256RSA(requestUrl, privateKey);
StringBuilder builder = new StringBuilder(requestUrl);
builder.append("&_url_signature=");
builder.append(signature);
return builder.toString();
}
public static String signSHA256RSA(String input, String privateKey) throws Exception {
// Remove markers and new line characters in private key
String realPK = privateKey.replaceAll("-----END PRIVATE KEY-----", "")
.replaceAll("-----BEGIN PRIVATE KEY-----", "")
.replaceAll("\r\n", "")//windows
.replaceAll("\n", "");//unix
byte[] b1 = Base64.getDecoder().decode(realPK);
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(b1);
KeyFactory kf = KeyFactory.getInstance("RSA");
Signature privateSignature = Signature.getInstance("SHA256withRSA");
privateSignature.initSign(kf.generatePrivate(spec));
privateSignature.update(input.getBytes());
byte[] s = privateSignature.sign();
return Base64.getUrlEncoder().withoutPadding().encodeToString(s);
}
My public key is published here: https://amp-frontend.dpo.styria-publishing.com/.well-known/amphtml/apikey.pub
What I tried
I even tried to follow the signing steps in the command line, but even after that the URL I obtained returned 403.
I tried following tips from this question (making sure that I use SHA256 and setting content-type of apikey to text/plain, but it did not help)
My question
Do you know why is Google AMP still returning 403? I suspected, that there might be an issue with my Base64 encoding, because the documentation is not very clear about that, but I am not sure.
EDIT
I realized there might be a problem with the implementation of the function building secondPartUrl
- specifically the timestamp. I created the timestamp using ZonedDateTime.now()
, which is obviously wrong, as I am in different Timezone than UTC. However, changing it to Instant.now()
did not help.