Aren't private keys vulnerable in memory? - security

I'm trying to understand what happens when I use a password-protected private key to generate a message digest.
I read here that password-protected private keys are just encrypted using a password-based symmetric key.
Once I enter the correct password, how is a digest generated without exposing the unprotected private key?

At some point the cryptographic primitives in your code will need to access and use the actual value of the key. There's simply no way around that. In a simple analogy, you cannot compute a + b if you don't know a.
The big question concerning secure software design thus boils down to how long sensitive information will persist in an unprotected state. Any sort of password caching is your enemy here, but even if neither the password nor the decrypted key are explicitly cached, they're still in memory at some point. Freezing a computer with liquid nitrogen can keep the memory content intact for a considerable amount of time, and forcing a swap-to-disk is another problem.
Good cryptographic programs should take care to overwrite the memory content as promptly as feasible and minimize the amount of time that sensitive information is retained in readable form. This requires careful analysis of which information is critical (e.g. the user's password input), and platform-specific knowledge of memory management (e.g. can you request non-pageable memory?).
It all depends on your threat model - which sort of attack do you need to protect against? If a rootkit monitors all your memory, you might be in trouble, though that rootkit would probably just read the user's password entry from the keyboard anyway.
This is a complicated issue, and there's extensive research into secure hardware design. In general, the more access an attacker has to your machine, the more likely it is that she'll be able to read sensitive data. Good design can only strive to minimize the surface of attack.

At some point the key has to be available in memory for use by the crypto algorithm.
There have been interesting attacks to try and grab valuable information from memory. One I read about involved plugging a device into a Firewire controller and using direct memory access to poke around for interesting things.
http://www.hermann-uwe.de/blog/physical-memory-attacks-via-firewire-dma-part-1-overview-and-mitigation
It's entirely possible that either a program with necessary privilege to read the memory location holding the key, or hardware utilizing DMA, can grab a private key from RAM.

Generally yes, once decrypted the key will be stored in system memory as cleartext until the application or operating system marks it's address as re-writable. With PGP Desktop, it's possible to manually clear the cached private key, a nice feature I wish more applications offered.

Yes, it is exposed in RAM, and unless the operating system supports protection of memory against paging, and the application uses that feature, the private key can be paged to disk "in the clear." Development tools and active attacks can look for it in memory.
This is one reason specialized hardware cryptographic modules exist. These perform operations with the private key in their tamper-proof memory space; the application can never access the private key itself, it delegates cryptographic operations to the device.

Related

How does PasswordVault protect passwords? [duplicate]

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.

What's the best place to hide long lived encryption keys

I am considering encryption options for a new Sybase project. I am thinking that Sybase encryption is the wrong strategy because a) dba's can get in, and b) if and when we migrate to SQL Server or Oracle I don't want to deal with different encryption strategies.
Therefore I'm thinking to encrypt the sensitive data (symmetric encryption) in my Java code before storing it in the DB.
Now, the encrypted fields better not have their encryption key changed, ever, except in a very controlled environment, which for me effectively means never. So it's going to be a permanent password.
The question is, where should I keep this password in a way that it is accessible from the program but not accessible to anyone else. If it's in a properties file, any developer with access to our Git repo could see it.
We could hard code it in the source code, but good lawd, that's a bad practice.
We could generate it in source, like the 10th Fibonacci or 3!+8! that would be hard to locate, but it's still rather exposed.
We could have the sa's maintain it in the environment, but then where do they file it for future reference?
So many poor choices. Are there any good ones?
Simply using some secret code to create the key on the fly is both an insecure method and produces a poor key. The DB keep needs to be a random byte array. Keep in mind that the key needs to be in memory when used which will be most of the time for the DB.
WRT using the DB encryption, examine closely if the algorithm is fully specified and compatibility to another DB. There is also the possibility that the entire DB will need to be run-off and then added to a new DB, in that case using the internal DB encryption will be transparent.
You really need to consider needing to be able to change the encryption key in the future, what will you do if it is ever compromised? There are solutions to this dilemma. There may be a substantial performance penalty performing the encryption outside the DB, there is a substantial setup time for each new encryption operation. Also since not all columns will be encrypted (a good guess) that information is not shared by the DB and the outside encryption code, that coupling is not good for design nor maintenance.
Do not connect the DB server to the Internet, make it separate and connected with a non-networked connection such as direct Ethernet. This also limited the number of admin users of the only system that contains the encryption key.
Another important part of the solution is to restrict admin access to the server. This includes requiring two-factor authentication as well as severely limiting the number of administrators. You need to control the second-factor to physical serial-numbered devices owned by the organization so that they can be positively retrieved on personnel changes and not copied. Personally I favor RSA SecureID (or similar) hardware devices, there is positive control.
Finally in answer to the question, keep the key in a file on the DB server secured as above, that is with no Internet access and restricted admin access.

How to Introspect normal world from secure world using TrustZone?

I have learned that secure world can protect critical data from being accessed by normal world, What I don't understand is that how do I measure the integrity of normal world from secure world.
I find some relevant work in the Samsung TZ-RKP and SierraTEE, in which they both implement a feature that could measure the integrity of normal world. But they didn't give technical details. I have two questions and I'd appreciate it very much if anyone could give me some clues.
Suppose I want to see what processes are running in the normal world, do I have to use a kernel module in the normal world to help me do this? If so, how do I make sure that it has passed the right result to the secure world? To be precise, how do I check that wether the kernel has been comprimised?
Suppose I have a RSA key pair and I keep the private key in the secure world. When a process request to decrypt some data, how does secure world get to know whether the request is from a legislative process? A whitelist mechanism might help, but what if the kernel in normal world has been compromised and the adversary pretend to be legislative? The secure world seems to know nothing about what is happening in the normal world.
Even if it can be sure that it is from a legislative process and it decrypts the data using the private key, the decrypted data would still be returned back to the normal world region somehow(ie. shared memory) and the decrypted data could still be leaked. So what is the point of keeping a private key in secure world?
BTW, I'm using an armv8 board.
Thanks in advance. It would be great if you could provide me with some examples.
Trust-zone is not by itself a security system. You have to engineer that. Also, there are many different types of security. For instance, you are assuming a software attack yet there are many physical attacks against a system (like I guess you describe). Something must be a trusted computing base (TCB); Ie, some code that you assume can not be compromised. A normal world kernel is probably too large to be part of the TCB, yet it can be a good first line of defence. An exploit against it is only a priveledge elevation from user to supervisor. Your TrustZone API should expect untrusted data (Ie, the normal world kernel trying buffer overflows and API mis-use, etc).
The key point here is that TZASC and other bus peripherals can grant access for the secure world to read/write normal world memory. You would have to verify MMU tables, and other data structures for the case of a full blown OS like Linux. Module loading, processes running, etc. all need verification. However, if you have a much simpler system in the normal world it may be possible to verify it. Most likely you have to settle for a portion of it. Random sampling of the PC might be a deterrent; but nothing will be fool-proof unless the normal world is proof carrying code.
Suppose I want to see what processes are running in the normal world, do I have to use a kernel module in the normal world to help me do this? If so, how do I make sure that it has passed the right result to the secure world? To be precise, how do I check that whether the kernel has been comprimised?
Your secure world can contain an OS (or primitive scheduler) which will periodically check the normal world code integrity. There are hardware modules like an RTIC, etc. You can also use the TZASC to lock the kernel code to normal user (no access) and normal supervisor as read-only. comprimised is an overloaded word. At some point you must trust something. Can the private key be replicated if the normal super is compromised? You have to define your security goals. In the any sense/meaning, of course the normal world kernel can be compromised. You don't have a complete specification of its behaviour to verify from the secure world.
Suppose I have a RSA key pair and I keep the private key in the secure world. When a process request to decrypt some data, how does secure world get to know whether the request is from a legislative process? A whitelist mechanism might help, but what if the kernel in normal world has been compromised and the adversary pretend to be legislative? The secure world seems to know nothing about what is happening in the normal world.
Your secure world probably has to have some co-operation from the encrypting entity. You could limit the amount of decrypts without some from of verification for instance. It seems that the most valuable thing is the private RSA key. If you allow the normal world to request decryption, then that is your issue and not Trustzone's? You have to handle this using normal mechanisms with cryptography and unknown/untrusted hosts. Is the RSA key pair global or per device? Do you support revocation, etc. It is in your system and TrustZone is only part of it.

Tips on encryption for storage at rest (AES, SHA??)

I wanted to know what is the best way to encrypt storage at rest. Lets say financial information for 1000 users is on a system. Besides making sure nobody unauthorized gets to how do we encrypt the data that is being used everyday so that if god forbid they get it, it should be impossible for them to decode or read?
I believe AES is a correct measure?? How can i implement AES using PHP for phpmyadmin data?
Neither SHA nor MD5 are encryption algorithms, so forget them for now.
The answer to your question is more organizational then technical. First you need to identify what storage you plan to use for the data. If it is the DBMS, then (a) it can offer certain encryption and authentication mechanisms, and (b) you can store the files of the DB on the encrypted storage.
If you have files (either the data itself or the DB with the data), you can store them on encrypted disk. This can be an encrypted NTFS disk or virtual encrypted disk (the one which resides in a file and is mounted as a virtual disk by software).
If you create backups of the data, then backup tools usually offer encryption mechanisms too.
In all of the above cases used algorithms don't matter too much: modern algorithms, offered by above mentioned mechanisms, are secure enough given that you choose 128-bit or larger key for symmetric encryption and choose long passphrase (more than 22 characters if you only use [A-z0-9] alphabet for 128-bit symmetric encryption).
There exists symmetric encryption and public-key encryption (PKI encryption). PKI lets you encrypt the files using public keys (private key is used for decryption), and one of the benefits is that you can encrypt the data for several different private keys. This means that any of the given set of keys can be used for decryption, and the owner of one key doesn't need another key for decryption. The benefit is that you can assign keys to certain users or roles instead of sharing a single passhprase.
The above is just a small guideline and you need to learn a lot (or better involve a security specialist) before you implement the solution, cause security made wrong is worse then no security at all (cause it gives false sense of protection and this makes people careless).
That depends on your platform; most modern operating systems offer disk encryption options with various degrees of security. Note that SHA and MD5 are hash algorithms and thus unsuitable for encryption.
I'd base my choice of algorithm on the capabilities of the system that is supposed to work with the data. Some CPUs have special instructions for AES processing, which gives a significant speed boost here; also, there are harddisk controllers that include encryption support.
Dedicated hardware has two major advantages: it is significantly faster, and it is more difficult to retrieve the symmetric key as a prelude to stealing the actual disk drives.

Security risk when store private data

I have to handle some sensitive data in my application, such as passwords, credit card information, etc.
What are possible security risks I could have and how can I avoid them?
Don't store Credit Card Information (in some jurisdictions, you might be breaking the law by doing so, or at least falling foul of a commercial agreement)
You don't say where your sensitive data is stored, but encypting it is the usual approach. There are two forms symmetric and asymmetric. Symmetric means you use the same key for encrypting and decrypting. Asymmetric consists of a public/private key pair.
Passwords: store only a salted hash (i.e. un-reversible) of your passwords, and compare with a similarly salted hash of an entered password.
Be aware that you really shouldn't store credit card info in any shape or form on a web server.
Bit of info on doing this in a web environment, which is my background:
If a website (or any application) needs to store card info, it should comply with the PCI DSS (Payment Cards Industry Data Security Standard). Amongst other things, it requires that the data be held encrypted on a separate server that isn't publicly accessible (IE: isn't hosting the site) and has a separate firewall between it and the webserver. Penalties for not complying are potentially very large in the event of any fraudulent activity following a security breach, and can include them ceasing working with you - it pretty much reserves the right for the them to chargeback any losses from the fraud to you (from my interpretation as a non legal person)
More on it here: https://www.pcisecuritystandards.org/security_standards/pci_dss.shtml
Obviously, this may be expensive compared to shared hosting, as you immediately need two servers and a load of networking gear. Which is why people don't often do this.
I would be inclined to perform some form of reversible encryption on the information as it's being stored, something like:
$card = myEncryptionFunction($input);
A little more information on the nature of your application wouldn't hurt though.
I'd be using reversible encryption on the database data. Make sure this data doesn't seep into log-files too, log derived information instead. Consider how yoǘ'll handle different environments - normally you want to not use production data in your test environments. So even though you may consider copying production data back to test systems, you should probably generate fake data for the sensitive parts.
It's been already said that you shouldn't store CC especially CVV2 information in your database, avoid where possible.
If you store CC + CVV2 then consider using asymmetric encryption and store your private key in another server. Otherwise an attacker who can access the data 99% can access the key and the whole encryption would be pointless.
Passwords should be stored as one way hashed.
After all these you need to ensure that your application is secure against vulnerabilities such as SQL Injeciton, remote code execution etc.
Don't forget Even when an attacker can't read previous data they can plant a backdoor for the next data.

Resources