Cant get private key from certificate - c#

So, I having trouble to get the private key from the certificate. This is my first time working with certificates and I have tried to find a solution to this but I cant make i work. It's a console application and a need the key to sign a SOAP message/request.
Here is a code sample; (Let me know if you need anything more)
public static X509Certificate2 FindCertificate(string issuedBy)
{
var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
//We gets the certificate from store
var certificate = store.Certificates.Cast<X509Certificate2>().FirstOrDefault(c => c.Issuer.Contains($"CN={issuedBy}"));
if (certificate.HasPrivateKey) // Result: True
{
//PrivateKey throws error: Keyset dosent exist
var key = certificate.PrivateKey;
}
if (certificate == null)
{
throw new ArgumentException($"Could not find certificate issued by: '{issuedBy}'", nameof(issuedBy));
}
var expireDate = DateTime.Parse(certificate.GetExpirationDateString());
if (expireDate < DateTime.Now)
{
throw new Exception($"Certificate has already expired: '{expireDate}'");
}
return certificate;
}

An alternative to your own solution (so you don't have to run VS in administrator mode is to give your own user privileges to read the private key.
Open the certificate manager for your machine certificates (type in "certificates" in Windows home menu search and choose "Manage computer certificates"
Find the certificate and right click -> "All Tasks" -> "Manage Private Keys..."
Click "Add..."
Type in your username (and click "Check Names" to see if you typed it in correctly)
Click "OK" and "OK"
Now you should be able to run your application (and VS) normally with access to the private key.

I was able to get it to work now just by start Visual Studio in Admin mode.

Related

How can i write in the "Enterprise Trust" Store?

I have a .p7b file with a few certificates and i want to install them in the "Enterprise Trust" Store. A program i want to use expects it there.
I have writte code in c# which extract all the certificates from the file and installs them into a X509Store ("Storename.My") which works.
If i try to use the same code to write in a different store it (which already exists) it creates a new empty store and writes in there.
The StoreName.My is taken from system.Security.Cryptography.X509Certificates public enum StoreName, but there is no option for the "Enterprise Trust" store.
So i tried to use the constructor where i can give the StoreName as a string.
I use the certmgr from windows to check what certificats are stored in which stores.
// open file
var certificateStore = new CmsSignedData(new
FileStream(_tempFileName.ToString(), FileMode.Open));
// get all certificats
IX509Store x509Certs = certificateStore.GetCertificates("Collection");
var a = new ArrayList(x509Certs.GetMatches(null));
// this works
var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
// this doesnt work
// var store = new X509Store("Enterprise Trust", StoreLocation.CurrentUser);
// open store
store.Open(OpenFlags.ReadWrite);
// write in store
foreach (object o in a) {
var cert = (Org.BouncyCastle.X509.X509Certificate)o;
var cert509 = new X509Certificate2();
cert509.Import(cert.GetEncoded());
store.Add(cert509);
}
store.Close();
How do i write correctly in the a store which isnt the StoreName enum?
If you want to be sure you aren't creating a new store, you can use the OpenFlags value OpenExistingOnly. Asserting that flag and checking for, e.g. "Trust2" yields System.Security.Cryptography.CryptographicException: The system cannot find the file specified. Therefore we get the best level of assurance that "Trust" is the right answer by specifying it as:
using (X509Store store = new X509Store("Trust", StoreLocation.CurrentUser))
{
store.Open(OpenFlags.ReadWrite | OpenFlags.OpenExistingOnly);
...
}
(Note that this is less good to use on Linux (.NET Core), because only Windows pre-initializes the stores)
We can get confirmation on the programmatic name to the display name via the certutil.exe command-line utility:
>certutil -store trust
trust "Enterprise Trust"
CertUtil: -store command completed successfully.
(I just don't have anything in that store)

Problem is Installing .pem extension Security Certificate in windows 7 for UBL Api

I am new to this. I am having issues in installing demo Merchant Digital Certificates for UBL Payment API. I tried various methods found on the Internet but nothing works for me. The issues come out of Certificate & password provision.
I used Internet Explorer for running the application as ubl doc said the recommended browser is IE.
I also checked certificates appears in Internet Options -> Certiticates tab but they are not working for me.
Here is my code sample as well.
public ActionResult Index()
{
RegistrationRequest ObjRequest = new RegistrationRequest();
ObjRequest.Customer = "Demo Merchant";
ObjRequest.Channel = "Web";
// ObjRequest.Language = "en";
ObjRequest.version =Convert.ToDecimal(2.0);
ObjRequest.Amount = Convert.ToDecimal(10.00);
ObjRequest.Currency = "AED";
// ObjRequest.OrderID = "123";
// ObjRequest.OrderInfo = "Test Info";
// ObjRequest.OrderName = "Test Name";
ObjRequest.ReturnPath = "www.google.com";
ObjRequest.TransactionHint = "CTP:Y";
ObjRequest.Password = "Comtrust";
// ObjRequest.Store = "n/a";
// ObjRequest.Terminal = "n/a";
UBLPaymentApi.MerchantAPI Obj = new MerchantAPI();
var Result= Obj.Register(ObjRequest);
return View();
}
and here is the image of the error i am getting.
This is the error i am getting.
I am getting very strong feeling that I am doing issue in installing/importing the certificates. As it's my first time dealing with certificates.
1 - You can use the following answer to import .pem file on windows 7.
Importing .PEM certificates on Windows 7 on the command line
2 - Verify if the certificate is installed on the machine.
View / install certificates for local machine store on Windows 7
If above doesn't work,
3 - Check if you can pass additional information through MerchantAPI() overloads.

How can I set this registry value for my User from my installer

The problem from
https://stackoverflow.com/a/37859812/4878558
I need to set Registry value for current user, who launch the install up. Since install going for system mode - I don't know anything about current user
Also my code giving 'System.UnauthorizedAccessException'
SecurityIdentifier sID = WindowsIdentity.GetCurrent().User;
var subKey = Registry.Users.OpenSubKey(sID + "\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run");
subKey.SetValue("test", "test");
enter code here
As Ripple and I have both commented, there's no need for code. Go to the Registry view in the setup project, right-click on Software under HKEY_CURRENT_USER and add the key Microsoft, then Windows, the CurrentVersion, then Run, adding each key.
Then in the Run key view, right-click in the Name, View pane on the right and add new string value, the name being your name. The value, I assume, is the path to your exe, and (assuming it's in the Application folder) make the value [TARGETDIR]my.exe.
If your install is an "Everyone" install then there is a perfectly good reason why it cannot work. This is nothing to do with the code. In an Everyone install that custom action code is running with the System account (NOT the installing user) so you are trying to create a run key for the system account.
Here is how to write autostartup options:
const string AutorunRegistryKey = #"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run";
Registry.SetValue(AutorunRegistryKey, <AppName>, <PathToApplication>);
If you want to remove it from autostartup:
const string AutorunRelativePath = #"Software\Microsoft\Windows\CurrentVersion\Run\";
var key = Registry.CurrentUser.OpenSubKey(AutorunRelativePath, true);
if (key != null)
{
key.DeleteValue(<AppName>, false);
key.Close();
}

Visual C# - Checking installed certificate - Does nothing if it doesnt exist

This is probably a very basic error, but i am pulling my hair trying to understand why this is happening.
I have a check against the store certificates if it contains a certain certificate with a name. If it doesnt, then update a label.text.
It does the check just fine and it finds it, but no matter what i do it doesnt handle if it isnt there. Its not doing anything. No text beeing displayed. I have also tried a simple else without the (!mCert) but still no go.
// Certificate controls
X509Store store = new X509Store("My", StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
foreach (X509Certificate2 mCert in store.Certificates)
{
if (mCert.Issuer.Contains("Cert-Name"))
{
label3.Text = "Found certificate";
}
else if (!mCert.Issuer.Contains("Cert-Name"))
{
label3.Text = "Didnt find the certificate";
}
}
So the else if statement isnt doing anything. Even if i just put an else instead there it isnt updating the label3.text.
If the store is empty and cant find any certificates the foreach will never run, thats why the if statements never get processed.
Adding this before the foreach will solve it
if (store.Certificates.Count==0)
"My" store of local machine is very likely to be empty (unless you install things such as IIS, where the installer generates test certificates).
Thus, switch to other stores, such as using StoreName enumeration,
https://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.storename(v=vs.110).aspx
You can always open MMC to see stores and certificates,
https://msdn.microsoft.com/en-us/library/ms788967(v=vs.110).aspx

How to obtain CN of the certificates in particular store?

i want to obtain the CN of the certificates stored in the MY store as i want to verify if the certificate exists or not in that store.
I don't know the which method should be used to perform this task.
I tried using below code but it doesn't works
X509Certificate2Collection cers = store.Certificates.Find(X509FindType.FindBySubjectName,"Root_Certificate",false);
if(cers.Count>0)
{
//certificate present
}
else
{
//certificate not present
}
Does the subjectName gives CN?
is there any other method?
Please suggest me how to check whether a particular certificate is present or not and i want to do it using CN.
You could use the store.Certificates.Find(X509FindType.FindBySubjectName, "SubjectName", false)
function to search for a certificate by its subject name. Do NOT include "CN=" in the subject name.
To search more specific you could use the thumbprint to search for your certificate.
The following code sample demonstrates this:
X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly | OpenFlags.IncludeArchived);
foreach (var c in store.Certificates)
{
Console.Out.WriteLine(c.Thumbprint);
Console.Out.WriteLine(c.Subject);
}
// Find by thumbprint
X509Certificate2Collection col =
store.Certificates.Find(X509FindType.FindByThumbprint, "669502F7273C447A62550D41CD856665FBF23E48", false);
store.Close();
I've added a foreach loop to the code sample to iterate over all certificates in the selected store.
Your certificate must be listed there. If not, you probably use the wrong store.
Note, there is a My store for the Machine and the Current User. So, be sure to open the right store.
To get the thumbprint of your certificate follow these steps:
Open certmgr.msc.
Double click on your certificate.
Go to the details tab.
Under thumbprint you will find the thumbprint of your certificate.
Hope, this helps.

Categories

Resources