(feature): JwsGenerator support for ACME extended JwsHeader
This commit is contained in:
parent
c6f7e47240
commit
9f9d5fc474
40
README.md
40
README.md
@ -1034,6 +1034,9 @@ The `JwsGenerator` class in the `MaksIT.Core.Security.JWS` namespace provides me
|
||||
1. **JWS Creation**:
|
||||
- Sign string or object payloads using an RSA key and JWK.
|
||||
- Produces a JWS message containing the protected header, payload, and signature.
|
||||
- Supports generic protected header and payload types.
|
||||
- Automatically sets the `Algorithm` property to `RS256` in the protected header.
|
||||
- Sets either the `KeyId` or the full `Jwk` in the protected header, depending on the presence of `KeyId`.
|
||||
|
||||
---
|
||||
|
||||
@ -1045,7 +1048,7 @@ using MaksIT.Core.Security.JWK;
|
||||
using MaksIT.Core.Security.JWS;
|
||||
|
||||
using var rsa = RSA.Create(2048);
|
||||
JwkGenerator.TryGenerateFromRCA(rsa, out var jwk, out var errorMessage);
|
||||
JwkGenerator.TryGenerateFromRSA(rsa, out var jwk, out var errorMessage);
|
||||
var header = new JwsHeader();
|
||||
var payload = "my-payload";
|
||||
var result = JwsGenerator.TryEncode(rsa, jwk!, header, payload, out var jwsMessage, out var error);
|
||||
@ -1064,34 +1067,35 @@ else
|
||||
#### API
|
||||
|
||||
```csharp
|
||||
public static bool TryEncode(
|
||||
public static bool TryEncode<THeader>(
|
||||
RSA rsa,
|
||||
Jwk jwk,
|
||||
JwsHeader protectedHeader,
|
||||
[NotNullWhen(true)]out JwsMessage? message,
|
||||
[NotNullWhen(false)] out string? errorMessage
|
||||
)
|
||||
```
|
||||
- Signs an empty payload.
|
||||
|
||||
```csharp
|
||||
public static bool TryEncode<T>(
|
||||
RSA rsa,
|
||||
Jwk jwk,
|
||||
JwsHeader protectedHeader,
|
||||
T? payload,
|
||||
THeader protectedHeader,
|
||||
[NotNullWhen(true)] out JwsMessage? message,
|
||||
[NotNullWhen(false)] out string? errorMessage
|
||||
)
|
||||
) where THeader : JwsHeader
|
||||
```
|
||||
- Signs the provided payload (string or object).
|
||||
- Signs an empty payload with a generic protected header.
|
||||
|
||||
```csharp
|
||||
public static bool TryEncode<THeader, TPayload>(
|
||||
RSA rsa,
|
||||
Jwk jwk,
|
||||
THeader protectedHeader,
|
||||
TPayload? payload,
|
||||
[NotNullWhen(true)] out JwsMessage? message,
|
||||
[NotNullWhen(false)] out string? errorMessage
|
||||
) where THeader : JwsHeader
|
||||
```
|
||||
- Signs the provided payload (string or object) with a generic protected header.
|
||||
|
||||
---
|
||||
|
||||
#### Notes
|
||||
- Only supports signing (no verification or key authorization).
|
||||
- The protected header is automatically set to use RS256.
|
||||
- The payload is base64url encoded.
|
||||
- If the JWK has a `KeyId`, it is set in the header; otherwise, the full JWK is included.
|
||||
- The payload is base64url encoded (as a string or JSON).
|
||||
- Returns `false` and an error message if signing fails.
|
||||
|
||||
---
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
<!-- NuGet package metadata -->
|
||||
<PackageId>MaksIT.Core</PackageId>
|
||||
<Version>1.5.8</Version>
|
||||
<Version>1.5.9</Version>
|
||||
<Authors>Maksym Sadovnychyy</Authors>
|
||||
<Company>MAKS-IT</Company>
|
||||
<Product>MaksIT.Core</Product>
|
||||
|
||||
@ -37,19 +37,26 @@ public static class JwkThumbprintUtility {
|
||||
) {
|
||||
thumbprint = null;
|
||||
errorMessage = null;
|
||||
|
||||
try {
|
||||
if (jwk.RsaExponent == null || jwk.RsaModulus == null)
|
||||
throw new ArgumentException("RSA exponent or modulus is null.");
|
||||
|
||||
var thumbprintObj = new OrderedJwk {
|
||||
E = jwk.RsaExponent,
|
||||
Kty = JwkKeyType.Rsa.Name,
|
||||
N = jwk.RsaModulus
|
||||
};
|
||||
|
||||
var json = thumbprintObj.ToJson();
|
||||
|
||||
thumbprint = Base64UrlUtility.Encode(SHA256.HashData(Encoding.UTF8.GetBytes(json)));
|
||||
|
||||
return true;
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
catch (Exception ex) {
|
||||
errorMessage = ex.Message;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,23 +8,24 @@ using MaksIT.Core.Extensions;
|
||||
namespace MaksIT.Core.Security.JWS;
|
||||
|
||||
public static class JwsGenerator {
|
||||
public static bool TryEncode(
|
||||
public static bool TryEncode<THeader>(
|
||||
RSA rsa,
|
||||
Jwk jwk,
|
||||
JwsHeader protectedHeader,
|
||||
THeader protectedHeader,
|
||||
[NotNullWhen(true)] out JwsMessage? message,
|
||||
[NotNullWhen(false)] out string? errorMessage
|
||||
) => TryEncode<string>(rsa, jwk, protectedHeader, null, out message, out errorMessage);
|
||||
) where THeader : JwsHeader =>
|
||||
TryEncode<THeader, string>(rsa, jwk, protectedHeader, null, out message, out errorMessage);
|
||||
|
||||
|
||||
public static bool TryEncode<T>(
|
||||
public static bool TryEncode<THeader, TPayload>(
|
||||
RSA rsa,
|
||||
Jwk jwk,
|
||||
JwsHeader protectedHeader,
|
||||
T? payload,
|
||||
THeader protectedHeader,
|
||||
TPayload? payload,
|
||||
[NotNullWhen(true)] out JwsMessage? message,
|
||||
[NotNullWhen(false)] out string? errorMessage
|
||||
) {
|
||||
) where THeader : JwsHeader {
|
||||
try {
|
||||
protectedHeader.Algorithm = JwkAlgorithm.Rs256.Name;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user