示例#1
0
        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));
        }
示例#2
0
        /// <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);
            }
        }
示例#3
0
        /// <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);
        }