public InitializationResponse Initialize(int n, int t) { if (Health.Initialized) { return(null); } using (var aes = Aes.Create()) using (var tss = ThresholdSecretSharingAlgorithm.Create()) using (var sha = SHA512.Create()) { aes.KeySize = 256; aes.GenerateKey(); var rootKeyClear = aes.Key; var rootKeyCrypt = tss.Split(rootKeyClear, n, t); var rootKeyShares = tss.Shares.ToArray(); var rootToken = Guid.NewGuid(); var resp = new InitializationResponse { Keys = rootKeyShares.Select(x => BitConverter.ToString(x).Replace("-", "")).ToArray(), KeysBase64 = rootKeyShares.Select(x => Convert.ToBase64String(x)).ToArray(), RootToken = rootToken.ToString(), }; try { State.Durable = new DurableServerState(); State.Durable.SecretShares = n; State.Durable.SecretThreshold = t; State.Durable.RootKeyTerm = 1; State.Durable.RootKeyInstallTime = DateTime.UtcNow; State.Durable.RootKeyEncrypted = rootKeyCrypt; State.Durable.RootKeyHash = sha.ComputeHash(rootKeyClear); State.Durable.RootTokenHash = sha.ComputeHash(rootToken.ToByteArray()); State.Durable.ClusterName = Settings.ClusterName; State.Durable.ClusterId = Guid.NewGuid().ToString(); SaveState().Wait(); Health.Initialized = true; return(resp); } catch { State.Durable = null; throw; } } }
private void Unseal(IEnumerable <byte[]> keys) { using (var tss = ThresholdSecretSharingAlgorithm.Create()) using (var sha = SHA512.Create()) { tss.Shares = keys; var rootKeyClear = tss.Combine(State.Durable.RootKeyEncrypted); var rootKeyHash = sha.ComputeHash(rootKeyClear); if (BitConverter.ToString(rootKeyHash) != BitConverter.ToString(State.Durable.RootKeyHash)) { // TODO: verify the response in this case throw new InvalidDataException("Invalid keys!"); } State.RootKey = rootKeyClear; } }