public override Jwk WrapKey(Jwk?staticKey, JwtObject header, Span <byte> destination) { if (staticKey != null) { ThrowHelper.ThrowArgumentException_StaticKeyNotSupported(); } ReadOnlySpan <byte> bytes = Key.AsSpan(); return(SymmetricJwk.FromSpan(bytes, false)); }
/// <inheritsdoc /> public override bool TryUnwrapKey(ReadOnlySpan <byte> keyBytes, Span <byte> destination, JwtHeader header, out int bytesWritten) { if (_disposed) { ThrowHelper.ThrowObjectDisposedException(GetType()); } var epk = header.Epk; if (epk is null) { ThrowHelper.ThrowJwtDescriptorException_HeaderIsRequired(HeaderParameters.EpkUtf8); } byte[] secretAppend = BuildSecretAppend(header.Apu, header.Apv); byte[] exchangeHash; using (var ephemeralKey = ECDiffieHellman.Create(epk.ExportParameters())) using (var privateKey = ECDiffieHellman.Create(((ECJwk)Key).ExportParameters(true))) { if (ephemeralKey.KeySize != privateKey.KeySize) { return(ThrowHelper.TryWriteError(out bytesWritten)); } exchangeHash = privateKey.DeriveKeyFromHash(ephemeralKey.PublicKey, _hashAlgorithm, _secretPreprend, secretAppend); } if (Algorithm.ProduceEncryptionKey) { using var key = SymmetricJwk.FromSpan(new ReadOnlySpan <byte>(exchangeHash, 0, _keySizeInBytes), false); if (key.TryGetKeyUnwrapper(EncryptionAlgorithm, Algorithm.WrappedAlgorithm, out var keyUnwrapper)) { return(keyUnwrapper.TryUnwrapKey(keyBytes, destination, header, out bytesWritten)); } else { return(ThrowHelper.TryWriteError(out bytesWritten)); } } else { new ReadOnlySpan <byte>(exchangeHash, 0, _keySizeInBytes).CopyTo(destination); bytesWritten = destination.Length; return(true); } }
/// <inheritsdoc /> public override SymmetricJwk WrapKey(Jwk?staticKey, JwtHeader header, Span <byte> destination) { Debug.Assert(header != null); var partyUInfo = GetPartyInfo(header, JwtHeaderParameterNames.Apu); var partyVInfo = GetPartyInfo(header, JwtHeaderParameterNames.Apv); var secretAppend = BuildSecretAppend(partyUInfo, partyVInfo); ReadOnlySpan <byte> exchangeHash; var ecKey = _key; var otherPartyKey = ecKey.CreateEcdhKey(); ECDiffieHellman ephemeralKey = (staticKey is null) ? ECDiffieHellman.Create(ecKey.Crv.CurveParameters) : ((ECJwk)staticKey).CreateEcdhKey(); try { exchangeHash = new ReadOnlySpan <byte>(ephemeralKey.DeriveKeyFromHash(otherPartyKey.PublicKey, _hashAlgorithm, _secretPreprend, secretAppend), 0, _keySizeInBytes); var epk = ECJwk.FromParameters(ephemeralKey.ExportParameters(false)); header.Add(JwtHeaderParameterNames.Epk, epk); } finally { if (staticKey is null) { ephemeralKey.Dispose(); } } SymmetricJwk contentEncryptionKey; if (Algorithm.ProduceEncryptionKey) { using var keyWrapper = new AesKeyWrapper(exchangeHash, EncryptionAlgorithm, _keyManagementAlgorithm !); contentEncryptionKey = keyWrapper.WrapKey(null, header, destination); } else { exchangeHash.CopyTo(destination); contentEncryptionKey = SymmetricJwk.FromSpan(exchangeHash, false); } return(contentEncryptionKey); }