I'm trying to figure out how best to set up Authenticode signing at my workplace. The security implications are stressing me out.
My initial thought is that the person who controls the key should install it to the build server and secure it so that only the build account can access it.
This seems reasonably secure, but it actually isn't. Yes, you can't steal the cert at this point, but if you can create a build you can get the build account to sign any binary.
Does anyone who is familiar with the process give me some pointers?
Indeed, if the key is available for use in build account, it's available for admin's account and it can be used to sign other file. Whatever you give to others' posession is not yours anymore. If you can't secure the server from other people access, then you don't control the server fully, and this leaves a chance for misuse. Frankly speaking, I can't imagine a single way (other than move signing to some other trusted system) to protect the key from misuse. Even when the key can't be extracted or copied (say it's put to cryptotoken), it still can be used in some way.
Related
I'd like to use Windows.Security.Credentials.PasswordVault in my desktop app (WPF-based) to securely store a user's password. I managed to access this Windows 10 API using this MSDN article.
I did some experiments and it appears that any data written to PasswordVault from one desktop app (not a native UWP app) can be read from any other desktop app. Even packaging my desktop app with Desktop Bridge technology and thus having a Package Identity does not fix this vulnerability.
Any ideas how to fix that and be able storing the app's data secure from other apps?
UPDATE: It appeared that PasswordVault adds no extra security over DPAPI. The case is closed with a negative result.
(this is from what I can understand of your post)
There is no real way of preventing data access between desktop apps when using these kind of API's http://www.hanselman.com/blog/SavingAndRetrievingBrowserAndOtherPasswords.aspx tells more about it. You'd probably just want to decrypt your information.
memory access restriction is difficult, code executed by the user is always retrievable by the user so it would be difficult to restrict this.
have you considered using the Windows Data Protection API :
https://msdn.microsoft.com/en-us/library/ms995355.aspx
grabbed straight from the source
DPAPI is an easy-to-use service that will benefit developers who must provide protection for sensitive application data, such as passwords and private keys
WDPAPI uses keys generated by the operating system and Triple DES to encrypt/decrypt your data. Which means your application doesn't have to generate these keys, which is always nice.
You could also use the Rfc2898DeriveBytes class, this uses a pseudo-random number generator to decrypt your password. It's safer than most decrypters since there is no practical way to go back from the result back to the password. This is only really useful for verifying the input password and not retrieving it back again. I have never actually used this myself so I would not be able to help you.
https://msdn.microsoft.com/en-us/library/system.security.cryptography.rfc2898derivebytes(v=vs.110).aspx
see also this post which gives a way better explanation than I can.
How to securely save username/password (local)?
If I misunderstood the question in some way, tell me, I will try to update the answer.
NOTE that modern/metro apps do not have this problem, although they still are accessible in other ways.
The hard truth is that storing a password in a desktop application, 100% securely is simply not possible. However, you can get close to 100%.
Regarding your original approach, PasswordVault uses the Credential Locker service which is built into windows to securely store data. Credential Locker is bound to the user's profile. Therefore, storing your data via PasswordVault is essentially equivalent to the master password approach to protecting data, which I talk about in detail further down. Only difference is that the master password in that case is the user's credentials. This allows applications running during the user's session to access the data.
Note: To be clear, I'm strictly talking about storing it in a way that allows you access to the plain text. That is to say, storing it in an encrypted database of any sort, or encrypting it yourself and storing the ciphertext somewhere. This kind of functionality is necessary in programs like password managers, but not in programs that just require some sort of authentication. If this is not a necessity then I strongly recommend hashing the password, ideally per the instructions laid out in this answer by zaph. (Some more information in this excellent post by Thomas Pornin).
If it is a necessity, things get a bit more complicated: If you want to prevent other programs (or users I suppose) from being able to view the plaintext password, then your only real option is to encrypt it. Storing the ciphertext within PasswordVault is optional since, if you use good encryption, your only weak point is someone discovering your key. Therefore the ciphertext itself can be stored anywhere. That brings us to the key itself.
Depending on how many passwords you're actually trying to store for each program instance, you might not have to worry about generating and securely storing a key at all. If you want to store multiple passwords, then you can simply ask the user to input one master password, perform some salting and hashing on that, and use the result as the encryption key for all other passwords. When it is time for decryption, then ask the user to input it again. If you are storing multiple passwords then I strongly urge you to go with this approach. It is the most secure approach possible. For the rest of my post however, I will roll with the assumption that this is not a viable option.
First off I urge you not to have the same key for every installation. Create a new one for every instance of your program, based on securely generated random data. Resist the temptation to "avoid having to store the key" by having it be generated on the fly every time it is needed, based on information about the system. That is just as secure as hardcoding string superSecretKey = "12345"; into your program. It won't take attackers long to figure out the process.
Now, storing it is the real tricky part. A general rule of infosec is the following:
Nothing is secure once you have physical access
So, ideally, nobody would. Storing the encryption keys on a properly secured remote server minimizes the chances of it being recovered by attackers. Entire books have been written regarding server-side security, so I will not discuss this here.
Another good option is to use an HSM (Hardware Security Module). These nifty little devices are built for the job. Accessing the keys stored in an HSM is pretty much impossible. However, this option is only viable if you know for sure that every user's computer has one of these, such as in an enterprise environment.
.Net provides a solution of sorts, via the configuration system. You can store your key in an encrypted section of your app.config. This is often used for protecting connection strings. There are plenty of resources out there on how to do this. I recommend this fantastic blog post, which will tell you most of what you need to know.
The reason I said earlier not to go with simply generating the key on the fly is because, like storing it as a variable in your code, you rely exclusively on obfuscation to keep it secure. The thing about this approach is that it usually doesn't. However, sometimes you have no other option. Enter White Box cryptography.
White box cryptography is essentially obfuscation taken to the extreme. It is meant to be effective even in a white-box scenario, where the attacker both has access to and can modify the bytecode. It is the epitome of security through obscurity. As opposed to mere constant hiding (infosec speak for the string superSecretKey approach) or generating the key when it is needed, white box cryptography essentially relies on generating the cipher itself on the fly.
Entire papers have been written on it, It is difficult to pull off writing a proper implementation, and your mileage may vary. You should only consider this if you really really really want to do this as securely as possible.
Obfuscation however is still obfuscation. All it can really do is slow the attackers down. The final solution I have to offer might seem backwards, but it works: Do not hide the encryption key digitally. Hide it physically. Have the user insert a usb drive when it is time for encryption, (securely) generate a random key, then write it to the usb drive. Then, whenever it is time for decryption, the user only has to put the drive back in, and your program reads the key off that.
This is a bit similar to the master password approach, in that it leaves it up to the user to keep the key safe. However, it has some notable advantages. For instance, this approach allows for a massive encryption key. A key that can fit in a mere 1 megabyte file can take literally billions of years to break via a brute force attack. Plus, if the key ever gets discovered, the user has only themselves to blame.
In summary, see if you can avoid having to store an encryption key. If you can't, avoid storing it locally at all costs. Otherwise, your only option is to make it as hard for hackers to figure it out as possible. No matter how you choose to do that, make sure that every key is different, so even if attackers do find one, the other users' keys are safe.
Only alternative is to encrypt password with your own private key stored somewhere in your code. (Someone can easily disassemble your code and get the key) and then store encrypted password inside PasswordVault, however the only security you have is any app will not have access to password.
This is dual security, in case of compromised machines, attacker can get access to PasswordVault but not your password as they will need one more private key to decrypt the password and that will be hidden somewhere in your code.
To make it more secure, if you leave your private key on your server and expose an API to encrypt and decrypt password before storing in Vault, will make it most secure. I think this is the reason people have moved on to OAuth (storing OAuth token in PasswordVault) etc rather then storing password in vault.
Ideally, I would recommend not storing password, instead get some token from server and save it and use that token for authentication. And store that token in PasswordVault.
It is always possible to push the security, with miscellaneous encryption and storage strategies. Making something harder is only making the data retrieval longer, never impossible. Hence you need to consider the most appropriate level of protection considering execution cost x time (human and machine) and development cost x time aspects.
If I consider strictly your request, I would simply add a layer (class, interface) to cipher your passwords. Best with asymmetrical encryption (and not RSA). Supposing the other softs are not accessing your program data (program, files OR process), this is sufficient. You can use SSH.NET (https://github.com/sshnet/SSH.NET) to achieve this quickly.
If you would like to push the security and give a certain level of protection against binary reverse-engineering (including the private key retrieval), I recommend a small (process limited) encrypted VM (like Docker, https://blogs.msdn.microsoft.com/mvpawardprogram/2015/12/15/getting-started-with-net-and-docker/) based solution such as Denuvo (https://www.denuvo.com/). The encryption is unique per customer and machine based. You'll have to encapsulated you c# program into a c/c++ program (which acts like a container) that will do all the in-memory ciphering-deciphering.
You can implement your own strategy, depending on the kind of investment and warranty you require.
In case your program is a backend program, you can pick the best strategy (the only I really recommend) of all which is to store the private key at the client side, public key at backend side and have local deciphering, all transmitted password would be hence encrypted. I would like to remark that password and keys are actually different strategies to achieve the same goal: checking if the program talks to the right person without knowing the person's identity; I mean this: instead of storing passwords, better store directly public keys.
Revisiting this rather helpful issue and adding a bit of additional information which might be helpful.
My task was to extend a Win32 application that uses passwords to authenticate with an online service with a "save password" functionality. The idea was to protect the password using Windows Hello (UserConsentVerifier). I was under the impression that Windows surely has something comparable to the macOS keychain.
If you use the Windows Credential Manager APIs (CredReadA, CredWriteA), another application can simply enumerate the credentials and if it knows what to look for (the target name), it will be able to read the credential.
I also explored using DPAPI where you are in charge of storing the encrypted blob yourself, typically in a file. Again, there seems to be no way (except obfuscation) to prevent another application from finding and reading that file. Supplying additional entropy to CryptProtectData and CryptUnprotectData again poses the question of where to store the entropy (typically I assume it would be hard-coded and perhaps obfuscated in the application: this is security by obscurity).
As it turns out, neither DPAPI (CryptProtectData, CryptUnprotectData) nor Windows Credential Manager APIs (CredRead, CredWrite) can prevent another application running under the same user from reading a secret.
What I was actually looking for was something like the macOS keychain, which allows applications to store secrets, define ACLs on those secrets, enforce biometric authentication on accessing the secret, and critically, prevents other applications from reading the secrets.
As it turns out, Windows has a PasswordVault which claims to isolate apps from each other, but its only available to UWP apps:
Represents a Credential Locker of credentials. The contents of the locker are specific to the app or service. Apps and services don't have access to credentials associated with other apps or services.
Is there a way for a Win32 Desktop application to access this functionality? I realize that if a user can be brought to install and run a random app, that app could probably mimic the original application and just prompt the user to enter the secret, but still, it's a little disappointing that there is no app-level separation by default.
Hi security aware people,
I have recently scanned my application with a tool for static code analysis and one of the high severity findings is a hardcoded username and password for creating a connection:
dm.getConnection(databaseUrl,"server","revres");
Why does the scanner think this is a risk for the application? I can see some downsides such as not being able to change the password easily if it's compromised. Theoretically someone could reverse-engineer the binaries to learn the credentials. But I don't see the advantage of storing the credentials in a config file, where they are easy to locate and read, unless they are encrypted. And if I encrypt them, I will be solving the same problem with the encryption key...
Are there any more risks that I cannot see? Or should I use a completely different approach?
Thank you very much.
A fixed password embedded in the code will be the same for every installation, and accessible by anyone with access to the source code or binary (including the installation media).
A password read from a file can be different for each installation, and known only to those who can read the password file.
Typically, your installer will generate a unique password per site, and write that securely to the file to be read by your application. (By "securely", I mean using O_CREAT|O_EXCL to prevent symlink attacks, and with a correct selection of file location and permissions before anyone else can open it).
This is an interesting one, I can give you examples for a .Net application (as you haven't specified running environment / technologies used). Although my guess is Java? I hope this is still relevant and helps you.
My main advice would be to read this article and go from there: Protecting Connection information - MSDN
Here is a page that describes working with encrypted configuration files here
I've seen this solved both using encrypted configuration files and windows authentication. I think that running your application as a user that will be granted access to the relevant stored procedures etc (as little as possible, e.g. Principle of Least Privilege) and furthermore folder access etc is a good route.
I would recommend using both techniques because then you can give relevant local folder access to the pool for IIS and split out your user access in SQL etc. This also makes for better auditing!
This depends on your application needs though. The main reason to make this configurable via a config file or environmental user account I would say is so that when you come to publish your application to production, your developers do not need access to the production user account information and instead can just work with Local / System test / UAT credentials instead.
And of course they are not stored in plain text in your source control checkin then either, which if you host in a private distributed network like GIT could mean that this could be compromised and a hacker would gain access to the credentials.
I think it depends on how accessible / secure your source code or compiled code is. Developers usually have copies of the code on their dev boxes, which are usually not nearly as secure as production servers, and so are much more easily hacked. Generally, a test user / pw is configured on the dev box, and in production, the "real" pw is stored in much more secure config files. Yes, if someone hacked into the server they could easily get the credentials, but that is much more difficult than getting into a dev box in most cases. But like I said it depends. If there is only one dev, and they have a super secure machine they work with, and the repo for their code is also super secure, then there is no effective difference.
What I do is to ask the credentials to end user initially and then encrypt and store them in a file. This way, I don't know their connection details and passwords as a dev. The key is a hashed binary and I store it by poking ekstra bytes in between. One who wants to crack it should find out the algorithm used, key and vector lengths, their location and the start-end positions of the byte sequence keeping the values. A genius, who would also reverse engineer my code to get all this information would break into it (but it might be easier to directly crack the end user's credentials).
I'm going to build a website for file manipulations. The idea is that the user will manage to upload his files to the website, and click the "manipulate" button, then he will get the resulted file. Also the user will have to pay in accordance with the amount of files he's trying to manipulate.
The code for the file manipulation is already written in JAVA.
The thing is, some of these files will probably be truly sensitive and private, so users will not be delighted to upload to my site over the internet.
I thought about making a local version of the website, and let the user download it (the local version) to his computer (and the only access the internet will be for the payment action).
But there seem to be two problems:
When i'll decide to change anything in my website, it will not affect the local users.
The local site will be very easy to "crack" in order not to pay...
This is my first website,
do you have any suggestions of how to solve one of these 2 problems?
Thanks!
Concerning question
(1) you would have to implement some update mechanism, for example your "local web site" (which might be a .jar file containing a web server) could check over the internet if a new version is available and then download and install it (however, you should generally ask for user's permission to do so, as many users are not delighted with silently auto-updating software). Concerning question
(2) you might use some code obfuscator to make your compiled java classes more difficult to decompile, and use an encrypted SSL connection for the transactions related to payment (while checking for server certificate to avoid man-in-the-middle attacks by the end user); however any software that a user can have on its computer will be eventually cracked by somebody. Therefore, the best solution is possibly to keep all on your server, while securing as much as possible the whole: use encrypted connections with SSL for everything, or even if the files are highly sensitive, provide a public key so users can encrypt their files with GPG (or similar software) before sending them to the site, and encrypt the files to be sent back to the user by using its public key (that he/she has to provide you and that is not critical at all to be transferred over the internet). Also carefully check the security of your web server and all the software running on it, to avoid bugs that might allow somebody to hack into it. Using the encryption with GPG/public keys and only storing encrypted data on your server might be already a good protection (but you have to make sure that it is impossible to get your private key in any way!).
I know it is possible to encrypt the connection-string stored in the web.config,
And I know you could never be too safe, but since the web.config cannot be viewed or downloaded, why is it needed? in what way is it more secure?
[EDIT:] I'm not using a shared-hosting server.
If you deploy your website to a customer's web server and want to keep the credentials secret.
If someone breaks into your server, he is not able to see all sensitive information without any further work. And if you deploy your application to some "cloud" service your credentials won't be exposed to everyone maintaining the service.
Edit: Also some Administrator or users that have access to the Server won't be able read the clear text credentials.
I think you have answered your own question by saying "you could never be too safe"
The fact that web.config cannot be viewed or downloaded is not a guarantee that an attack from inside your organization could not occur. Someone with the right access could breach the security and get the data if it is visible in plain sight. While as you said, attack via Http is unlikely to get this file, others who have right access could still access through other means such as remote file access, remote desktop, etc. Encrypting + assigning proper access/authorization are making a tad more difficult for the attacker to try to break your system.
In security, you simply have to be paranoid and took every measure you think possible in order to make the data as safe as possible and it's your job giving the attacker a hard time to retrieve any information. I don't think there is such thing as 100% secure. In some sense, you would always be vulnerable to a security threat, all we could do is try to minimize it as much as possible.
Suppose I need a login mechanism for a program in a Local Area Network in a company, my guess is to store a file with username/password pairs on the local server, but would the Java program be able to read/write information to the file from a local PC? It's my first time dealing with such a task so I am a bit confused about this. Also I want to store only the passwords for the program, not the PC user.
Hmm, you should do it differently imho.
Write a service to authenticate against. The service is the only application allowed to read the password-file and runs on the server. The clients authenticate against that service. Once the user is authenticated, pass him an identification token that is tied to his machine and can expire after a period. Also, the machine needs to transmit some sort of digital signature to verify its integrity in an asynchronous manner. If you do this, you can verify that only authenticated users, who really are who they claim to be can access services which require the authentication token, including the authentication service itself.
BUT: I strongly suggest you get something that has already been built for such tasks. There're things like Kerberos which have been built for such tasks. I am not a sysadmin, you might ask again at serverfault or so.
Additionally, I'd like to state that MD5 is not the toughest hash anymore. AFAIK blowfish is the way to go today, I might be wrong, though. It's tougher than MD5 anyway, which is prone to collision-attacks already.