Can I retrieve certificate information from ClickOnce deploy files? - c#

I have a ClickOnce application that has been deployed to many users that was signed with a certificate that was located on a previous developer's computer. The certificate has expired since that developer left the company. In order to re-publish the application from another machine we need to be able to find the original certificate and update it with an extension. I have access to the previous developer's computer, but I cannot locate the original .pfx file to copy and update the certificate. I also have access to all of the previously deployed files.
We attempted to deploy the application and received the error:
The deployment identity does not match the subscription.
My best guess is that it is, in fact, the different certificate causing this error based on an MSDN forum question and response, Deployment identity does not match the description. However, it is worth noting that we have both changed the machine from which the code is being deployed and also updated the solution to Visual Studio 2010 (the platform and configuration are the same though).
How do I retrieve the original certificate information from the previous developer's machine or the deploy files? Or are we possibly going down the wrong hole trying to resolve this?

If the physical access to the machine/user account is available, it should not be a problem to retrieve the certificate, provided it was not protected with a custom password at the time of import. The export wizard can be launched from Internet Explorer Options as shown on the picture. Look up the desired certificate in one of the tabs (typically, in Personal tab). Use PFX format to export both private and public keys.
Another way to access the Export wizard is through the MMC snap-in.
[UPDATE] For the answer's completeness sake, it is impossible to retrieve the private key from a signed deployment file as it only contain the public part of the encryption key. Perhaps, in the OP's case the private key is still there, buried somewhere in the file system of the development machine (as .PVK file), although it'd be a bad practice to store it like that. More details about certificate file types can be found here. I would rather expect both private and public keys to be found in the machine's certificate store, as described above.

Related

Adding a <publisher> to an Excel add-in project

I recently had to take over an Excel plugin project and one of the issue I'm getting is that a customer can't use the plugin because their Trust center only allows COM add-ins signed by Trusted publishers. (And they are not able to disable it)
I'm quite new and don't really understand this signing issue so I self-signed the code.
But the add-in has its publisher set to None. Here's how it's showing.
I believe that's not what I need to do, right? As a self signing will not be trusted by the customer Trust Center.
I saw this post but I was quite unsure about what was going on.
Does that mean there is no possible workaround or am I getting this wrong?
One thing I was wondering but I needed some help over is that if the add-in needs to be signed by a Trusted publisher.. Would that do the trick if the client is generating .pfx and I use it to sign the add-in?
AFAIK, there are no "tricks" you can do from the DEV side. This is a security feature. You need to sign your add-in with a valid certificate to get rid of "unknown publisher". You can do that by selecting that certificate on "Sign" tab in Project settings in Visual Studio.
If you are a public company/developer and don't really have any assumptions about your users, then you can obtain the code signing certificate from one of the public code signing certificate providers. The main ones are listed here: https://learn.microsoft.com/en-us/windows-hardware/drivers/dashboard/get-a-code-signing-certificate
It is not free, and you'll need to prove your identity to the certificate issuing authority (like, provide them your passport/company registration details/etc).
If you are developing an add-in for a specific organization and you can negotiate with it's admins, or your users have admin rights on their computers and are allowed to mess with security, then you can create a self-signed certificate, sign your code with it (select it on "Signature" tab), and then ask your users (or user's admin) to add this self-signed certificate to "trusted root" for their organization/on their PC.
Please note that self-signed certificate usually work only on the PC where the certificate was created, and used for testing or development purposes. In your case, this means that your self-signed certificate is considered valid on your PC, but not on the customer's PC. If you want a certificate created by you on your PC to also work on customer's PC, then you'll have to ask the customer to add your certificate as "trusted root", i.e. to treat your signature the same way as one of those "worldwide trusted certification authorities" from the list above.
The normal practice is to buy a certificate from the certification authorities though.

Deploying AWS .NET SDK project failing

I have configured the .NET SDK in Visual Studio to use IAM credentials (which are being encrypted to the app.configs such as is described here: https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/net-dg-setup.html I then wrote a call to my S3 server to get a presigned URL so I could display it in my .NET desktop app. When I run the app from my computer (through VS or by clicking the Executable) the pictures load fine from S3. When I move the bin folder files (I copy the Release directory to the 5 client computers) it doesn't work on those machines!
I've thought about trying to run an install (which has several draw backs that stem from my lack of experience creating installers). The only thing I could see this changing, is if the encryption of the IAM key uses a MAC address and the installer re-requests the IAM credentials, then it would work.
The error I get on the other PC's is: "Failed to retrieve credentials from EC2 Instance Metadata Service."
The machines are on a network whose public IP is white listed to another IAM role with FullS3 Permissions but the Group the Security Key is in also has FullS3 permissions so I wouldn't think that would matter either.
I'm more than happy to answer any other questions people have because I really want to get it going! Thank you!
I found this article about 45 minutes after posting and after reading it about 3 times I finally saw it!
"SDK Store profiles are specific to a particular user on a particular host. They cannot be copied to other hosts or other users. For this reason, SDK Store profiles cannot be used in production applications."
and "Using a Credentials File
You can also store profiles in a credentials file, which can be used by the other AWS SDKs, the AWS CLI, and Tools for Windows PowerShell. To reduce the risk of accidentally exposing credentials, the credentials file should be stored separately from any project files, usually in the user's home folder. Be aware that the profiles in a credentials files are stored in plaintext."
So the answer is I have to provide a plaintext file with the credentials and simply put it somewhere I believe to be "safe" on the clients computer, then specify that location in the app.config file.

Read certificates from a PKI card

How can I read certificates from a PKI card?
I tried finding answer on the Internet but I didn't get any good results.
Any ideas how to get the certs from a PKI card?
I need to sign some forms with a certificate key. All this will happen in a web app.
Later...
I didn't tried much because I don't have a point to start. I've just learned that all of the certs are read by Windows when you insert the card. This way I think I can get them using X509Store. I'll try it and I'll be back but still I'm in the need of some help.
As soon as you plugin in your SmartCard the certificates are copied to your local, personal certificate store. You can use "certmgr.msc" (run -> enter) to have a look at these certs.
You can access the certificates, as well as the associated private keys, with the X509Store. But of course you can only do it locally on your machine due to security reasons. Imagine every website would have access to your private keys...
How to Sign and Verify the signature with .NET and a certificate (C#)
If you are using CAPICOM, you will still need to execute code on the local machine (JavaScript).
You find the following statement here :
[CAPICOM is a 32-bit only component that is available for use in the following operating systems: Windows Server 2008, Windows Vista, Windows XP. Instead, use the .NET Framework to implement security features. For more information, see the alternatives listed below.]
Important None of the alternatives to CAPICOM offer a solution for scripts; therefore, you must write your own ActiveX control. For more information, see ActiveX Controls.
Which indicates that the .Net classes are not a "full" replacement to CAPICOM. So you can't use the "X509" classes in JavaScript.
If you want to use a client side private certificate to sign some data (assume a hash), you need to run code on the client. Here are some ideas what you could do:
Write an ActiveX control
Write browser Plugin(s)
Write an application which can be called by using a custom URI schema (can't post another Link, google it and you will find it).
Of course you need to retrieve the data on the server side and for the last solution you may need a kind of a webservice.
Conclusion
Don't be confused about private and public keys from a certificate.
There are scenarios where you send a certificate to the server for e.g. authentication.
But then its your public key. You should never send your private key around (of course technically its possible).

How to programmatically add x509 certificate to local machine store using c#

I understand the question title may be a duplicate but I have not found an answer for my situation yet so here goes;
I have this simple peice of code
// Convert the Filename to an X509 Certificate
X509Certificate2 cert = new X509Certificate2(certificateFilePath);
// Get the server certificate store
X509Store store = new X509Store(StoreName.TrustedPeople, StoreLocation.LocalMachine);
store.Open(OpenFlags.MaxAllowed);
store.Add(cert); // x509 certificate created from a user supplied filename
But keep being presented with an "Access Denied" exception.
I have read some information that suggests using StorePermissions would solve my issue but I don't think this is relevant in my code.
Having said that, I did test it to to be sure and I couldn't get it to work.
I also found suggestions that changing folder permissions within Windows was the way to go and while this may work(not tested), it doesn't seem practical for what will become distributed code.
I also have to add that as the code will be running as a service on a server, adding the certificates to the current user store also seems wrong.
Is there anyway to programmatically add a certificate into the local machine store?
Thank you to Oscar and Bob for asking the questions and leading me in the right direction +10 to you both :)
My issue, as I think we all knew (even me) was the user running the application had insufficient privilages to add a certificate to the local machine store.
But various attempts to elevate the user permissions were failing for me, let me explain why.
I had 3 seperate projects in my solution, the wcf service which requires the X509certificates, the windows form client and the cryptography class library which, amongst other things, installs the certificates provided via the windows form client.
As most of the code within all 3 projects could run without elevated permissions, I really wanted to only elevate them at the certificate install stage within the class library but I tried to use Process and Verb= "runas" in code and this didn't work.
Then I tried to add a custom manifest but if you try to alter the properties of a class library to use a custom manifest, you'll find the option is disabled.
So I changed things.
My cryptography class is now within my windows form client and I've added the custom manifest to the client. This now means the whole client opens with elevated privilages but I'd rather that than the alternative.
Thank you again

Why does sslStream.AuthenticateAsServer require no UAC and alternatives

While tweaking a web proxy code, I noticed that if I run the code in an app with UAC (User Access Control) I get an exception
Here is the location where the exception is thrown:
sslStream.AuthenticateAsServer(_certificate, false, SslProtocols.Tls | SslProtocols.Ssl3 | SslProtocols.Ssl2, false);
Here is the error I get (with UAC)
The server mode SSL must use a certificate with the associated private key.
First question: Why?
2nd question: Is there an alternative? I really would like to run this in UAC (note that http works fine)
It sounds like the private key to your certificate is probably located somewhere with restricted file access. This is so that not just any user can read your private key. What is the purpose of running your service with limited privileges? If the key is only for this service, you may consider removing the security limitations on the folder it is in, but if this key is for your whole domain, I would be hesitant to do that...
Have you installed the certificate in the appropriate certificate store?
From what I remember when working with certificates, the file that you load is only used as a reference to identify the server certificate in one of the Windows certificate stores. If the proxy is running under one account but not the other, maybe you didn't install the certificate in that other account's personal certificate store.

Categories