diff --git a/src/BirdsiteLive.Domain/ActivityPubService.cs b/src/BirdsiteLive.Domain/ActivityPubService.cs index 7101c23..21ee7fd 100644 --- a/src/BirdsiteLive.Domain/ActivityPubService.cs +++ b/src/BirdsiteLive.Domain/ActivityPubService.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Net; using System.Net.Http; +using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; using BirdsiteLive.ActivityPub; @@ -88,9 +89,10 @@ namespace BirdsiteLive.Domain var date = DateTime.UtcNow.ToUniversalTime(); var httpDate = date.ToString("r"); - var signature = _cryptoService.SignAndGetSignatureHeader(date, actorUrl, targetHost, usedInbox); - + var digest = ComputeSha256Hash(json); + + var signature = _cryptoService.SignAndGetSignatureHeader(date, actorUrl, targetHost, digest, usedInbox); var client = new HttpClient(); var httpRequestMessage = new HttpRequestMessage @@ -101,7 +103,8 @@ namespace BirdsiteLive.Domain { {"Host", targetHost}, {"Date", httpDate}, - {"Signature", signature} + {"Signature", signature}, + {"Digest", $"SHA-256={digest}"} }, Content = new StringContent(json, Encoding.UTF8, "application/ld+json") }; @@ -109,5 +112,16 @@ namespace BirdsiteLive.Domain var response = await client.SendAsync(httpRequestMessage); return response.StatusCode; } + + static string ComputeSha256Hash(string rawData) + { + // Create a SHA256 + using (SHA256 sha256Hash = SHA256.Create()) + { + // ComputeHash - returns byte array + byte[] bytes = sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(rawData)); + return Convert.ToBase64String(bytes); + } + } } } \ No newline at end of file diff --git a/src/BirdsiteLive.Domain/CryptoService.cs b/src/BirdsiteLive.Domain/CryptoService.cs index ed62a59..837922e 100644 --- a/src/BirdsiteLive.Domain/CryptoService.cs +++ b/src/BirdsiteLive.Domain/CryptoService.cs @@ -7,7 +7,7 @@ namespace BirdsiteLive.Domain public interface ICryptoService { string GetUserPem(string id); - string SignAndGetSignatureHeader(DateTime date, string actor, string host, string inbox = null); + string SignAndGetSignatureHeader(DateTime date, string actor, string host, string digest, string inbox); } public class CryptoService : ICryptoService @@ -33,7 +33,7 @@ namespace BirdsiteLive.Domain /// in the form of https://domain.io/actor /// in the form of domain.io /// - public string SignAndGetSignatureHeader(DateTime date, string actor, string targethost, string inbox = null) + public string SignAndGetSignatureHeader(DateTime date, string actor, string targethost, string digest, string inbox) { var usedInbox = "/inbox"; if (!string.IsNullOrWhiteSpace(inbox)) @@ -41,12 +41,12 @@ namespace BirdsiteLive.Domain var httpDate = date.ToString("r"); - var signedString = $"(request-target): post {usedInbox}\nhost: {targethost}\ndate: {httpDate}"; + var signedString = $"(request-target): post {usedInbox}\nhost: {targethost}\ndate: {httpDate}\ndigest: SHA-256={digest}"; var signedStringBytes = Encoding.UTF8.GetBytes(signedString); var signature = _magicKeyFactory.GetMagicKey().Sign(signedStringBytes); var sig64 = Convert.ToBase64String(signature); - var header = "keyId=\"" + actor + "\",headers=\"(request-target) host date\",signature=\"" + sig64 + "\""; + var header = "keyId=\"" + actor + "\",algorithm=\"rsa-sha256\",headers=\"(request-target) host date digest\",signature=\"" + sig64 + "\""; return header; } }