Crypto-Key header: illegal format
This issue exists since the new version 5.1.2.
What I did: Try to send a push message with VAPID, using Chrome 133.
Result: The push-service answered HTTP 403: permission denied: crypto-key header had invalid format. crypto-key header should have the following format: p256ecdsa=base64(publicApplicationServerKey)
Reason: The error disappears when reverting the following change between version 5.1.1 and 5.1.2. in AbstractPushService:
I checked that it can also be solved by replacing
Base64.getUrlEncoder().encodeToString(pk) by Base64.getUrlEncoder().withoutPadding().encodeToString(pk).
withoutPadding was simply missed here during the task of replacing Base64Encoder.
By the way: I believe that the constructors of Notification that use Base64.getUrlDecoder() and Utils.loadPublicKey don't work because of the usage of the URL-decoder. The example in https://github.com/web-push-libs/webpush-java/wiki/Usage-Example implements the BASE64-decoding by using Base64.getDecoder() and not Base64.getUrlDecoder().
By the way: I believe that the constructors of Notification that use Base64.getUrlDecoder() and Utils.loadPublicKey don't work because of the usage of the URL-decoder. The example in https://github.com/web-push-libs/webpush-java/wiki/Usage-Example implements the BASE64-decoding by using Base64.getDecoder() and not Base64.getUrlDecoder().
Seems to me, after a lot of struggling, that both encodings actually need to be supported at this place: URL and non-URL.
Agreed with all the above. Just implemented this in my app and had lots of problems working out that there was a URL decoding scheme in place. Decided to go with 5.1.1 rather than 5.1.2 as could not get past the crypto-key error described above. Would be good if somebody could submit a PR.
Switching the encoding to AES128GCM instead of AESGCM does fix the problem. I can see two reasons for that:
- Firebase Cloud Messaging quietly removed support for the AESGCM-encoding
- FCM can't parse the Crypto-Key-Header, which for AESGCM-Endcoding looks like
dh=%BASE64_DH_KEY%;p256ecdsa=%BASE64_PUBLIC_KEY%instead of justp256ecdsa=%BASE64_PUBLIC_KEY%for AES128GCM.
I can't confirm what really happened, but as per rfc8291 AESGCM is not part of the standard, whilst AES128GCM is. Therefore, i think they dropped the legacy support for AESGCM, which they probably used before the PushAPI was actually standardized.