Exemple #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()));
        }
Exemple #2
0
        /// <summary>
        /// Unlocks (i.e. decrypts) the archive with the given raw user secret.
        /// </summary>
        /// <param name="userSecret">The user secret to use to unlock the archive.</param>
        public void Unlock(RawUserSecret userSecret)
        {
            ArgCheck.NotNull(userSecret, nameof(userSecret));

            using var userKey = UserKey.DeriveFrom(
                      userSecret,
                      this.ArchiveMetadata.KeyDerivationSalt.ToArray(),
                      this.ArchiveMetadata.SecuritySettings);
            this.Unlock(userKey);
        }