/// <summary> /// Uses the <see cref="RsaSecurityKey"/>s stored in the given directory. /// Note: this extension will automatically ignore incompatible keys and /// create a new RSA key if none has been previously added. /// </summary> /// <param name="configuration">The options used to configure the OpenID Connect server.</param> /// <param name="directory">The directory containing the encrypted keys.</param> /// <param name="protector">The data protector used to decrypt the key.</param> /// <returns>The options used to configure the OpenID Connect server.</returns> public static OpenIdConnectServerConfiguration UseKeys( [NotNull] this OpenIdConnectServerConfiguration configuration, [NotNull] DirectoryInfo directory, [NotNull] IDataProtector protector) { if (!directory.Exists) { throw new InvalidOperationException("The directory does not exist"); } foreach (var file in directory.EnumerateFiles("*.key")) { using (var buffer = new MemoryStream()) using (var stream = file.Open(FileMode.Open)) { // Copy the key content to the buffer. stream.CopyTo(buffer); // Extract the key material using the data protector. // Ignore the key if the decryption process failed. var parameters = protector.DecryptKey(buffer.ToArray()); if (parameters == null) { continue; } configuration.UseKey(new RsaSecurityKey(parameters.Value)); } } // If no signing key has been found, // generate and persist a new RSA key. if (configuration.Options.SigningCredentials.Count == 0) { // Generate a new 2048 bit RSA key and export its public/private parameters. var provider = new RSACryptoServiceProvider(2048); var parameters = provider.ExportParameters(includePrivateParameters: true); // Generate a new file name for the key and determine its absolute path. var path = Path.Combine(directory.FullName, Guid.NewGuid().ToString() + ".key"); using (var stream = new FileStream(path, FileMode.CreateNew, FileAccess.Write)) { // Encrypt the key using the data protector. var bytes = protector.EncryptKey(parameters); // Write the encrypted key to the file stream. stream.Write(bytes, 0, bytes.Length); } configuration.UseKey(new RsaSecurityKey(parameters)); } return(configuration); }