コード例 #1
0
        public async Task <IdentityResult> ChangeKdfAsync(User user, string masterPassword, string newMasterPassword,
                                                          string key, KdfType kdf, int kdfIterations)
        {
            if (user == null)
            {
                throw new ArgumentNullException(nameof(user));
            }

            if (await CheckPasswordAsync(user, masterPassword))
            {
                var result = await UpdatePasswordHash(user, newMasterPassword);

                if (!result.Succeeded)
                {
                    return(result);
                }

                user.RevisionDate  = user.AccountRevisionDate = DateTime.UtcNow;
                user.Key           = key;
                user.Kdf           = kdf;
                user.KdfIterations = kdfIterations;
                await _userRepository.ReplaceAsync(user);

                await _pushService.PushLogOutAsync(user.Id);

                return(IdentityResult.Success);
            }

            Logger.LogWarning("Change KDF failed for user {userId}.", user.Id);
            return(IdentityResult.Failed(_identityErrorDescriber.PasswordMismatch()));
        }
コード例 #2
0
        public SymmetricCryptoKey MakeKeyFromPassword(string password, string salt, KdfType kdf, int kdfIterations)
        {
            if (password == null)
            {
                throw new ArgumentNullException(nameof(password));
            }

            if (salt == null)
            {
                throw new ArgumentNullException(nameof(salt));
            }

            var passwordBytes = Encoding.UTF8.GetBytes(NormalizePassword(password));
            var saltBytes     = Encoding.UTF8.GetBytes(salt);

            byte[] keyBytes = null;
            if (kdf == KdfType.PBKDF2)
            {
                if (kdfIterations < 5000)
                {
                    throw new Exception("PBKDF2 iteration minimum is 5000.");
                }
                keyBytes = _keyDerivationService.DeriveKey(passwordBytes, saltBytes, (uint)kdfIterations);
            }
            else
            {
                throw new Exception("Unknown Kdf.");
            }
            return(new SymmetricCryptoKey(keyBytes));
        }
コード例 #3
0
        public static string WriteToFile(string fileDirectory, Wallet wallet, KdfType kdfType)
        {
            if (wallet?.KeyPairs == null || wallet.KeyPairs.Count != 1)
            {
                throw new NotSupportedException("This function expects a wallet with a single address");
            }

            FileAttributes attributes = File.GetAttributes(fileDirectory);

            if (!attributes.HasFlag(FileAttributes.Directory))
            {
                throw new InvalidOperationException("The provided path must be a directory");
            }
            if (!Directory.Exists(fileDirectory))
            {
                throw new InvalidOperationException("The provided directory path does not exist");
            }

            var address = wallet.KeyPairs[0].PublicKey;
            var json    = ExportToKeystore(kdfType, wallet, address, GetJsonSerializerSettings());

            // UTC--2017-10-01T17-22-26.196Z--01caf1a3bf2164ec410b888c74d82a292c326487
            var timestamp = $"{DateTimeOffset.UtcNow:s}".Replace(':', '-');
            var lastDash  = timestamp.LastIndexOf('-');

            timestamp = timestamp.Remove(lastDash, 1);
            timestamp = timestamp.Insert(lastDash, ".");
            var filename = Path.Combine(fileDirectory, $"UTC--{timestamp}Z--{address.ToHex()}");

            File.WriteAllText(filename, json);

            return(filename);
        }
コード例 #4
0
 public SetKeyConnectorKeyRequest(string key, KeysRequest keys,
                                  KdfType kdf, int?kdfIterations, string orgIdentifier)
 {
     this.Key           = key;
     this.Keys          = keys;
     this.Kdf           = kdf;
     this.KdfIterations = kdfIterations;
     this.OrgIdentifier = orgIdentifier;
 }
コード例 #5
0
 public async Task SetInformationAsync(string userId, string email, KdfType kdf, int?kdfIterations)
 {
     _email         = email;
     _userId        = userId;
     _kdf           = kdf;
     _kdfIterations = kdfIterations;
     await Task.WhenAll(
         _storageService.SaveAsync(Keys_UserEmail, email),
         _storageService.SaveAsync(Keys_UserId, userId),
         _storageService.SaveAsync(Keys_Kdf, (int)kdf),
         _storageService.SaveAsync(Keys_KdfIterations, kdfIterations));
 }
コード例 #6
0
        public async Task <SymmetricCryptoKey> MakeKeyFromPinAsync(string pin, string salt,
                                                                   KdfType kdf, int kdfIterations)
        {
            var pinProtectedKey = await _storageService.GetAsync <string>(Constants.PinProtectedKey);

            if (pinProtectedKey == null)
            {
                throw new Exception("No PIN protected key found.");
            }
            var protectedKeyCs = new CipherString(pinProtectedKey);
            var pinKey         = await MakePinKeyAysnc(pin, salt, kdf, kdfIterations);

            var decKey = await DecryptToBytesAsync(protectedKeyCs, pinKey);

            return(new SymmetricCryptoKey(decKey));
        }
コード例 #7
0
        public async Task <SymmetricCryptoKey> MakePinKeyAysnc(string pin, string salt, KdfType kdf, int kdfIterations)
        {
            var pinKey = await MakeKeyAsync(pin, salt, kdf, kdfIterations);

            return(await StretchKeyAsync(pinKey));
        }
コード例 #8
0
 public KeystoreFileStorageFormat(KdfType kdfType = KdfType.Scrypt)
 {
     _kdfType      = kdfType;
     _jsonSettings = GetJsonSerializerSettings();
 }
コード例 #9
0
        public static string ExportToKeystore(KdfType kdfType, Wallet wallet, byte[] address, JsonSerializerSettings jsonSettings)
        {
            Contract.Assert(!string.IsNullOrWhiteSpace(wallet.PasswordHash));
            var passwordHashBytes = Encoding.UTF8.GetBytes(wallet.PasswordHash);

            var salt      = CryptoUtil.RandomBytes(32);
            var kdfparams = new
            {
                dklen = 32,
                salt  = salt.ToHex()
            };

            byte[] derivedKey;
            switch (kdfType)
            {
            case KdfType.Scrypt:
            {
                derivedKey = PasswordHash.ScryptHashBinary(passwordHashBytes, salt, PasswordHash.Strength.Sensitive, kdfparams.dklen);
                break;
            }

            case KdfType.Argon:
            {
                derivedKey = PasswordHash.ArgonHashBinary(passwordHashBytes, salt, PasswordHash.StrengthArgon.Sensitive, kdfparams.dklen);
                break;
            }

            default:
                throw new NotSupportedException("Unsupported kdf");
            }

            var iv    = CryptoUtil.RandomBytes(32);
            var pKey  = wallet.GetPrivateKeyByAddress(address);
            var nonce = derivedKey.Take(24).ToArray();
            var box   = SecretBox.CreateDetached(pKey, nonce, iv);

            var keystore = new Keystore
            {
                Version = KeystoreVersion,
                Id      = wallet.Id,
                Address = address.ToHex(),
                Crypto  = new KeystoreCrypto
                {
                    CipherText       = box.CipherText.ToHex(),
                    CipherParameters = new KeystoreCryptoParameters
                    {
                        Iv = iv.ToHex()
                    },
                    Cipher        = "crypto_secretbox_detached",
                    Kdf           = kdfType.ToString().ToLowerInvariant(),
                    KdfParameters = new KeystoreKdfParameters
                    {
                        Salt             = kdfparams.salt,
                        DerivedKeyLength = kdfparams.dklen,
                    },
                    Mac = box.Mac.ToHex()
                }
            };

            return(JsonConvert.SerializeObject(keystore, Formatting.None, jsonSettings));
        }