hs2019 signatures hashed with SHA-512, and SHA-512 digests
A draft-cavage hs2019 signature leaves the hash to the key: with an RSA key it is tried with SHA-256, as nearly everyone signs, then with SHA-512, as some do; rsa-sha256 stays SHA-256 only. A Digest of SHA-512= is checked as SHA-256= is. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LsXgEaXee4GCU1hwYgPJXw
This commit is contained in:
1 parent
0310bbe0f9
commit
e708f1ad2e
5 files changed
+39
-7
No files matched your search
@@ -152,9 +152,11 @@ namespace PrivaPub.Federation.Signing
|
||||
{
|
||||
if (!parameters.Headers.Contains("digest"))
|
||||
return "the digest is not signed";
|
||||
var expectedHash = Convert.ToBase64String(SHA256.HashData(body));
|
||||
var sha256 = Convert.ToBase64String(SHA256.HashData(body));
|
||||
var sha512 = Convert.ToBase64String(SHA512.HashData(body));
|
||||
var matches = request.Headers["Digest"].ToString().Split(',').Select(d => d.Trim())
|
||||
.Any(d => d.StartsWith("SHA-256=", StringComparison.OrdinalIgnoreCase) && d[8..] == expectedHash);
|
||||
.Any(d => d.StartsWith("SHA-256=", StringComparison.OrdinalIgnoreCase) && d[8..] == sha256
|
||||
|| d.StartsWith("SHA-512=", StringComparison.OrdinalIgnoreCase) && d[8..] == sha512);
|
||||
if (!matches)
|
||||
return "the digest does not match the body";
|
||||
}
|
||||
@@ -213,7 +215,8 @@ namespace PrivaPub.Federation.Signing
|
||||
return string.IsNullOrEmpty(raw) || raw[0] != '/' ? $"{request.PathBase}{request.Path}{request.QueryString}" : raw;
|
||||
}
|
||||
|
||||
public static bool Verify(string publicKeyPem, string signingString, byte[] signature)
|
||||
// hs2019 leaves the hash to the key: RSA with SHA-256, as nearly everyone signs, else with SHA-512, as some do
|
||||
public static bool Verify(string publicKeyPem, string signingString, byte[] signature, string algorithm = "rsa-sha256")
|
||||
{
|
||||
if (string.IsNullOrEmpty(publicKeyPem) || signingString == null)
|
||||
return false;
|
||||
@@ -221,8 +224,9 @@ namespace PrivaPub.Federation.Signing
|
||||
{
|
||||
using var rsa = RSA.Create();
|
||||
rsa.ImportFromPem(publicKeyPem);
|
||||
return rsa.VerifyData(Encoding.UTF8.GetBytes(signingString), signature,
|
||||
HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
|
||||
var data = Encoding.UTF8.GetBytes(signingString);
|
||||
return rsa.VerifyData(data, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1)
|
||||
|| algorithm == "hs2019" && rsa.VerifyData(data, signature, HashAlgorithmName.SHA512, RSASignaturePadding.Pkcs1);
|
||||
}
|
||||
catch (CryptographicException)
|
||||
{
|
||||
|
||||
@@ -40,6 +40,6 @@ namespace PrivaPub.Federation.Signing
|
||||
_message != default ? MessageSignatures.Base(request, _message, baseAddress) : HttpSignatures.SigningString(request, _cavage);
|
||||
|
||||
public bool VerifiedBy(string publicKeyPem, string signed) =>
|
||||
_message != default ? MessageSignatures.Verify(publicKeyPem, _message, signed) : HttpSignatures.Verify(publicKeyPem, signed, _cavage.Signature);
|
||||
_message != default ? MessageSignatures.Verify(publicKeyPem, _message, signed) : HttpSignatures.Verify(publicKeyPem, signed, _cavage.Signature, _cavage.Algorithm);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user