Must GnuPG to have installed keys for every username profile? - c#

I'm running (on my local machine) the GPG (wingpg ) - command line version.
My login name at win7 - is RoyiN. ( so I have a profile for it)
When I logged in - I've installed the keys (using PKA.exe) both private and public.
All fine.
Then I wrote this code ( which is working )
Process proc = new Process();
proc.StartInfo.FileName = cfg.PGP_Program_FullPath;
proc.StartInfo.UserName = "Royin";
proc.StartInfo.Domain = ...;
proc.StartInfo.Password = ...
proc.StartInfo.Verb = "runas";
proc.Start();
...
However if I write in the UserName field - another user which is also Administrator on my local machine - it says :
gpg: decryption failed: No secret key
Then I swapped again to RoyiN and it did work
Are keys installed per user? is there a way to change that so it will be global ? ( so every user on the machine will be able to use these keys - without having to install the keys under each every profile) ?
It also implies that if i want to allow other's to connect to my computer - I must be logged on with RoiyN 24/7....
Is there any workaround for this ?

There are two different things happening here that are related to the "person" running gpg.
GPG searches for keys in the default keyring files, which are installed in your user profile directory (under a folder named .gnupg). This will be a set of files like pubring.gpg and secring.gpg. This part is easy to work around: pass --secret-keyring "path\to\file" as one of the parameters and it will add that keyring file to its search path. You may want to move it to a publically readable location, like %ALLUSERSPROFILE%, first.
Apart from that, GnuPG keys are generated for and tied to an identity, which is usually your email address. When receiving files, the data will specify the identify of the person who's key is needed to decrypt and/or verify the integrity. When encrypting or signing files, you have to tell GPG who's key to use. Your secret key is used when you sign things for others, or when you decrypt data sent to you. You need to make sure the appropriate keys are in whatever keyring file you use, regardless of where it is.
There's no need for you to actually stay logged in when you run gpg, if you give it an explicit location for the data. It's simply that gpg, by default, reads the current environment variables, set at login, to determine where those things are.
You'll probably need to specify a keyring file path, a secret keyring file path, and a configuration file path if you want to run GPG unattended. The entire list of options you can specify is on the GPG Configuration Options page.
(You may want to try starting with just the --homedir option, which I think will override the default paths for everything else in one go, but you'd need to test that to make sure.)

Yes, they are installed on per-user basis
Simple answer - just export the private/public key pair, and install it for the Administrator account as well.
Although, it'd be better to create a separate key for your automated system with own public key - whoever has your key with a high level of trust, will accept this one as well.

Related

DPAPI ProtectData from different users

I'm using DPAPI ProtectData as follow:
var temp = new byte[32]
{
1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,3,
3,3,3,3,3,3,3,3,
4,4,4,4,4,4,4,4
};
ProtectedData.Protect(temp, null, DataProtectionScope.CurrentUser);
string userName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
Lets assume that now temp look likes:
temp = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,....31 };
I want to execute this code from .exe file and also from my WebService (IIS).
The problem is that if I'm running the code from the exe the current user is MyDomain/Administrator and if i'm running the code from WebService the current user is IIS APPPOOL/MyApp.
How can i solve this issue?
I'm trying to run from the WebService the .exe file as follow:
Process.Start(#"C:\myexe.exe");
But Its not worked from some reason (i have full access to my iis application) and anyway i dont think this is the right solution for this case.
Note: From security reason i cant change from DataProtectionScope.LocalMachine to DataProtectionScope.CurrentUser
If you don't want to use DataProtectionScope.CurrentUser, you could install it as LocalMachine to begin with. Then, have the WebService decrypt it, then re-encrypt it using CurrentUser. Make sure to delete the old value and all its transient copies. In this way, you can take it from LocalMachine and lock it down once the appropriate user is running.
This still leaves the key exposed at LocalMachine level, but for a shorter window of time.
Another solution is to use LocalMachine and use the additional entropy feature with a secret shared between the two executables. This could be an obfuscated value known to the application (no "real" security), or a user-provided password. The user-provided password solution could be more secure but is also more of a pain and more programming overhead.
If the time window between installation and WebService running is small, the first solution may be a good fit.
The problem was solved.
I running the IIS application from local user.
You can find this by selecting the app pool and clicking Advance Settings... under the Actions pane menu. Select Identity and then click the button beside the current user listed. Select Custom account and click Set. Use the format domain\username for the username and enter the password for the user.

In Visual Studio: Trying to delete registry entry but "Requested registry access is not allowed"

I have searched for quite a while on a solution to this. At least I think I understand the problem, but I have yet to come to any solution.
What I need is either some sort of executable or a script that will delete some registry entries. The problem is that the registry entries in question only give read/write access to SYSTEM and no one else. The only way that I can delete them is by going into regedit, setting myself as the owner, and finally setting full control to everyone. Only then can the keys be deleted. I need this process to be in some sort of script though!
So in C#, I first make sure that the software has administrative rights. Then I try to execute the following.
RegistryKey reg_localmachine = RegistryKey.OpenRemoteBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, "");
RegistryKey key = reg_localmachine.OpenSubKey(#"SYSTEM\path to subkey", true);
On the second line, when I try to access the sub key with write access, I get the exception "Requested registry access is not allowed." In order for me to change owner or grant permissions, I need to execute SetAccessControl() on the RegistryKey. In order to set access control, I need write privileges for the key. So I am in this paradox.
Security is there for a reason.
You don't want any old program to be able to come in and start hacking around in the registry.
Each entry in the registry has it's own set of DACLS. There are only two solutions:-
Change the account under which your program is running to an account that has permission to delete the registry entry.
Change the DACLS on the registry entry to include the account your program is running under.

Automatically accessing Truecrypt/Keepass etc. using Windows 7 password

I basically want to automatically mount a (non-system) Truecrypt volume or start Keypass just protected with a single (secure) password, the one windows 7 use for default authentification.
I'm using C#.
Is there anyway to get this password when already being logged in?
Or anyway to get this password while I'm actually typing it during the login process.
For 1. I couldn't find anything (the password is not stored anywhere, just a hash of the password is stored)
For 2. I already tryed some things. I got a program to execute before a user logs on using
GPEDIT.MSC Computer Configuration -> Windows Settings -> Scripts -> StartUp.
Then I tryed to get the password using global key hooks (tryed GetAsyncKeyState and SetWindowsHookEx). Both work well when I try to capture keys when I'm already logged in, but not during the login process.
But I found a keylogging software (Elite Keylogger) which is actually able to get the password that way (when logging in). (I tryed the trial version in VMWare). The other things if tryed in VM Ware and also on a real machine.
Thank you for any help or tips.
I'm doing something similar with batch scripting in order to automatically mount a Truecrypt (or Veracrypt if you prefer) volume upon Windows login with Windows 10. I use a KeePass file setup to use Windows Authentication to securely house the encrypted volume password.
Here's the process:
1) Create your truecrypt or veracrypt non-system volume
2) Create a KeyPass file to hold an entry containing the password to the encrypted volume. Setup the KeyPass file to use windows authentication under the login you will use when you want the drive to automatically mount.
3) Use a batch script like the one below to open the encrypted volume. By housing the password in the KeyPass file with windows authentication you prevent exposing the password in plain-text in the batch file. You'll need to modify this script to your specific system.
#ECHO Mounting Secure Drive (S:)
#ECHO OFF
SETLOCAL EnableDelayedExpansion
SET x=0
FOR /F "usebackq" %%F IN (`"C:\Program Files (x86)\KeePass Password Safe 2\KPScript.exe" -c:GetEntryString C:\<LocationOfYourKeePassFile>\<keepassfilename>.kdbx -useraccount -ref-Title:<entrytitle> -Field:Password`) DO (
SET Pass!x!=%%F
set /a x+=1
)
"C:\Program Files\TrueCrypt\truecrypt" /v \Device\Harddisk0\Partition4 /ls /s /q /p %Pass0% /b /h n /w
4) Lastly, set up a windows Task Scheduler to run the batch upon windows login. Trigger should be "at log on" for the target user account. Action should be "Start a Program" with the target the full path to the batch script
Another feature I like about this approach is that I can save the encrypted file volume password elsewhere incase the windows account is corrupted or deleted. I.e. I may lose access to the KeyPass file that is setup to use windows authentication but if I've saved the actual encrypted disk password somewhere else, I can still restore access to the encrypted volume.
There is a way of unlocking a KeePass database with its master password automatically after the Windows log on. You can use the same database on other computer, because it will not be bound to your Windows user account. See this Super User answer for details.
You change your KeePass database to use your Windows account as the master key, then install the TrueCrypt plugin for KeePass. You then have an entry in KeePass that contain the password for the TrueCrypt mount also registered with the TrueCrypt plugin.
With that in place, after you've logged in, open KeePass and select the entry and click Ctrl + T and you have the volume mounted in TrueCrypt.

Getting a System.UnauthorizedAccess exception when trying to access a file from a standard user account in vista

I am trying to generate a license key file in the common application data location in windows so when a standard user account tries to access my application, the application can check to see if the license key is valid. The license file is being created using an admin account during install but when a standard user account tries to access the file, a System.UnauthroizedAccess exception is thrown.
Here is the code I use to create the directory that I store the license key file.
FileSystemAccessRule fsAccessRules = new FileSystemAccessRule("USERS", FileSystemRights.FullControl, AccessControlType.Allow);
Directory.CreateDirectory(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\COMPANYNAME\\");
Directory.GetAccessControl(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\COMPANYNAME\\").AddAccessRule(fsAccessRules);
Thanks.
I believe the problem is that you're only modifying the FileSystemSecurity object in memory, meaning you're not saving the changes. From the docs for AddAccessRule, it looks like you need to call SetAccessControl to save the changes back to disk after calling AddAccessRule. This will update the security descriptor on the file with the access rule you added.
This CodeProject article has some good sample code: Allow write/modify access to CommonApplicationData
One other thing to consider: if you only need users to be able to read this file, you might consider granting them a more limited set of rights, such as FileSystemRights.Read. This would prevent the users from actually modifying the license file, assuming they don't need that ability.

Know if app is installed for "All users"

How do detect if my app was installed for "All users" or just for one user.
Today I check for files put in either Environment.SpecialFolder.CommonApplicationData or Environment.SpecialFolder.ApplicationData by my installer.
Is there a better way?
To expand on Sachin Gaur's answer:
The S-1-5-18(*) folder is for Local System user - which is used when installing for All Users.
Intallation for the current user would have the product key in a folder named after that user's security identifier (S-something-else).
To get the current user's SID, use System.Security.Principal.WindowsIdentity.GetCurrent() to get a WindowsIdentity. Then, use the User property to get a SecurityIdentifier. Then use ToString() to get the string value.
See MSDN for the GetValue method used to access the registry.
(*) HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\
I hope this may be useful to you.
You can know whether application is installed for all user or not by reading the registry value. For this, you must know the product code of the application:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Products\
To read the registry entry in C#, you can use GetValue() method of Registry class in Microsoft.Win32.

Categories