So at my workplace, I have a .NET based web application, that has to pick up an encrypted parameter in a querystring.
Those supplying the encrypted string is an external contractor and they prefer (almost demand. cant change contractors though, the higher ups decide that stuff...), to use Microsoft's Crypto API to encrypt the string.
Well, fair enough, AFAIK I can decrypt that with C#, but after endless searching I am still at a loss on how it works.
That means I cant even supply example code, and I am stuck in this bind until I can decrypt this string.
What I have is:
I have the common password they encrypt with and I have to use to decrypt it with.
Encryption settings are: "CALC_AES_128" hash: "CALC_MD5". The string is encrypted, then hashed.
So I want to unhash it, and decrypt it.
I know its a lot to ask but how do I go about it?
Your external contractor doesn't know what he is talking about.
Hashes are used as a trap door function, a way to recognize something without been told what that thing IS. It is a digital fingerprint. The way a CRYPTOGRAPHICALLY SECURE hash is made, means even given the hash and the algorithm it is difficult to create an object that matches the fingerprint.
AES is a non-deterministic cypher. The non-determinisism comes from the Initialization Vector, which is meant to be a random number each time (not hard coded from a die roll, ahem Sony). This means for all intents and purposes, the output of AES is pure random (unless you have the key). Good cyphers are all designed to produce data that is statistically random (thus there is little data to form an attack from).
So by feeding data into a function that creates random data, then putting it into a trap door function, you have produce something that is truly difficult to decode (difficult in this sense is mathematically, you actually need more energy than exist in the universe to compute this).
As for how to send data across in a secure manner (secure as in against prying eyes on an unsecure network) in the query string? There is a well known protocol that .net supports that does this very well. Its called HTTPS.
Related
I want to do the below. What is the best way to achieve this?
I have a desktop app in C# which will be installed on multiple client machines.
The application is capable of doing an operation X but it needs some auxillary info which it can read from a file. This auxiliary info essentially provides some specifics that identify that machine where the operation should be run and what operation to run etc.
I will work with the client to get some of this auxilary info about his machine (say hostname/ip address etc) which I want to put in this file along with other info and generate it on my machine and share it with him/her to provide it to my software. I want to encrypt this data so that the structure of the data is not obvious to somebody who opens it. (I will get some of the machine identification info from the client, either via phone or email).
I want to somehow encrypt and secure this file such that only I can generate the file but any of my installations can read it. But since the contained info is specific to a machine it will be executed only on one machine (other machines will read but reject it since the given hostname/ip etc won't match that machine)
How do I do this? I want to make sure the below:
Only I can generate this file.
I need to somehow authenticate that this is generated only by me and not by somebody else.
But my software on client machines should be able to decrypt this.
I don't want to take a password from the customer etc. all the decryption logic should be in the installed software itself. I want to code it in.
When I researched this online, many talk about public and private cryptography but there they talk about encrypting with the public key and decrypting with the private key. But I don't think this will work since decryption is being done by my software at the client machine and so I shouldn't put the private key in my code. Because, from what I read, private key can generate public key so somebody could potentially generate that instruction file if I do this.
What is the best way to do this? Can I encrypt with private key and decrypt with public key? Is it ok if somebody gets hold of my public key (say they disassemble the C# code)? Any other good ways to encrypt and authenticate such that I hold the private data with me but code only harmless public keys/data in the application?
TIA.
Who are you trying to protect this from?
You are giving the end user your application binary. Assume they can decompile it and work out how it works. Or step through your code in a debugger, with access to the contents of every variable. Assume that an attacker can learn everything they need to know about how it works.
At best I would recommend creating a hash of the machine details and a salt value. Then create a signature of that hash.
Keep the salt and the public key of the signature as a constant in the application binary. Maybe XOR values together so an attacker has to think a little about how it works.
But anything more is pointless. Any attacker with more skills will just patch your program to delete the test entirely. So I wouldn't bother building anything too complicated.
Giving someone a program, and preventing them from using it, is like trying to make water not wet.
You have two questions
How do you encrypt the information, and
How can your client make sure the information came from you.
Those are orthogonal
I'll address the second on first - it's easier.
First, hash the file, and add the hash to the payload. Then generate a public/private key pair, then encrypt some known (but non-trivial) information with the private key and add that to the payload. You can distribute the public key with your app. If your app hashes the file and the hashes match and it can decrypt the known information and make sense of it, then it came from you and no one has changed it.
This is known as a digital signature. If you look up a digital signature provider and follow the docs, it should just work.
The encryption problem is more of an issue. There's pretty much no way to do what you want. If your app can decrypt the information using information you distribute with the application, then a determined bad guy can extract that key material and decrypt it.
However, you can use the RSA key container on the client to do the encryption when you install the app. The process is similar to using encrypted sections in a web.config file. Since you won't be following the encrypted config section cookbook the process is complicated.
I've done this before, but it was several jobs ago, so I don't have anything I can show you.
But, it will be encrypted so that it can be read only where it was encrypted. No two installations will recognize each others files.
That said...
Encryption seems like a heavy hammer to prevent your customers from being able to guess "the structure of the data [so that it] is not obvious to somebody who opens it"
Unless you have something worth protecting, you can probably get away with obfuscating the data. For example, you could have the data as JSON, but then use GetBytes on a Utf8Encoding to get a byte[] and convert that to a hex string. A determined hacker could decompile you code, figure out what you've done and reverse it, but that doesn't seem like a threat you really need to worry about.
I need my program to be secure as it's contents include personal information like IP (a private IRC chat if you must know). My plan is to read the bytes of the program and then create a symmetric encryption algorithm like AES to encrypt the byte arrays, to increase security I have added other minor things which can take care of debugging and emulators for example. Then I will use codedom to create my stub that 'carries' these encrypted bytes. There are 2 ways that I know which can 'carry' the code:
Append encrypted bytes to stub in order for it to decrypt, write and run. (Known as dropping)
Add it to the stub's resources so it can decrypt and load it so it which then is able to run it in Memory.
I could have 4 ways by adding to resource then decrypt, write and run or appending then decrypt, load and run in the memory. I could also make my own little obfuscation in the code but I doubt it will make much difference.
Method 2 seems to have been abused by people and is detected by the Anti-Virus and it is really annoying to get your project blocked by your anti-virus every time you debug. Enough of the excuses it will just be a false positive for the user when all the program is doing is protecting itself from being easily disassembled with programs such as the Red Gate Reflector.
Including the database information e.g. SQL login methods are still going to be analyzed if disassembled:
Are there more ways of doing this?
There is no way of doing what you describing. Get rid of it.
Another way to do such a thing would be to have a webservice that the user has to authenticate against which then sends the sensitive information over a secure channel (e.g. SSL/TLS).
An second approach could be that you
Enrypt the information
Embed the encrypted version of the sensitive informations into the executeable
Ask the user for a symmetric key at runtime (e.g. he has to enter the "passwort" for the data)
Use the symmetric key to decrypt the information
Use the information
The big disadvantage here is, that if the symmetric key (e.g. the password) is stolen in any way, the attacker can then get all that enrypted information.
What about SecureString? Seems like this would handle hiding the information within the program without a whole lot of bother. If the memory is dumped during execution then the data will be encrypted.
We have an application which contains sensitive information and I'm trying my best to secure it. The sensitive information includes:
The main algorithm
The keys for an encryption/decryption algorithm
I've been looking at Obfuscating the code but it doesn't seem to help much as I can still decompile it. However, my biggest concern is that the keys used for encryption of serial numbers etc are clearly visible when you decompile the code, even when it's Obfuscated.
Can anyone suggest how I can secure these strings?
I realise one of the methods might be to remove any decryption from the application itself, while this may be possible in part, there are some features which have to use encryption/decryption - mainly to save a config file and to pass an 'authorisation' token to a DLL to perform a calculation.
There are ways to do what you want, but it isn't cheap and it isn't easy.
Is it worth it?
When looking at whether to protect software, we first have to answer a number of questions:
How likely is this to happen?
What is the value to someone else of your algorithm and data?
What is the cost to them of buying a license to use your software?
What is the cost to them of replicating your algorithm and data?
What is the cost to them of reverse engineering your algorithm and data?
What is the cost to you of protecting your algorithm and data?
If these produce a significant economic imperative to protect your algorithm/data then you should look into doing it. For instance if the value of the service and cost to customers are both high, but the cost of reverse engineering your code is much lower than the cost of developing it themselves, then people may attempt it.
So, this leads on to your question
How do you secure your algorithm and data?
Discouragement
Obfuscation
The option you suggest, obfuscating the code, messes with the economics above - it tries to significantly increase the cost to them (5 above) without increasing the cost to you (6) very much. The research by the Center for Encrypted Functionalities has done some interesting research on this. The problem is that as with DVD encryption it is doomed to failure if there is enough of a differential between 3, 4 and 5 then eventually someone will do it.
Detection
Another option might be a form of Steganography, which allows you to identify who decrypted your data and started distributing it. For instance, if you have 100 different float values as part of your data, and a 1bit error in the LSB of each of those values wouldn't cause a problem with your application, encode a unique (to each customer) identifier into those bits. The problem is, if someone has access to multiple copies of your application data, it would be obvious that it differs, making it easier to identify the hidden message.
Protection
SaaS - Software as a Service
A more secure option might be to provide the critical part of your software as a service, rather than include it in your application.
Conceptually, your application would collect up all of the data required to run your algorithm, package it up as a request to a server (controlled by you) in the cloud, your service would then calculate your results and pass it back to the client, which would display it.
This keeps all of your proprietary, confidential data and algorithms within a domain that you control completely, and removes any possibility of a client extracting either.
The obvious downside is that clients are tied into your service provision, are at the mercy of your servers and their internet connection. Unfortunately many people object to SaaS for exactly these reasons. On the plus side, they are always up to date with bug fixes, and your compute cluster is likely to be higher performance than the PC they are running the user interface on.
This would be a huge step to take though, and could have a huge cost 6 above, but is one of the few ways to keep your algorithm and data completely secure.
Software Protection Dongles
Although traditional Software Protection Dongles would protect from software piracy, they wouldn't protect against algorithms and data in your code being extracted.
Newer Code Porting dongles (such as SenseLock†) appear to be able to do what you want though. With these devices, you take code out of your application and port it to the secure dongle processor. As with SaaS, your application would bundle up the data, pass it to the dongle (probably a USB device attached to your computer) and read back the results.
Unlike SaaS, data bandwidth would be unlikely to be an issue, but performance of your application may be limited by the performance of your SDP.
† This was the first example I could find with a google search.
Trusted platform
Another option, which may become viable in the future is to use a Trusted Platform Module and Trusted Execution Technology to secure critical areas of the code. Whenever a customer installs your software, they would provide you with a fingerprint of their hardware and you would provide them with a unlock key for that specific system.
This key would would then allow the code to be decrypted and executed within the trusted environment, where the encrypted code and data would be inaccessible outside of the trusted platform. If anything at all about the trusted environment changed, it would invalidate the key and that functionality would be lost.
For the customer this has the advantage that their data stays local, and they don't need to buy a new dongle to improve performance, but it has the potential to create an ongoing support requirement and the likelihood that your customers would become frustrated with the hoops they had to jump through to use software they have bought and paid for - losing you good will.
Conclusion
What you want to do is not simple or cheap. It could require a big investment in software, infrastructure or both. You need to know that it is worth the investment before you start along this road.
All efforts will be futile if someone is motivated enough to break it. No one has managed to figure this out yet, even the biggest software companies.
I'm trying my best to secure it
I'm not saying this as a scathing criticism, just you need to be aware of what your trying to achieve is currently assumed to be impossible.
Obfuscation is security through obscurity, it does have some benefit as it will deter the most incompetent of hacker attempts, but largely it is wasted effort that could perhaps be better spent in other areas of development.
In answer to your original question, you are going to run into problems with intelligent compilers, they might automatically piece together the string into the compiled application removing some of your obfuscation efforts as a compilation optimisations. It would be hard to maintain as well, so I would reconsider your risk analysis model and perhaps resign yourself to the fact it can be cracked and if it has any value probably will be.
I recently read a very simple solution to OP.
Simple declare your constants as readonly string, not const string. That simple. Apparently const variables get written to a stack area in the binary but written as plain text whereas readonly strings get added to the constructor and written as a byte array instead of text.
I.e. If you search for it, you won't find it.
That was the question, right?
Using a custom algorithm (security through obscurity?), combined with storing the key inside the application, is simply not secure.
If you are storing some kind of a password, then you can use a one-way hashing function to ensure that decrypted data is unavailable anywhere in your code.
If you need to use a symmetric encryption algorithm, use a well known and tested one, like AES-256. But the key obviously cannot be stored inside your code.
[Edit]
Since you mentioned encryption of serial numbers, I believe you a one-way hashing function (like SHA-256) would really suit your needs better.
The idea is to hash your serial numbers during build time into their hashed representations, which cannot be reversed (SHA-256 is considered to be a pretty safe algorithm, compared to, say, MD5). During run time, you only need to apply the same hash function to the user input, and compare hashed values only. This way none of the actual serial numbers are available to the attacker.
#Tom Gullen have given a proper answer.
I merely got some suggestions on how you can make it harder for the users to access your keys and algorithm.
As for the algorithm: Do not compile your algorithm at compile time, but at runtime. To be able to do this you need to specify an interface which contains the methods for the algorithm. The interface is used to run it. Then add the source code for the algorithm as an encrypted string (embedded resource). Decrypt it at runtime and use CodeDom to compile it into a .NET class.
Keys: The usual way is to store spread parts of your key in different places in the application. Store each part as byte[] instead of string to make it a bit harder to find them.
If all your users have an internet connection: Fetch the algorithm source code and the keys using SSL instead.
Note that everything will be pieced together at runtime, anyone with a bit of more knowledge can inspect/debug your application to find everything.
i dont think you can easily obfuscate string constants, so if possible, dont use them :) you can use assembly resources instead, those you can encrypt however you want.
Depends what you're trying to do but can you use asymmetric encryption? That way you only need to store public keys with no need to obfuscate them.
See the title for question.
In a nut shell, what I am trying to do is encrypt some data with the seed (keyword) provided by the user. Is there a way to know that the data has been decrypted wrong, or in other words that the seed is wrong?
Using .net 2.0, C#
Thanks!
It's quite normal to make a hash part of the encrypted data. Say, you have some data you want to encrypt. You then create an MD5 hash of this and add this to the end of the data. Then, when you decrypt it, you take the hash of the end of the encrypted data and verify that the hash hasn't changed.
Depends on your algorithm specifics. stream ciphers (like RC4) will not by themselves be able to detect any tampering. Block ciphers (AES) may detect some tampering because of the block padding algorithms (PKCS#5). This padding check is what causes ICryptoTransform.TransformFinalBlock` to throw exception that the decryption failed, but this detection is not cryptographically secure (in the worst case is 1/256 chances of not detecting tampering, if padding is one byte). This is not an omission of the .Net implementation, is a fundamental problem with using all encryption algorithms.
So given that the decryption operation itself basically cannot detect tampering (or the use of a bad key/IV) the solution is to add a digest of the message in the message. The industry standard is to use an HMAC digest, and have the key derivation process produce enough key material for the key/IV and HMAC secret (this is how TLS/SSL do it, which is pretty much 'industry standard', see 6.3 Key calculation of the RFC linked). The decryption step decrypts the message and then computes the HMAC of the message, comparing it with the original digest. If they match, the decryption was successful (correct key/IV used) and the message was not tampered with.
If you want to prevent tampering of the message use a HMAC.
Regular encryption doesn't tamper proofs messages. Learn from asp.net's team mistake, and put the extra validation in place - see how the asp.net padding oracle vulnerability related to getting different levels of access.
If you don't put the extra validation, it's likely you'll expose information that an attacker may use to try to game the system.
The formal way to resolve that issue is to use a key wrap around the key (which would itself be encrypted). This is because you should only trust entirely private keys, not keys which are given to you. If you were to use an invalid key for encrypting data, then things go bad.
There are no built in routines (that I know of) that perform key wrapping in .NET, but in essence you can achieve the same thing by prefixing and postfixing the actual key with a string of 16 (or whatever your blocksize is) 'A' characters. When you decrypt the key you ensure that it is pre & postfixed with 'A' and flag it as an error if not.
If you have less formal requirements then another option is to use the key to decrypt a string which is known to be encrypted with the correct key. If once you've decrypted that string you get an unexpected result, then flag it as an error.
One brute force way - depending of what are you doing with your data... Push it to any algorithm that expects it and see if it crashes. I have encrypted binary serialized data that I deserialize that way. Binary formatter throws an exception if data is decrypted wrongly and turned to noise.
I'm trying to determine the best course of action to implement a simple "licensing" system with a partner of mine. The concept is:
Generate an encrypted value based upon several internal hardware components. Have the customer send this value to us which we will implement into our key generator. Once we have that, we add any other restrictions on the license (user, expires, etc.). From there we generate a file which we send to the customer they can add to their installation and voila, happy people about.
I have the first part all done. My next part is trying to figure out which encryption methodology I would need to use. I already know Symmetric Encryption is pretty much the only route I can take. Most of the information I have found involves .NET already creating a key from its own internal methods.
That's a bit of background, my question is: "Which encryption method could I use which would allow me to encrypt the restrictions based upon the "id" I was given from the customer's computer?" I'm writing this in C# by the way.
You say you know you need symmetric encryption but you would be wrong. With symmetric encryption the code checking the license has to have access to the secret, which means if your code is reverse engineered someone can not only figure out where to remove the checks, they can generate and sell license keys that are indistinguishable from the ones you make.
Use asymmetric encryption, or a secure hash. And don't try to use the customer-specific hardware information as the key, instead prepend or append it to the other data. You're essentially creating an access control/rights/privileges list file coupled with a message authentication code to verify its source (you).
I recently did something very similar to this. I used AES to generate a value based on a private key using an internal customer id or order number as the IV used to encrypt the value.
Instead of an order number you can use some form of checksum from your first step so it's not something that's stored as the IV. That way if the file is hosed or if they transfer the software to a new computer - either way will invalidate the file.
Something you might be careful of though is how closely you tie the installation/license to the hardware. You don't want to punish a legitimate user simply because they upgraded their motherboard.