-
-
Save it-can/f237f84dd4e115b4628be10233f2c138 to your computer and use it in GitHub Desktop.
| <?php | |
| // Retrieve the signature from the request headers and decode it from base64 | |
| $signature_base64 = $request->header('X-MailPace-Signature'); | |
| $signature = base64_decode($signature_base64); | |
| if ($signature === false) { | |
| // Invalid signature encoding | |
| abort(400, 'Invalid signature encoding'); | |
| } | |
| // Decode your public key from base64 | |
| $verify_key_base64 = 'Your Public Key from app.mailpace.com here'; | |
| $verify_key = base64_decode($verify_key_base64); | |
| if ($verify_key === false) { | |
| // Invalid public key encoding | |
| abort(500, 'Invalid public key encoding'); | |
| } | |
| // Retrieve the raw body of the request | |
| $message = $request->getContent(); | |
| // Verify the signature | |
| $isValid = sodium_crypto_sign_verify_detached($signature, $message, $verify_key); | |
| if ($isValid) { | |
| // Verification passed | |
| return response('Verification passed', 200); | |
| } else { | |
| // Verification failed | |
| abort(400, 'Invalid signature'); | |
| } |
@paul-oms seems this is not working (the signature from the header) with strict set to true in base64_decode (https://www.php.net/base64_decode).
$message = '';
$signature = base64_decode("sHnRyHCzMpHhMrWT5\/GynEWzryRQG7FvWcCvvKHjDWV6r+\/X+OzG4YMpua78I7CYh+qC3hK9xXZlYHePZHopCg==", true);
$verify_key = base64_decode('private-key', true);
$isValid = sodium_crypto_sign_verify_detached($signature, $message, $verify_key);
this gives me an error:
sodium_crypto_sign_verify_detached(): Argument #1 ($signature) must be SODIUM_CRYPTO_SIGN_BYTES bytes long
EDIT:
seems not to happen on all signature headers... strange
EDIT2:
I removed the strict parameter from base64_decode, and it seems to work now
strict decode should work on the signature. However I think I've found the root cause. It looks like Laravel (or something in the stack) automatically converts Unicode escape sequences when getContent() is called. So e.g. "message_id":"\[email protected]\u003e" is converted to "message_id":"<[email protected]>"
This won't match the original email we sign on our end, therefore preventing the signatures from matching - i'm checking for a way to get the original request without this
Looks like this should work:
$message = json_encode($response->getOriginalContent(), JSON_HEX_TAG);
Try that and let me know if you still face problems
Ok will test it out thanks for now!