-
-
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!