Exemplo n.º 1
0
        /// <summary>
        /// Derives a <see cref="UserKey"/> from the input user secret.
        /// </summary>
        /// <param name="userSecret">The secret used to derive the key.</param>
        /// <param name="keyDerivationSalt">The salt used to derive the key.</param>
        /// <param name="securitySettings">Security parameters for the <see cref="SecureArchive"/>.</param>
        public static UserKey DeriveFrom(
            RawUserSecret userSecret,
            ReadOnlySpan <byte> keyDerivationSalt,
            SecuritySettings securitySettings)
        {
            ArgCheck.NotNull(userSecret, nameof(userSecret));
            ArgCheck.NotEmpty(keyDerivationSalt, nameof(keyDerivationSalt));
            ArgCheck.IsValid(securitySettings, nameof(securitySettings));

            var cryptoAlgoProperties = EncryptionAlgoProperties.For(securitySettings.EncryptionAlgo);

            // We'll use the user secret to derive the user key as well as the key ID.
            // The algorithm is:
            //   let N be the number of bytes for the key
            //   let M be the number of bytes for the keyId
            //   keyMatter := Derive N + M bytes from the secret using the KDF
            //   key := keyMatter[0..N-1]
            //   keyId := base64url(keyMatter[N..])
            var keyDerivationStrategy = CryptoHelpers.GetKeyDerivationStrategy(securitySettings.KeyDerivationFunction);
            var keyMatter             = keyDerivationStrategy.DeriveKeyMatter(
                cryptoAlgoProperties.KeySizeInBytes + securitySettings.KeyIdSizeInBytes,
                userSecret.Key,
                keyDerivationSalt,
                securitySettings.KeyDerivationWorkFactor);

            var key   = keyMatter.Slice(0, cryptoAlgoProperties.KeySizeInBytes);
            var keyId = Helpers.Base64UrlEncode(keyMatter.Slice(cryptoAlgoProperties.KeySizeInBytes));

            return(new UserKey(keyId, key.ToArray()));
        }
Exemplo n.º 2
0
        /// <summary>
        /// Creates a new symmetric <see cref="ArchiveKey"/> that can be used with the
        /// algorithms described in the given <see cref="SecuritySettings"/>.
        /// </summary>
        /// <param name="securitySettings">The <see cref="SecuritySettings"/> for the archive.</param>
        /// <returns>The new <see cref="ArchiveKey"/>.</returns>
        public static ArchiveKey CreateNew(SecuritySettings securitySettings)
        {
            ArgCheck.IsValid(securitySettings, nameof(securitySettings));

            var numKeyBytes = EncryptionAlgoProperties.For(securitySettings.EncryptionAlgo).KeySizeInBytes;

            return(new ArchiveKey(CryptoHelpers.GetRandomBytes(numKeyBytes)));
        }