HTTP Signatures are hard to digest (pun intended). The last thing I care about is follower count, but I need help

I am livestreaming ActivityPub development: https://www.twitch.tv/utdliyvlyuc

I hope that no human or computer will actually watch 9 hour videos to see the issue that I am running to, but am linking it because I want to see if the stars align by exercising some possibility that since I am currently almost every day actively streaming it, an expert who is also passionate about ActivityPub can clearly understand the issue that I am running into. Mostly HTTP Signature-related. Specifically the context is follow requests, both incoming and outgoing.

Here is a current opinion that I would rather not think about changing yet: As much as possible, I should rely on landrok/activitypub.

Therefore, when I am inspecting the incoming requests (my test case is Mastodon @ https://activitypub.academy, the code is looking like this:

$server = $activityPubRequest->activityPubServer();

$httpSignature = new HttpSignature($server);
$incomingRequest = \Symfony\Component\HttpFoundation\Request::create(
	$_SERVER['REQUEST_URI'],
	'POST',
	$_REQUEST, // parameters
	$_COOKIE, // cookies
	[], // files
	$_SERVER // $_SERVER,
);

error_log('test1');
error_log(print_r($_SERVER, true));
error_log('test2');
error_log(print_r($httpSignature, true));
error_log('test3');
error_log(print_r($httpSignature->verify($incomingRequest) ? 'yes' : 'why', true));
error_log(print_r('test23423423424', true));
exit('test2342342342');

$httpSignature->verify($incomingRequest) never seems to return true, only false. Of course I need to be able to verify signatures from 3rd party ActivityPub servers.

Now, posting this code is only somewhat relevant at all, due to the scope of this issue.

Despite my discomfort with streaming from some angles, I think the main reason I am posting this is with a hope that someone who is both an expert on the subject and happens to click on the stream at the right time (please do not watch any 9 hour videos for this), can help guide me in a good direction for signing HTTP requests and successfully processing follow requests.

I don’t have enough context to know if this is what you need (haven’t watched the videos), but HTTP signatures were a huge problem for me when I implemented them in Tapir too. Mastodon is very finicky about them, the signed text must include only a few specific headers in a particular order.

In the end, I only managed to get it working by copying Honk’s Go implementation of HTTP signatures. My TypeScript implementation here might help if you know JavaScript; it uses the browser-compatible Web Crypto API to perform RSA-SHA256.

If you want to stick with a third-party library, also be very careful that you’re using the right public key to verify the signature. A Mastodon user’s public key is on their Actor object, so verifying a signature on a message from that actor requires making at least one HTTP request to get the actor’s JSON-LD representation (and then probably caching the public key).

HTTP signatures are easy, actually. Here’s my known-working library-free implementation in Smithereen:

Yeah, a lot of developers have gotten HTTP Signatures working. I’ve never heard any issues about the order of the headers like arnelson mentioned, it should always just match the order you list the headers in the “headers” parameter.

Are you able to sign and verify your own signatures when communicating with your own server? If so, can you post that code?

Thanks so much for all the great input!

Straying from the original goal of using the landrok/activitypub library for as much as I could, I’ve instead removed some dependencies entirely including that one.

Signatures on incoming Inbox requests seem to be successfully verified here:

And the code behind the verify method is here:

When I try to send a signed outgoing Follow request (for example):

/instalution/lipupini/blob/v2.x/module/Lipupini/ActivityPub/Request/Follow.php#L55
/instalution/lipupini/blob/v2.x/module/Lipupini/ActivityPub/Request.php#L45
/instalution/lipupini/blob/v2.x/module/Lipupini/Request/Outgoing/Signature.php#L14

I think there’s still an issue with that, so it’s the next aspect to tackle.

Edit: The forum won’t let me paste more than two links, even from GitHub

1 Like