Testing HttpSignatures (mastodon)

Yeah exactly as I suspected.

And this isn’t a public key, it’s a certificate. You’re supposed to generate an RSA key pair.

good morning,
for this testcase i generate the keyPair in my Controller Class like that:

import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

private static String privateKey;
private static String publicKey;

static {
	try {
		KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
		kpg.initialize(2048);
		KeyPair kp = kpg.generateKeyPair();
		
		Base64.Encoder encoder = Base64.getEncoder();
		StringBuilder sb = new StringBuilder();
		sb.append("-----BEGIN RSA PRIVATE KEY-----\n");
		sb.append(encoder.encodeToString(kp.getPrivate().getEncoded()));
		sb.append("\n-----END RSA PRIVATE KEY-----\n");
		privateKey = sb.toString();
		
		sb = new StringBuilder();
		sb.append("-----BEGIN RSA PUBLIC KEY-----\n");
		sb.append(encoder.encodeToString(kp.getPublic().getEncoded()));
		sb.append("\n-----END RSA PUBLIC KEY-----\n");
		publicKey = sb.toString();
	} catch (NoSuchAlgorithmException e) {
		throw new RuntimeException(e);
	}	
}

Unhandled exception</h1><pre>org.json.JSONException: Unterminated string at 417 [character 0 line 16]

I have to switch of the server because of my ressources. Please send me a message, if i should start it.

You aren’t using a json library, are you? So, do publicKey.replace("\n", "\\n") while adding the key to the json string.

1 Like

ok, now.
Bad request: java.lang.StringIndexOutOfBoundsException: String index out of range: 0

Show me your signature header. Or I could enable additional logging on my side.

(I need to handle errors better, too)

I’m not sure, if i understand you
Signature - [Qp3j8go0xK2xSeGkBwpfvP3cyjfQACLvemQQTzqyTnM=]
digest - [SHA-256=ANFl5Jso9ixM2+G+KXGz/eRg16ED+3J2ZZz6yDf34vE=]
Host - [friends.grishka.me]
Date - [Mon, 17 May 2021 13:34:58 GMT]

It’s supposed to be a key-value thing, like this

Signature: keyId="http://smithereen.local:8080/users/1#main-key",headers="(request-target) host date digest",algorithm="rsa-sha256",signature="hfB6do4LmGgD2Fi7+tNcscy1hYbuC3/AAcRbOpLaBLPq3mv30Vq472Z0eXYVfkptDiP+zB80ZzoKUuv+bATTzUaLJePFCf7rbSekUvbSECoBCIvjoEYVwgPPyoRd+s4m8UJGtewad7u+Ftk9BnEmXduc8lUrxzv0I6H+WfxceN4VUERwgDvDQa31pyeXWRpsK9zZ2eIW4oOR7EQ21MFEt1QvV4OYGj0nQ79r+SXUaJxI7TKcIkyx3qqzgHLUxmLkbyU9wLfTpiKy+J4B6NGjSrOMEa9Na82+rsn0oefIj5cpE7gPH32MBasAbC0+I8m5Hd17HD5xnEm0ELeNjta1NQ=="

I have no idea! The description of the library says:

"The returned Signature object represents a full HTTP Signature. Simply call toString() on it to get a fully formatted Authorization header value."

There is no mention of a header attribute Signature.
I have adapted this anyway and also filled the Authorization header.

Now it’s:

Authorization - [Signature keyId="https://naturzukunft.ddnss.de/key",created=1621264456,algorithm="hmac-sha256",headers="digest host date (request-target)",signature="4P0BA77xUg0mwzlaH4Wtf8RaUE3MlfklejiqzecXAsQ="]
Signature - [keyId="https://naturzukunft.ddnss.de/key",created=1621264456,algorithm="hmac-sha256",headers="digest host date (request-target)",signature="4P0BA77xUg0mwzlaH4Wtf8RaUE3MlfklejiqzecXAsQ="]
digest - [SHA-256=ANFl5Jso9ixM2+G+KXGz/eRg16ED+3J2ZZz6yDf34vE=]
Host - [friends.grishka.me]
Date - [Mon, 17 May 2021 15:14:16 GMT]

Error:

<400,Bad request: smithereen.exceptions.ObjectNotFoundException: Can't resolve remote object: https://naturzukunft.ddnss.de,[Server:"nginx/1.16.1", Date:"Mon, 17 May 2021 15:26:23 GMT", Content-Type:"text/html;charset=utf-8", Transfer-Encoding:"chunked", Connection:"keep-alive", Set-Cookie:"JSESSIONID=node086q4ruywoty41ez4s2klfh59a7584.node0;Path=/;HttpOnly", Expires:"Thu, 01 Jan 1970 00:00:00 GMT"]>

Okay, try changing your keyId to something like https://naturzukunft.ddnss.de/actor#main-key… That’s kinda my laziness because I don’t really support arbitrary key IDs.

I tried to add a second representation, not sure if it is as you like.
Get: 400,Bad request: java.lang.IllegalArgumentException: Signature failed to verify

Okay, you’ve got further this time. I see this in my log:

Failed sig: keyId="https://naturzukunft.ddnss.de/actor#main-key",created=1621268496,algorithm="hs2019",headers="digest host date (request-target)",signature="h2AAAX3Eq0qtFG7QTUI2b7sIOZKBqwCSRUDlT4Il7W7YJxtZ3XEo5nuvhcs+hzy7MDBcfYcCxAWQNRkmJGzWoFW2uW5rjBrrD+e6qay+fhQruODkRV9J5FCHtp9WXOu3ACmFcpuz/mtLbvVrk/Ahf2cdV9Ie1DX7Yn5vZSJSw1546igQw6kvHxcomHGGuCO0YGtYbkfq3GfM29hmMTAnryT2W/gZXf2LkYFsGM5d9qoAOP5GUIKVgzz6t9hO18u/823nXEKetqbyQD+3G7TQ8eFuW64Ha+IsfZkRhfDsUevG7f9QmFPH3guchRxpxTU7Z7QKFR0uI6tmVxjnDRJseQ=="

Failed sig string: 'digest: SHA-256=ANFl5Jso9ixM2+G+KXGz/eRg16ED+3J2ZZz6yDf34vE=
host: friends.grishka.me
date: Mon, 17 May 2021 16:21:36 GMT
(request-target): post /activitypub/sharedInbox'

algorithm=“hs2019”

I honestly have no idea what this is. It’s supposed to be “rsa-sha256”. I should really be checking this and returning an appropriate error.

ah, i was changing that, because in the meanwhile i again “fired” against mastodon and they told me, that my algorithm is not supported. so i switched to “RSA_SHA256”, but there was a still a wrong peace.
I removed that " hs2019 now. can you check again ?

It’s again failed to verify. I suppose you just aren’t generating it correctly. As there’s hashing involved, it’s important that there’s a bit-exact match between the strings on both sides.

(I added the check for algorithm btw)

The order is also important. The headers in the string you sign have to be in the same order they are in the headers parameter.

“(request-target)” should also be a header attribute ?

Uh. Could you please read the tutorial, my code that generates valid signatures, or both?

1 Like

In your code the host is not in the header right ?

In the tutorial it is:

HTTP.headers({ 'Host': 'mastodon.social', 'Date': date, 'Signature': header })
    .post('https://mastodon.social/inbox', body: document)

Isn’t it necessary ?

Puh, i replaced now the httpPost and the signing with your code with minimum changes.

But still get an error
Bad request: java.lang.IllegalArgumentException: Signature failed to verify

The call is here

I tried to verify the generated request before sending it. This is indeed a very dirty hack. The result is

Failed sig string: '(request-target): post https://friends.grishka.me/activitypub/sharedInbox

I don’t understand where the full path comes from, but I think in the request we just write the path /activitypub/sharedInbox.

Do you have the same error in the server log?

Fredy