How to generate new guid for each installed instance? - c#

I use C#. Is it possible to make every installed instance has different guid?
To be more specific, let's say I have an application called "abc" and a setup for it. Each time it is installed on a different computer, I want it's assembly guid to be regenerated. If it's not possible, I always listen to new ideas.
Thanks in advance.

Why not just check for a file on startup ? You could then Generate a UID and insert it into the file. So the next time the Application loads you would be able to read the UID from the file ?
This could be either on a per user basis (where you would put the file in their user directory) or per installation (Where the file is right next to the executable or somewhere outside of the current user directory, just watch out for Windows File Permissions!).

It sounds like you want to uniquely identify the machine on which your application is installed. There are many ways to do this - but changing the assembly GUID is not a good option for this.
Instead, you should look at the machine configuration, and generate a unique Id from it rather than generating a random id. For example, you could take the machines MAC address as a starting point.
This would make the machines unique id deterministic, meaning you don't need to store it anywhere, you can generate it each time you need it :)
Early versions of the GUID specification (version 1) actually used the machines MAC address as part of the GUID - however this led to security problems and was the cause of the Melissa virus. The modern GUID specification does not use MAC address data.

Related

.NET Windows API Check if folder accessed

I am searching for a function that allows me to put a dialog-window(w/ a password query) before the folder is accessed. Is there such a function? Also, this would be great if this protection is there before any program, even Windows Explorer/cmd.exe are allowed to access those files. Is that possible to make?
I'm not using something like IOContainer, passwd. protected ZIPs or any other things that are too slow, because I guess 20GB in one file are a bit overkill and it would take ages to decrypt that file. Is there maybe a VFS solution for C# which supports password protection and can be used as a normal filesystem or folder on the disk?
Thanks!
There exist two options. The simpler one is to have a virtual file system mapped from the file. Our product, SolFS (OS edition), does exactly what you are asking in the second part of your question - it provides a container with optional encryption, which is exposed as a virtual drive so that access to the contents is transparent. Decryption in such systems is done in pages, so 20GB-large file won't be decrypted in whole as you worry.
Another option is to employ a filesystem filter driver, which will intercept requests for directory opening, and will ask the user for a password. This approach is possible (we even have a product for this, called CallbackFilter), but there are two drawbacks in it: first, it's not impossible to remove the driver, leaving the data unprotected. And the second problem is that if you ask the user for a password in a callback, while the OS is waiting for access to the directory, you can end up in a deadlock or a timeout while the user is thinking.
With these two limitations in mind something like SolFS is the preferred and recommended approach.
PS: and we have free non-commercial licenses as well.

C# Application License Components and Controls [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
If I have 5 target computers and I am going to install my application to one of those target computers. How I prevent users from copying my application to other target computers?
To make it clear, I don't want them to copy my application after installation (They should not copy my application from the installed application folder). The problem is now I setup and deploy my application using Visual Studio 2010 Setup and Deployment, but anyone can copy my application folder after the installation for example, my application folder (exe, DLLs, and resources) locates at "Program Files/MyApplication". They actually can copy my application from that folder and paste it to other computers then use it. Of course, they can copy it but I think they should not be able to use my copied application right? Is there a way to protect them copying my application? I have to write an additional code?
I am really new for software distribution. Please guide me what I have to do.
Thanks
You can use Rhino Licensing framework for license file generation. It has LicenseGenerator class which has a Generate method. Here is what it looks like:
public string Generate(string name, Guid id, DateTime expirationDate, IDictionary<string, string> attributes, LicenseType licenseType);
Generate method takes the name of the licensee. Unique id for the license which can be generate as Guid.NewGuid(), the expiration date and the attributes dictionary is a place where you can store a custom key value pair in the license file.
The way it can works is that, you can embed the information of the machine in the license and in the verification phase you can check whether the license belongs to the same machine. This means that you can not copy license file of one machine and put it on another machine because it won't work.
In the license file you can store the following information:
The expiry date of the license
Name of the person for whom the license is generated
Hash calculated based on the system information
The industry-standard way of preventing users from running an application on more than one machine is indeed to lock your product to some parameters of that system. However, you need to think about the following issues to avoid future work or upset customers down the road. Crude systems that don't deal with these issues have given node-locking a bad name, but when done properly node-locking is unobtrusive, flexible and secure:
How will you accurately obtain the system parameters you will lock to? Asking users to read/type them is a common source of error, for example by mis-reading an 'l' for a '1' or a '0' for an 'O'.
The MAC address is commonly used for node-locking, but this is a poor choice as the MAC address can be set by an admin under many operating systems.
Say you lock a license to several parameters of the system. What will happen if the user does a minor system upgrade, so causing one of them to change? They won't be happy if your app suddenly refuses to run.
Users will want to move their license to a different machine at some point. You'll need to think about how you support this without making it a security hole.
Users machines will crash - it happens. How can they get their license running again on their new/rebuilt system?
Just some issues we've encountered and dealt with in our solutions. Hope this helps.
I use Infralution License Tracker. It is payware but allows for licensing of some part or all of an application. It also allows for key verification on on-line verification. It is possible to use customer information to generate the key so it should be feasible to register using information from the target computer.
http://www.infralution.com/licensing.html
When you want it really easy you can use LimeLM.
Simple online-verification with a trial option.
You need to use machine-locked / activated licenses to prevent this. This ensures that the license can only be validated from a single machine - if license validation fails, you can decide what steps to take - whether to exit the app, show a message to the user, allow a grace period, etc.
Try CryptoLicensing which supports activated / machine-locked licenses.
DISCLAIMER: I work for LogicNP Software, the developer of CryptoLicensing.

How should I stop users from modifying my data files?

I'm working on a project that is going to replace legacy software on our manufacturing floor. One of my concerns is that currently, config files, script caches, etc are all plain text, stored on the system that the user is using. A lot of this stuff is going to get pushed off to limit access network locations, but things like config files stay local. It's already been an issue with users thinking that they know what they're doing with the system, and modifying the config files. I don't want this happening any more in the new software. How should I prevent this? Encryption? Do some sort of signing/checksum with a database lookup? What kind of features does C#/.NET offer to help me out with this?
UPDATE: Just to address some things that were brought up in comments, every user on the manufacturing floor has admin access to the system they're working on. This isn't likely to change soon as most of the security comes from limiting access to folders on the network, web services, and databases. Permissions would be ideal, I agree, but I have to work in the environment that I'm provided. I plan to bring it up in a meeting that I have with IS to see if this is a possibility, but assume for now that this will be on a system where the user has full access.
This isn't a C# coding issue, it's a system configuration issue. Set up the machine such that the users have normal (non-admin) accounts. Set the file permissions on the config files you're worried about so that anyone (including your app running as current user) can read the config files, but only an admin can write the config files. Finally, don't give the users the admin password. ;>
If your app needs to be able to write the the config files also, you'll have to add code to transition into admin mode within your app, preferably only around the write operation.
To prevent the average end-user from modifying config files by hand, you could simply sign the config file using the SHA of its contents concatenated with some secret factor known only by the program. This is obviously not a true or perfect secret, but it's enough to prevent simple tampering by end-users.
Basically (pseudo-code):
function isValidConfig(configPath, signaturePath) {
return readFile(signaturePath) == SHA(readFile(configPath) + secret)
}
function writeConfig(contents, configPath, signaturePath) {
writeFile(configPath, contents)
writeFile(signaturePath, SHA(contents + secret))
}
Short of decompiling the program, they won't be able to tamper with the config. I assume you don't have l33t crax0rs on your manufacturing floor...
This seems like a good job for a Digital Signature. A Digital signature will provide integrity and authentication of your data. Meaning the digital signature will detect if the data (config file) has been changed, and that the data originated from a trusted source. A digital signature is created by performing a hash of the data and then encrypting the hash with a private key from a public/private pair. The Application will decrypt the encrypted hash, calculate hash of the data, and compare the decrypted hash to the calculated hash. If the hashes match the data is valid. If they do not match the data has been altered.
.Net contains these functions in DSACryptoServiceProvider.VerifyHash
Of course if you do not want to go through the hassle of creating a public/private key pair you could just go with a simple hash of the config file to make sure it hasn't been altered.
The really important question is; what are you going to do when the application detects an altered config file?
Are you going to have the application quit, lock out certain functions, send an e-mail to you, try to obtain a good copy of a config file? These actions are referred to as the penalty for failing the integrity check. Right now your application is not performing integrity checks on the config file, but when you add the check you will need to decide the best course of action for a failure.
An option is for you to move as much as you can from the config file to either IsolatedStorage or even better to the database. It would be highly unlikely that a typical user would know how to access them.
I'd keep the files in some kind of structured storage, be it isolated storage, slightly encrypted ZIP file or something like our SolFS virtual file system (also encrypted). The secondary benefit of having one file is that it can be copied for backup easily.
I'm not an expert in local security but maybe you could use file system permissions to prevent use access to a given folder or file.
Then, if you application needs to access this file, you will have to launch your application with different windows account that has the right to modify your file.

How to make my program not run on other computers?

I have an assignment, and it has (amongst others) two demands:
make an installer
make it so that if it is installed on one computer, anyone trying to run the same files on another computer will fail.
I'm using VS9 (2008) express, I think I can do the installer part, but I'm not sure how to do the "security" part. I don't need any hard to crack safety, just a dumb condition that will stop most users from copying the files to another computer. (Like checking the MAC address).
Any ideas?
EDIT:
I would like to check the MAC address but I want the program finalized during installation. Meaning that after I install I can't move the program to another machine. It also does not have to be a very smart or difficult condition, just bare minimum. I just don't know how to do it in the installation.
EDIT:
It's sad I don't have the complete VS then I would be able to do it easily.
If you're looking for some way to mark the first computer as the "authorized" computer, then you need some external service you can ask for permission to launch.
The first person to ask permission would be allowed, the rest would be prevented.
You'll also need to come up with some way of identifying a particular instance of your application that's different for every install.
If your app needs to be authorized for the machine, then you will need to calculate some fingerprint for the machine it can use each time (eg across installs).
[Edit]
This approach is useful when you're worried about copies of the installer being distributed as well. You did specify that its ok to install on multiple machines, so in that case MasterMind's approach is superior. It will work, and does not requires a 3rd party server
[Edit 2]
If you're looking for info on how to build a custom installer, try here
First of all, come up with some function to generate a unique PC signature, like Windows does for activation.
Your installer will be creating this signature and writing it to a local file (better encrypted). You can create a simple console executable to generate this file and include that executable into your installer package, setting it up to run silently after the successful installation.
Your program when starting will be creating the signature again using the same algorithm and comparing it to the one created during installation. If the new signature is different from the original one or the signature file is missing, then exit without loading the UI.
ADDED: If you don't need it very complex, you can just choose a few unique values like the MAC address you suggested, maybe the hard drive serial number, mainboard serial number, concatenate them into a single string and generate the hash out of it.
This approach will allow for an unlimited number of copies to run (but each installation will only be workable on one single machine where it was installed). If you stick to the identification by hardware (or OS product key as well), then the application can run on various OS installations on the same machine.
This strategy, however, implies that you control all installations (or perform them yourself) or absolutely trust your client not to install additional copies elsewhere or distribute your installer. If you need that kind of protection as well, then you should consider product activation. It can be quite complicated if you do it yourself. There are however third party products to help you. Some offer product activation services: Google: activation service
Once you have a decent fingerprint, the rest is easy. Personally I'd take something like the MAC address and the windows product ID (at HKLM\Software\Microsoft\Windows\CurrentVersion\ProductId) and use a hashing algorithm to get something reasonably obscure.
edit:
Here's a question that shows you how to get your MAC address as a string:
Read MAC Address from network adapter in .NET
Then grab your windows product ID (in case they don't have a network adapter) from the above registry key. Concatenate both strings and do a GetHashCode() (or use your favorite hashing algorithm) on the result. This is a simple way to get a UID for a computer.
Write the hash to a file or to a registry entry when your installer is executing and check it when your program starts up.
Consider using two or more values that potentially identify the machine, e.g.
Windows product code
Volume serial number of the C: drive
MAC address of an ethernet interface
And if just one of these changes but the others match, update that one value in the registry and continue running normally. Hard drives get replaced (regularly), Windows gets upgraded (occasionally), Ethernet adapters get replaced (rarely but it does happen.) It can be very frustrating when old software stops working because of this.
Bare minimum answer, assuming the only requirement here is that the software should run if installed through the installer, and won't run if copied to another computer:
Write a simple key to the registry. Most likely your product's version number, incase they copy a newer version to the computer, it has a different number to check for.
In your software, just make sure this registry value exists.
For packaging installations, I enjoy using NSIS which has simple methods for writing to the registry.
I like the idea of checking the MAC address.
I have also seen product key/online activation combinations where you enter the product key and the software contacts a web service that logs the product key and # of installs.
This isn't the most secure option or anything but you did say it didn't have to be smart...
On install, you could set a program variable to be the machine name (or a hash of it if you like).
Like:
myProgram.Properties.Settings.Default.Machine = System.Environment.MachineName;
myProgram.Properties.Settings.Default.Save();
then check that on startup:
if (System.Environment.MachineName != myProgram.Properties.Settings.Default.Machine)
{
MessageBox.Show("Can't run on this computer");
this.Close();
}
To get the installer to only work for one machine, you'd pretty much have to build it for the target machine. I dont think it would be possible to make an installer that assumes the first machine it sees is it's mommy and is attached for life.
-1 for clinging to an antiquated license-restriction policy that is a poor practice in general. Hardware dongles and "device detection" are SO 1990.
People own more than one computer. They buy new computers. They upgrade their computers. Computers break, resulting in replacement of motherboards or network cards.
All of these, given your design, will result in honest, paying customers being locked out of what they've paid for and will have to call you for support to "reset" their activation.
And each time you do so, your overhead will increase by, very likely, more than the actual cost of a license.
I'm not suggesting you give up and just send your app off to the torrentverse, but you should think more creatively about how to allow customers the freedom to use what they paid for, keep your support costs low, and discourage pirates.
One creative solution would be to cache the user's settings on your server, keyed by their serial number, and synchronize them every time the application starts and is connected to the Net.
This will allow a user to install the app on, say, both a laptop and desktop, and will actually be a value-add for customers because their settings are synchronized between devices.
But it actively discourages users from sharing their license key, since doing so would mean they would be sharing their settings with every pirate user, or that they would have to remember to stay disconnected from the Interwebs when they open or close the app.

How do I store information in my executable in .Net

I'd like to bind a configuration file to my executable. I'd like to do this by storing an MD5 hash of the file inside the executable. This should keep anyone but the executable from modifying the file.
Essentially if someone modifies this file outside of the program the program should fail to load it again.
EDIT: The program processes credit card information so being able to change the configuration in any way could be a potential security risk. This software will be distributed to a large number of clients. Ideally client should have a configuration that is tied directly to the executable. This will hopefully keep a hacker from being able to get a fake configuration into place.
The configuration still needs to be editable though so compiling an individual copy for each customer is not an option.
It's important that this be dynamic. So that I can tie the hash to the configuration file as the configuration changes.
A better solution is to store the MD5 in the configuration file. But instead of the MD5 being just of the configuration file, also include some secret "key" value, like a fixed guid, in the MD5.
write(MD5(SecretKey + ConfigFileText));
Then you simply remove that MD5 and rehash the file (including your secret key). If the MD5's are the same, then no-one modified it. This prevents someone from modifying it and re-applying the MD5 since they don't know your secret key.
Keep in mind this is a fairly weak solution (as is the one you are suggesting) as they could easily track into your program to find the key or where the MD5 is stored.
A better solution would be to use a public key system and sign the configuration file. Again that is weak since that would require the private key to be stored on their local machine. Pretty much anything that is contained on their local PC can be bypassed with enough effort.
If you REALLY want to store the information in your executable (which I would discourage) then you can just try appending it at the end of the EXE. That is usually safe. Modifying executable programs is virus like behavior and most operating system security will try to stop you too. If your program is in the Program Files directory, and your configuration file is in the Application Data directory, and the user is logged in as a non-administrator (in XP or Vista), then you will be unable to update the EXE.
Update: I don't care if you are using Asymmetric encryption, RSA or Quantum cryptography, if you are storing your keys on the user's computer (which you must do unless you route it all through a web service) then the user can find your keys, even if it means inspecting the registers on the CPU at run time! You are only buying yourself a moderate level of security, so stick with something that is simple. To prevent modification the solution I suggested is the best. To prevent reading then encrypt it, and if you are storing your key locally then use AES Rijndael.
Update: The FixedGUID / SecretKey could alternatively be generated at install time and stored somewhere "secret" in the registry. Or you could generate it every time you use it from hardware configuration. Then you are getting more complicated. How you want to do this to allow for moderate levels of hardware changes would be to take 6 different signatures, and hash your configuration file 6 times - once with each. Combine each one with a 2nd secret value, like the GUID mentioned above (either global or generated at install). Then when you check you verify each hash separately. As long as they have 3 out of 6 (or whatever your tolerance is) then you accept it. Next time you write it you hash it with the new hardware configuration. This allows them to slowly swap out hardware over time and get a whole new system. . . Maybe that is a weakness. It all comes down to your tolerance. There are variations based on tighter tolerances.
UPDATE: For a Credit Card system you might want to consider some real security. You should retain the services of a security and cryptography consultant. More information needs to be exchanged. They need to analyze your specific needs and risks.
Also, if you want security with .NET you need to first start with a really good .NET obfuscator (just Google it). A .NET assembly is way to easy to disassemble and get at the source code and read all your secrets. Not to sound a like a broken record, but anything that depends on the security of your user's system is fundamentally flawed from the beginning.
Out of pure curiosity, what's your reasoning for never wanting to load the file if it's been changed?
Why not just keep all of the configuration information compiled in the executable? Why bother with an external file at all?
Edit
I just read your edit about this being a credit card info program. That poses a very interesting challenge.
I would think, for that level of security, some sort of pretty major encryption would be necessary but I don't know anything about handling that sort of thing in such a way that the cryptographic secrets can't just be extracted from the executable.
Is authenticating against some sort of online source a possibility?
I'd suggest you use a Assymmetric Key Encryption to encrypt your configuration file, wherever they are stored, inside the executable or not.
If I remember correctly, RSA is one the variants.
For the explanation of it, see Public-key cryptography on Wikipedia
Store the "reading" key in your executable and keep to yourself the "writing" key. So no one but you can modify the configuration.
This has the advantages of:
No-one can modify the configuration unless they have the "writing" key because any modification will corrupt it entirely, even if they know the "reading" key it would takes ages to compute the other key.
Modification guarantee.
It's not hard - there are plenty of libraries available these days. There're also a lot of key-generation programs that can generate really, really long keys.
Do take some research on how to properly implement them though.
just make a const string that holds the md5 hash and compile it into your app ... your app can then just refer to this const string when validating the configuration file

Categories