In one of the projects at work, I need to find certificate matching an email address from Firefox certificate manager if there is no matching certificate found in the Windows certificate store. In this post, I’m going to show how to find a certificate and export it from Firefox certificate manager.
Firstly, let’s create a new console app in Visual Studio. Then we need to download the Network Security Services (NSS) from Firefox. NSS is a set of library that supports security standard PKCS#12 which allows us to export the certificate with private key. More details on NSS can be found here. After downloading the NSS, we need to:
- Extract the ZIP file
- Move all the content from folder lib to folder bin
- Create a new folder NSS in the console app
- Move everything from folder bin to the new folder NSS
The solution should look like this

We then need to copy everything in the NSS to output directory by adding the following in the project file
<ItemGroup>
<None Update="NSS\**">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
We’ll use the NSS library by executing a CMD command line. We are going to create a helper class to do this.
public static class CmdHelper
{
public static string Execute(string cmd)
{
var process = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = $"/C \"{cmd}\"",
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false
}
};
process.Start();
var result = process.StandardOutput.ReadToEnd();
process.WaitForExit();
return result;
}
}
Then we create a method to get the certificate as followed
public static X509Certificate2 GetFirefoxCertificate(string email)
{
var firefoxProfilesDirectory = $"{Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)}\\Mozilla\\Firefox\\Profiles";
var nssDirectory = $"{Directory.GetCurrentDirectory()}\\NSS";
const string tempPassword = "P@ssw0rd";
X509Certificate2 result = null;
foreach (var profileDirectory in Directory.GetDirectories(firefoxProfilesDirectory))
{
var certUtilResult = CmdHelper.Execute($"\"{nssDirectory}\\certutil.exe\" -L -d \"sql:{profileDirectory}\" -n {email} -a");
// This means no matching certificate found
if (string.IsNullOrWhiteSpace(certUtilResult))
continue;
// Export the matching certificate to a temp file
var tempCertFile = Path.Combine(Path.GetTempPath(), $"{Guid.NewGuid()}.pfx");
CmdHelper.Execute($"\"{nssDirectory}\\pk12util.exe\" -o \"{tempCertFile}\" -d \"sql:{profileDirectory}\" -n {email} -W {tempPassword}");
result = new X509Certificate2(tempCertFile, tempPassword);
File.Delete(tempCertFile);
break;
}
return result;
}
That is pretty much all we need. To test this, I have imported a sample certificate to Firefox with email [email protected]

var certNotFound = GetFirefoxCertificate("[email protected]");
var validCert = GetFirefoxCertificate("[email protected]");
Console.WriteLine($"Certificate 1: \n{certNotFound?.SubjectName.Name}\n");
Console.WriteLine($"Certificate 2: \n{validCert?.SubjectName.Name}\n");
And this is the result
