/// <inheritdoc /> /// <exception cref="ArgumentNullException" /> public string Encode(IDictionary <string, object> extraHeaders, object payload, byte[] key) { if (payload is null) { throw new ArgumentNullException(nameof(payload)); } var segments = new List <string>(3); var header = extraHeaders is null ? new Dictionary <string, object>(StringComparer.OrdinalIgnoreCase) : extraHeaders; header.Add("typ", "JWT"); header.Add("alg", _algorithm.Name); var headerBytes = GetBytes(_jsonSerializer.Serialize(header)); var payloadBytes = GetBytes(_jsonSerializer.Serialize(payload)); segments.Add(_urlEncoder.Encode(headerBytes)); segments.Add(_urlEncoder.Encode(payloadBytes)); var stringToSign = String.Join(".", segments.ToArray()); var bytesToSign = GetBytes(stringToSign); var signature = _algorithm.Sign(key, bytesToSign); segments.Add(_urlEncoder.Encode(signature)); return(String.Join(".", segments.ToArray())); }
/// <inheritdoc /> /// <exception cref="ArgumentNullException" /> public string Encode(IDictionary <string, object> extraHeaders, object payload, byte[] key) { if (payload is null) { throw new ArgumentNullException(nameof(payload)); } if (!_algorithm.IsAsymmetric() && key is null) { throw new ArgumentNullException(nameof(key)); } var header = extraHeaders is null ? new Dictionary <string, object>(2, StringComparer.OrdinalIgnoreCase) : new Dictionary <string, object>(extraHeaders, StringComparer.OrdinalIgnoreCase); if (!header.ContainsKey("typ")) { header.Add("typ", "JWT"); } header.Add("alg", _algorithm.Name); var headerBytes = GetBytes(_jsonSerializer.Serialize(header)); var payloadBytes = GetBytes(_jsonSerializer.Serialize(payload)); var headerSegment = _urlEncoder.Encode(headerBytes); var payloadSegment = _urlEncoder.Encode(payloadBytes); var stringToSign = headerSegment + "." + payloadSegment; var bytesToSign = GetBytes(stringToSign); var signature = _algorithm.Sign(key, bytesToSign); var signatureSegment = _urlEncoder.Encode(signature); return(stringToSign + "." + signatureSegment); }
/// <inheritdoc /> /// <exception cref="ArgumentNullException" /> /// <exception cref="ArgumentOutOfRangeException" /> public string Encode(IDictionary <string, object> extraHeaders, object payload, byte[] key) { if (payload == null) { throw new ArgumentNullException(nameof(payload)); } if (key == null) { throw new ArgumentNullException(nameof(key)); } if (key.Length == 0) { throw new ArgumentOutOfRangeException(nameof(key)); } var segments = new List <string>(3); var header = extraHeaders != null ? new Dictionary <string, object>(extraHeaders) : new Dictionary <string, object>(); header.Add("typ", "JWT"); header.Add("alg", _algorithm.Name); var headerBytes = Encoding.UTF8.GetBytes(_jsonSerializer.Serialize(header)); var payloadBytes = Encoding.UTF8.GetBytes(_jsonSerializer.Serialize(payload)); segments.Add(_urlEncoder.Encode(headerBytes)); segments.Add(_urlEncoder.Encode(payloadBytes)); var stringToSign = string.Join(".", segments.ToArray()); var bytesToSign = Encoding.UTF8.GetBytes(stringToSign); var signature = _algorithm.Sign(key, bytesToSign); segments.Add(_urlEncoder.Encode(signature)); return(string.Join(".", segments.ToArray())); }
/// <inheritdoc /> public string Encode(IDictionary <string, object> extraHeaders, object payload, byte[] key) { var segments = new List <string>(3); var header = extraHeaders != null ? new Dictionary <string, object>(extraHeaders) : new Dictionary <string, object>(); header.Add("typ", "JWT"); header.Add("alg", _algorithm.Name); var headerBytes = Encoding.UTF8.GetBytes(_jsonSerializer.Serialize(header)); var payloadBytes = Encoding.UTF8.GetBytes(_jsonSerializer.Serialize(payload)); segments.Add(JsonWebToken.Base64UrlEncode(headerBytes)); segments.Add(JsonWebToken.Base64UrlEncode(payloadBytes)); var stringToSign = string.Join(".", segments.ToArray()); var bytesToSign = Encoding.UTF8.GetBytes(stringToSign); var signature = _algorithm.Sign(key, bytesToSign); segments.Add(JsonWebToken.Base64UrlEncode(signature)); return(string.Join(".", segments.ToArray())); }
public void Write(ReadOnlySpan <byte> payload) { // to avoid payload copy, write all data in this place. // make new payload.... byte[] newPayloadArray = null; try { if (expire != null) { newPayloadArray = ArrayPool <byte> .Shared.Rent(payload.Length + 8 + 20); // ,"exp":} + maxint-size var newPayload = newPayloadArray.AsSpan(); payload.CopyTo(newPayload); newPayload = newPayload.Slice(payload.Length - 1); // except } int expLength; if (payload.Length == 0 || payload.Length == 2) // {} { expKey.CopyTo(newPayload); newPayload = newPayload.Slice(expKey.Length); expLength = expKey.Length; } else { expKeyWithComma.CopyTo(newPayload); newPayload = newPayload.Slice(expKeyWithComma.Length); expLength = expKeyWithComma.Length; } var writeLength = NumberConverter.WriteInt64(newPayload, 0, expire.Value); newPayload = newPayload.Slice(writeLength); newPayload[0] = (byte)'}'; payload = newPayloadArray.AsSpan(0, payload.Length + writeLength + expLength); } var headerBase64 = algorithm.HeaderBase64Url; byte[] rentByte = null; var payloadEncodedLength = Base64.GetBase64UrlEncodeLength(payload.Length); if (payloadEncodedLength > 1024) { rentByte = ArrayPool <byte> .Shared.Rent(payloadEncodedLength); } try { Span <byte> payloadBase64 = (rentByte != null) ? rentByte.AsSpan(0, payloadEncodedLength) : stackalloc byte[payloadEncodedLength]; Base64.TryToBase64UrlUtf8(payload, payloadBase64, out _); // We can compute final size, so GetSpan only once. // hedaer . payload . signature var length = headerBase64.Length + payloadBase64.Length + 2 + Base64.GetBase64UrlEncodeLength(algorithm.HashSize); var finalBuffer = writer.GetSpan(length); headerBase64.CopyTo(finalBuffer); dot.CopyTo(finalBuffer.Slice(headerBase64.Length)); payloadBase64.CopyTo(finalBuffer.Slice(headerBase64.Length + 1)); dot.CopyTo(finalBuffer.Slice(headerBase64.Length + 1 + payloadBase64.Length)); Span <byte> signature = stackalloc byte[algorithm.HashSize]; algorithm.Sign(finalBuffer.Slice(0, headerBase64.Length + 1 + payloadBase64.Length), signature); Base64.TryToBase64UrlUtf8(signature, finalBuffer.Slice(headerBase64.Length + 2 + payloadBase64.Length), out _); writer.Advance(length); } finally { if (rentByte != null) { ArrayPool <byte> .Shared.Return(rentByte); } } } finally { if (newPayloadArray != null) { ArrayPool <byte> .Shared.Return(newPayloadArray); } } }