Beispiel #1
0
 /// <inheritsdoc />
 public override int GetKeyWrapSize()
 {
     Debug.Assert(Algorithm != null);
     Debug.Assert(Algorithm.WrappedAlgorithm != null);
     Debug.Assert(Algorithm.WrappedAlgorithm.Category == AlgorithmCategory.Aes);
     return(AesKeyWrapper.GetKeyWrappedSize(EncryptionAlgorithm));
 }
Beispiel #2
0
        /// <inheritsdoc />
        public override SymmetricJwk WrapKey(Jwk?staticKey, JwtHeader header, Span <byte> destination)
        {
            if (header is null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.header);
            }

            var         contentEncryptionKey = CreateSymmetricKey(EncryptionAlgorithm, (SymmetricJwk?)staticKey);
            Span <byte> buffer = stackalloc byte[_saltSizeInBytes + 1 + _algorithmNameLength];

            _saltGenerator.Generate(buffer.Slice(_algorithmNameLength + 1));
            buffer[_algorithmNameLength] = 0x00;
            _algorithm.EncodedUtf8Bytes.CopyTo(buffer);

            Span <byte> derivedKey = stackalloc byte[_keySizeInBytes];

            Pbkdf2.DeriveKey(_password, buffer, _hashAlgorithm, _iterationCount, derivedKey);

            Span <byte> salt    = buffer.Slice(_algorithmNameLength + 1, _saltSizeInBytes);
            Span <byte> b64Salt = stackalloc byte[Base64Url.GetArraySizeRequiredToEncode(salt.Length)];

            Base64Url.Encode(salt, b64Salt);
            header.Add(JwtHeaderParameterNames.P2s, Utf8.GetString(b64Salt));
            header.Add(JwtHeaderParameterNames.P2c, _iterationCount);

            using var keyWrapper = new AesKeyWrapper(derivedKey, EncryptionAlgorithm, _keyManagementAlgorithm);
            return(keyWrapper.WrapKey(contentEncryptionKey, header, destination));
        }
Beispiel #3
0
        /// <inheritsdoc />
        public override SymmetricJwk WrapKey(Jwk?staticKey, JwtHeader header, Span <byte> destination)
        {
            if (header is null)
            {
                ThrowHelper.ThrowArgumentNullException(ExceptionArgument.header);
            }

            var contentEncryptionKey = CreateSymmetricKey(EncryptionAlgorithm, (SymmetricJwk?)staticKey);
            int bufferSize           = _saltSizeInBytes + _algorithmNameLength + 1;

            byte[]? bufferToReturn = null;
            Span <byte> buffer = bufferSize > Pbkdf2.SaltSizeThreshold + 18 + 1  // 18 = max alg name length
              ? (bufferToReturn = ArrayPool <byte> .Shared.Rent(bufferSize))
              : stackalloc byte[Pbkdf2.SaltSizeThreshold + 18 + 1];

            buffer = buffer.Slice(0, bufferSize);
            _saltGenerator.Generate(buffer.Slice(_algorithmNameLength + 1));
            buffer[_algorithmNameLength] = 0x00;
            _algorithm.EncodedUtf8Bytes.CopyTo(buffer);

            Span <byte> derivedKey = stackalloc byte[KeySizeThreshold].Slice(0, _keySizeInBytes);

            Pbkdf2.DeriveKey(_password, buffer, _hashAlgorithm, _iterationCount, derivedKey);

            Span <byte> salt          = buffer.Slice(_algorithmNameLength + 1, _saltSizeInBytes);
            int         saltLengthB64 = Base64Url.GetArraySizeRequiredToEncode(salt.Length);

            byte[]? arrayToReturn = null;
            Span <byte> b64Salt = saltLengthB64 > Pbkdf2.SaltSizeThreshold * 4 / 3
                ? (arrayToReturn = ArrayPool <byte> .Shared.Rent(saltLengthB64))
                : stackalloc byte[Pbkdf2.SaltSizeThreshold * 4 / 3];

            try
            {
                int length = Base64Url.Encode(salt, b64Salt);
                header.Add(JwtHeaderParameterNames.P2s, Utf8.GetString(b64Salt.Slice(0, saltLengthB64)));
                header.Add(JwtHeaderParameterNames.P2c, _iterationCount);

                using var keyWrapper = new AesKeyWrapper(derivedKey, EncryptionAlgorithm, _keyManagementAlgorithm);
                return(keyWrapper.WrapKey(contentEncryptionKey, header, destination));
            }
            finally
            {
                if (bufferToReturn != null)
                {
                    ArrayPool <byte> .Shared.Return(bufferToReturn);
                }

                if (arrayToReturn != null)
                {
                    ArrayPool <byte> .Shared.Return(arrayToReturn);
                }
            }
        }
Beispiel #4
0
        /// <inheritsdoc />
        public override int GetKeyWrapSize()
        {
            int size;
            var alg = Algorithm;

            if (alg.ProduceEncryptionKey)
            {
                var wrappedAlgorithm = alg.WrappedAlgorithm;
                if (wrappedAlgorithm is null)
                {
                    ThrowHelper.ThrowNotSupportedException_EncryptionAlgorithm(EncryptionAlgorithm);
                }

                size = wrappedAlgorithm.Category switch
                {
                    AlgorithmCategory.Aes => AesKeyWrapper.GetKeyWrappedSize(EncryptionAlgorithm),
#if SUPPORT_AES_GCM
                    AlgorithmCategory.AesGcm => AesGcmKeyWrapper.GetKeyWrapSize(EncryptionAlgorithm),
#endif
                    _ => throw ThrowHelper.CreateNotSupportedException_EncryptionAlgorithm(EncryptionAlgorithm)
                };
            }
            else
            {
                if (alg == KeyManagementAlgorithm.EcdhEs)
                {
                    size = _keySizeInBytes;
                }
                else
                {
#if SUPPORT_AES_GCM
                    if (EncryptionAlgorithm.Category == EncryptionType.AesGcm)
                    {
                        size = _keySizeInBytes + 8;
                    }
#endif
                    size = EncryptionAlgorithm.KeyWrappedSizeInBytes;
                }
            }

            return(size);
        }