Security concerns trying to sign downloadable exe file from my web app - c#

Let me explain my dilemma. I am writing an ASP.NET web application that is supposed to let a logged in user download my client-side Windows executable file. Before such file is downloaded the web app changes some strings inside the .exe file (by modifying the exe file image with the user selection).
I am now looking into a way to digitally sign this executable file with my code signing certificate. The problem is that to do this I need to run it through the Microsoft's signtool that requires either an installed digital certificate on the server where the web app is running from, or that I provide the .pfx file that contains my private key.
This bring up two issues:
If I go with installing my digital cert on the server, then anyone can use it to sign any executable off that server (which I would prefer to avoid.)
If I choose to upload the exported Personal Information Exchange (PFX file) for my certificate, I can protect it with a password, but signtool will require that password to sign my exe file, which it will need in a plain text form. So I will need to store the password somewhere, which is not that safe either.
Any suggestions, how shall I overcome these?

If you plan to use number 2, you can look into using SecureString to encrypt your password. You still need to initialize SecureString with the plain password for which you have two secure options.
Provide the string manually through a webpage (use SSL to protect this page from MITM attacks). This is the most secure option but it has a tradeoff that You have to provide the password every time app starts. Or,
Create a web service on a different server that will return this plain password (again communicating over SSL). This is not full proof because if the web service's server is compromized, your password is gone. However, by distributing risk into multiple servers, you make the job harder for hacker to break the security of the system.

Related

Store secret key securely in .NET Standard cross-platform app

I'm working on a C# PowerShell module, which is going to be a simple wrapper around some service REST API. I'd like to target PowerShell Standard / .NET Standard and make module available across all supported platforms.
For this app authentication requires API token, issued on a service website by the user. Entering key every time you open a session would be extremely inconvenient and therefore I need some way to securely store the API key in a user profile.
The problem is - I cannot find an easy way to encrypt data that has transparent cross-platform support. Initially, I wanted to use SecureString, but it is (a) deprecated and (b) doesn't seem to have good support on Linux. In a perfect world I'd like to have some mechanism similar to Windows encryption - user certificate encrypts API key and I put result in a text file in a user folder.
This is not a financial or mission-critical application, top-notch security is not required, but still keening plain text secrets in my home folder makes me nervous. Yes, I'm talking to you, AWS SDK authors :)
My first thought was: "just save secret key to ENV variables..."
But if I understood OP's question correctly, it is required to restrict unauthorized reading of this secret even on OP's machine.
One option I could see is just create a folder (or maybe file) and give it the access permissions only for one particular user. Ultimately one can create new user account which will be used to run the code in powershell and give this new user exclusive permissions to read secret file. This will prevent some 3rd party programs running from OP's account to read secret file.

Compiling Service Account Credentials Into Executable?

I have a program (compiled into a DLL to be used in other applications) that uses a Google Service Account to create and upload some files to Google Drive. The credentials are stored in a credentials.json file. I want to be able to ship this program to clients but do not want to have these credentials readable to them as that presents an obvious security concern. What is the best way to go about compiling these credentials into the DLL so that they don't exist in plaintext anywhere accessible to the end user?
You could just hard code it in a string on your application:
var apiKey = "my key";
But as mentioned in the comment above, someone can decompile the IL and see it. That would also make it difficult to change if you need to.
Or, you could encrypt it in the configuration file.
But in either of those options, or really any option where your application talks directly to the Google API, any savvy user can use something like Fiddler to inspect the traffic and see the key (even if it's over SSL).
The only way to keep your Google API key safe is to not let your application talk directly to the Google API. You can setup your own API as a proxy. The user authenticates to your API using different credentials for each user, and your API talks to Google. That way, if anyone misbehaves, you know who it is and you can disable their credentials.

Store key file as embedded resource (how unsafe is it?)

If I have a stored key file used to decrypt the encrypted input coming into my application, and I store that key file as an embedded resource so that it is embedded in the assembly when deploying, how difficult would it be for someone to reverse engineer the application and retrieve the key file?
Also, the application is deployed through ClickOnce "Online only" mode which I imagine would also make it more difficult to reverse engineer? (I'm not exactly sure of the workings of ClickOnce but I wasn't able to find the dll's/assemblies on my local machine after running the application in online only mode...).
Update:
As Ralf essentially answered the main question below in his comment (answer: it's not really safe at all), here's some more information so that you knowledgeable people can possibly suggest a better security model.
The encryption will be used to encrypt the login password for my application, to be used in a SSO setup (the user will first sign on to a different system and then by clicking a link will be able to directly open my application without having to enter in their login details).
The encrypted data will be sent as a base-64 string URL parameter in the link that will launch the my click-once application.
I will also be developing the application that will create the encrypted data for the URL parameter (clarification: not the first application the user will sign in to for the SSO, I will only be creating a small tool to convert the plain text password into an encrypted base64 string).
It's only an internal application so bullet proof security isn't essential and ease of deployment is more important, but it'd be nice to know what the best practices and different options that are available.
Whether in clear text or encrypted, you don't want to store the password. When you get a password, all you should do is pass it to your server app where you compare it against the salted hash of the password you have in the DB. Even if you don't think security is that important, you need to take care with the password because people frequently reuse passwords across different systems. I know they shouldn't but they do.
If you want to implement a single sign on (SSO), create a sign on token on the server side and pass it back to the client, either encrypted or signed (HMAC is a good choice for signing). This is an unforgeable token because you need to know the encryption key or shared secret for the HMAC and that data is only known on your servers. So you have your SSO and all data involving the SSO is managed on servers so there's no data leakage or chance of spoofing.
As long as the aplication can be launched, the files have to be somewhere on the computer. You just have to know where to look. The reverse-engineering may be ugly but it is always possible. The computer has to be able to understand what he is supposed to do so you only have to extraxt the information one is looking for. Therefore the security of your application should never depend on the difficulty of reverse-engineering! I believe that a secure application should be open-source anyways.
You propably need a diffent security model. The important thing here is that you know against what you want to protect the data. If you simply want that you know the data is sent by the server and not somebody else (man in the middle attack) you could use digital signatures instead.
If you do not want anybody to read any data sent between server and client you should use some sort of ssl implementation to create an encrypted channel. Then you only need to watch out that the public key of the server is not altered on the client. This may be done by an certificate of an official CA but unfortunately those are usualy not for free.

When should I encrypt my config file?

I have a C# application that comes with an app.config file. The application is built on a build server and deployed to multiple users.
I'd like to encrypt the app.config, but I'm not sure about when to do so: If I do it straight after the build, won't the encryption depend on the build server credentials? How can the application decrypt on other machines? If I do the encryption on the users machine, won't this leave time when the app.config is unprotected?
Thanks
Edit:
I was considering using DPAPI. It uses the user's credentials to encrypt and decrypt. This is why I think I might have a problem delivering an encrypted file to the users.
I just read the addition to your post, and I don't think you actually need encryption at all...
You say that you intended to use a system that would encrypt/decrypt based on the user's credentials. That means two things:
You don't encrypt during build; you can't use this sort of system during build, for the reasons yoy noted.
You seem to be OK with the users having access to the data. In that case, you should not be using configuration at all, but you should be prompting them for login info (perhaps saving it securely afterward to reuse) or just using their Windows/domain logins.
Either way, you don't need to encrypt the file to protect it... you simply need to store the login info, or other config info, as user settings, rather than configuration, which is readable to all users.

Monitor File for Read and Change Data?

Is there any way, using C#, to monitor a specific file then change its contents before it is read by specific applications?
Here is the situation:
I have a Windows 2003 Server running ASP.NET with a configuration file (xml) which contains LDAP information. I want to have the LDAP password encrypted. I'm trying to devise a way to monitor that file, and whenever it is read, decrypt the LDAP password and pass that to whatever is reading it. Is there any way to tell which program is doing the read? I aldready have the encrypt/decrypt working but it is built into the ASP.NET installation; I would like to make it external. The encrypt/decrypt is RSA using key's from the key store.
If you want the encrypt/decrypt external to your main application, what about creating a separate .dll or webservice that does that. Then your call in your ASP.NET application is to your webserice or .dll.
Something like (Warining: Not Compiled- you'll need to clean this up)
WebServiceInstance instance = new WebServiceInstance();
string password = instance.PerformGetPassword();
Then, your ASP.NET service is unaware of the encrypted password at all. Additionally, if you have other applications which need to access the same file, they can call the same webservice.
I think this would be much better accomplished by using NTFS permissions on the file. Grant access only to certain users/groups, and ensure that any process requiring access to the secured data is running under the security context of a user that has the correct ACL permissions.

Categories