How secure is encryption provided by CryptProtectData API? - c++

Say, if I encrypt some text using CryptProtectData API without specifying the CRYPTPROTECT_LOCAL_MACHINE flag. If I understood it correctly, doing so will allow only the user that my application was running under to decrypt it.
Let's assume that I saved the resulting ciphertext data in HKCU registry key for my application. So obviously some other users (from other user accounts) will be able to read that data from registry.
My question is, will any other user on that computer be able to decrypt it without having the initial user log in to that machine?

Certainly, no other user can decrypt it. User master key is needed to decrypt the data and it is created by user password. So copying the registry info doesn't allow to decrypt the data.
Master Key, created and encrypted with user's password, is stored in a
separate file in the Master Key storage folder along with other system
data. User's Master Keys are stored in %APPDATA%/Microsoft/Protect/%SID%,
where %APPDATA% is the Application Data directory.
More info here

Related

winapi to read or copy NTUSER.DAT (locked file)

I am trying to load NTUSER.DAT of logged-in local user in registry hive to read their keys from my program running as admin (it has got SeDebugPrivilege, SeBackupPrivilege, etc).
It works when the user is logged-out, and doesn't work when they are logged-in.
The error is:
Error: (32) The process cannot access the file because it is being used by another process
So, is there any Win32 API, or another way, I can copy NTUSER.DAT or read it without relying on a third-party library? I need to do this when they are logged-in.
Shadow Volume Copy copies the whole drive, hence it isn't feasible. Maybe it is possible to unmount their registry hive and then load it using RegLoadKeyA() or something?
I found a workaround,
when the user is logged-off you can load NTUSER.DAT of that user in registry, then read key.
if the user is logged-in, you can read their keys from HKU/user-sid

How can I hide my AWS S3 access key and secret in C++?

I'm using AWS S3 in my C++ app to upload and download files. I've included the access key and secret in my code but I'm worried someone could read them from the binary. Is there any standard technique for obfuscating them?
Update: I'm not running this app on a PC, it's actually on an embedded device so I'm not worried about users reading the key and secret from a file or RAM (accessing the device is a lot harder). What I'm worried about is someone binwalking our update file and pulling the key and secret from the binary.
Storing a secret in computer is not an easy task. One thing you could do is encrypt the key using a password and store the encrypted data in a file. Then when user enters a password you can decrypt the encrypted data using the password and retrieve the key - which you can use.
But this approach will not work for scenarios where the software needs to run without user intervention.
It is better not keeping keys in code. Input when needed.
If kept in code, do not keep the key in simple string. Keep it in some pattern, and generate the key by some algorithm when needed.

wso2: Encrypting ConnectionPassword property for secondary userstore

I am new to wso2 so hopefully I am not missing something obvious but we are trying to sucessfully encrypt the Connection password for a seoncary user store (\repository\deployment\server\userstores\domain.xml) and have it remain usable.
We have used the cipher tool for all our other secret information and have no issues. I have also used the cipher-tool.properties to set up a refence to the secondary user store file and got the connection password encrypted running ciphertool.bat -Dconfigure.
At that point I restart the service and viewing the logs I recieve the following error and none of my secondary user store users are available.
AuthenticationException: [LDAP: error code 49 - 80090308: LdapErr: DSID-0C0903C8, comment: AcceptSecurityContext error, data 52e, v23f0
I have double checked that the value I am encrypting is infact correct. As soon as I change it back to clear text password it works agian.
Do I have to create a custom UserStoreManager in order to acheive this?
Please try setting the alias of the property as "UserStoreManager.Property.ConnectionPassword" both in cipher-tool.properties and cipher-text.properties files.
In cipher-tool.properties
UserStoreManager.Property.ConnectionPassword=../../deployment/server/userstores/prudential.xml//UserStoreManager/Property[#name='ConnectionPassword'], true
In cipher-text.properties
UserStoreManager.Property.ConnectionPassword=[your password]
Run the cipher tool again with -Dconfigure and check.
The cipher tool cannot be used to encrypt Secondary User Store connection passwords. Instead, If you are manually adding a Secondary User Store Configuration file to
<Product_Home>/repository/deployment/server/userstores
directory, you can use the following steps to easily encrypt it.
Step 1 :
Create the Secondary User Store Configuration xml file and remove the “encrypted” attribute present in the relevant property for Connection Password as follows. Note that the password is in plain text.
<Property name=”ConnectionPassword”>admin</Property>
Step 2 :
Now rename the xml file to have a file extension of .enc as shown below.
If the name of the xml file is xyz_com.xml, rename it to
xyz_com.enc
Step 3 :
Drop the .enc file to /repository/deployment/server/userstores directory. Remember to create the “userstores” directory if it is not present.
That is all you have to do. Now you can see that the dropped file has been renamed to an xml file automatically, and when you check the file contents, the “ConnectionPassword” property has been encrypted as shown below. Note the property encrypted=“true” added to the property automatically.
<Property name=”ConnectionPassword” encrypted=”true”>eyJjIjoiTUlETUFuNEJIdjUweWNFeWQ5UThjNGx1ZTExa0NOLzJZbVExTWI3d3djRkZBUnplWmVHSXdzdFNwMTlQdmtjYjdZWHhFejdtOTJhbFFONTRKT3lIczcwNnl1WW9VaHh4d1Zmci9IL3ExWUlOOVowNERvbEZ0aExiNWRnQkhkU3luUWtxVElBc3Jydys5eEVUV1RvU3MyTTgrS0xlWkhtZW12dE1BZFRoTXVIUm9ndEJnWmVvaUxxNDAxQjk1dDgrOUd1eHN0RXE5N0R3TndwZmRlWnpnRk1VMnBEWmthMGFLckdhcTAxTlpLK1kxdG1YMWFhSlJyOGtXMlpRQW1pUm1UV1lZR0g1ZGg1OVNuV21tTzgrMW9lSFJMUU02RjdKT1dSd21xclhWdTg5aTByYWtqMk41cnJ4WGgvaGRmbVk4cmg3VkkwZkJ4M3E1eEN3YjdYRlJnXHUwMDNkXHUwMDNkIiwidCI6IlJTQS9FQ0IvT0FFUHdpdGhTSEExYW5kTUdGMVBhZGRpbmciLCJ0cCI6IjUwMUZDMTQzMkQ4NzE1NURDNDMxMzgyQUVCODQzRUQ1NThBRDYxQjEiLCJ0cGQiOiJTSEEtMSJ9</Property>
You don’t need to restart the server for these changes to be reflected. The file gets hot deployed.
You can find more information regarding encrypting Secondary User Store passwords from this article.

AIR application - unable to open encrypted database using coldfusion.air.SyncManager

I have an AIR application (written in Flex 4.1.0.16076) that copies data from an unencrypted database to an encrypted database and then tries to open the encrypted database using coldfusion.air.SyncManager's openSession method (Coldfusion-AIR integration library from version 9.0.1). Once the encrypted database is created, the application will be distributed only with the encrypted database.
I use com.adobe.air.crypto.EncryptionKeyGenerator to generate encryption key. I use the same password, first to encrypt the database and then try to open it.
The database is successfully generated but when I try to open it, I get the following error:
SQLError: 'Error #3125: Unable to open the database file.', details:'An encryption key cannot be specified when the database is not encrypted.', operation:'open', detailID:'1011'
I'm passing the encryption key to openSession method.
What am I doing wrong? Please help!
Dilip
In my experience, with AIR, a DB must be created as an encrypted DB. An unencrypted DB cannot be later encrypted. Is that what you are trying to do?

Multiuser access to encrypted data

I'm building a server-side application which requires the data the be stored encrypted in the database. When a client accesses the data, it also has to be transferred encrypted. The clients each has a unique login.
My original idea to do this, is to store the data encrypted with a symmetric-algorithm like AES. So when a client wants to access the data the encrypted data is transferred to the client, while the key is encrypted with the public key from the client.
Is this a secure way to do store and transfer the data or is there a better solution to this problem?
Update: If following Søren's suggestion to keep a copy of the AES key encrypted using each client's public key, wouldn't that include the key to be stored somewhere in order to add additional clients or could that be generated in any way?
First you should start by defining some security properties you want to provide, for example:
Is it ok to give different users access to the same secret key? Aka if File1 is AES encrypted with key K, is it a problem if user Alice and user Bob both are given K.
How do I revoke users from the system? (It turns out Bob from scenario 1 is actually a Chinese spy working for our company, how do I securely kick him out of the system).
Does the encrypted data that is saved in the database need to be searched? (This problem is well researched and hard to solve!)
How much (if any) and what plaintext data will be placed into the database to help organize it? Databases expect data to have unique keys associated with them. You need to make sure these keys don't leak information, but are useful enough to retrieve the data later.
How often should secret keys be changed? If you are storing files and multiple users are allowed access to encrypted files, what happens when user X modifies a file? Does the secret key change? Should the new key be sent to all users?
What happens when 2 users modify the same data at the same time? Will the database be able to handle this without modification?
There are many others.
If the server is not trusted and must never see plaintext data, then here's a general overview of a possible solution.
Let the clients managed the crypto completely. Clients authenticate with the server and are allowed to store data into the database. It is the responsibility of the client to make sure the data is encrypted.
In this scenario, keys should be saved securely only on the clients computer. If they must be placed elsewhere, a "master key" could be created.
Secure from what? You need to define your goals more clearly.
The solution would protect the data during transfer, but from your description, the server would have full access to the data (since it'd need to store the AES key unencrypted). In other words, a hacker or burglar with access to the server would have full access to the data.
If secure transmission is what you want, use an SSL / TLS wrapper around the database connection. This is a standard solution from all major vendors.
To secure the data server side, the server should not have the AES key. If the number of clients were limited, the server could store a copy of the AES key for every client, each copy of the key already encrypted with the public key of each client, such that the server never sees the plain text data nor any unencrypted AES keys.
That is indeed the common approach, e.g. also used by NTFS file encryption.