What happens behind ComputeHash of MACTripleDes C# function? - c#

I need to port MACTripleDes functionality to another programming language and want to know what it really does.
So I have data and a keypharse given.
Is it right, to just TripleDes the data with an IV=0 and the keyphrase, and then take the last 8 byte as the MAC ?
Ciao
Ephraim

DO NOT WRITE YOUR OWN CRYPTOGRAPHIC FUNCTIONS! Not even a direct port of an existing function.
If your language has any maturity, it will have an open source implementation that you can use. If it does not, DO NOT PORT ONE! Find one in another language and write a wrapper for it that you can call (like the C# implementation that you want to port).
Any existing open source implementation will be tested and verified for correctness by people who know far more about cryptography than me, you and over 99% of the global developer population.
If you really cannot find an open source implementation, write a simple .exe using C# that calls the C# implementation and returns the result. Not including setup and boilerplate, that's basically one line of code.
Again, if you write your own implementation, you will inevitably fail to account for some edge case or not understand the algorithm enough, resulting in a dangerous piece of code with exploitable flaws. Unless you are one of the original developers of 3DES or have many years of experience developing currently used encryption standards, you simply do not have the technical skill to port an implementation.
Again, if you write your own implementation, something goes wrong and your data gets leaked, you can and will be held personally accountable. Linkedin was recently sued for $ 5 million because they didn't implement proper security. This is something that can break your career.
DO NOT MAKE THE SAME MISTAKE AS LINKEDIN!

Apparently, the MACTripleDES class implements CBC-MAC using Triple DES as the underlying block cipher. If you have access to a crypto library that implements CBC-MAC and Triple DES (and lets you use the latter as the block cipher in the former, as any generic CBC-MAC implementation should), you should be able to combine them to obtain an equivalent MAC.
Alternatively, if your crypto library does not directly implement CBC-MAC, but does implement CBC mode encryption, you can indeed implement CBC-MAC yourself by encrypting the message in CBC mode, using an all-zero IV, and taking the last block of the resulting ciphertext as the MAC value. (This is simply the definition of CBC-MAC.) It is also not particularly difficult or tricky to implement CBC mode (or CBC-MAC) yourself, using just the raw block cipher. But really, any decent crypto library should already provide CBC-MAC, or at least CBC mode encryption, built in.
What you should not try is implementing Triple DES, or any other block cipher, yourself! It's very hard to implement low-level crypto algorithms like Triple DES securely, since you have to pay attention to things like side-channel attacks, and any such implementation should be thoroughly tested and scrutinized by professional cryptographers before being used for anything serious.
(One specific exception here is that, if you only have access to the plain DES block cipher, you may reasonably safely implement Triple DES on top of that. This is because Triple DES is not actually a separate low-level cipher, but simply a method of expanding the keyspace of DES, at the expense of performance, by encrypting each block several times with independent keys. But again, any decent crypto library written in the last 20 years should support Triple DES if it supports DES at all.)
Of course, even when only implementing high-level crypto algorithms like CBC-MAC, it's still possible to make mistakes, and such mistakes can have security consequences. But at this level, the difficulty and the risk are not significantly greater than those inherent in simply using crypto (and therefore, by implication, working with security-critical data like encryption keys) in the first place. Even so, it's always a good idea to have someone (or, preferably, several someones) with crypto experience review your code before it's deployed. This holds even if you're a crypto expert yourself; anybody can make mistakes, and the more eyeballs you can get on your code, the more likely it is that any mistakes are found before someone exploits them.
Finally, note that, if you don't specifically need compatibility with Microsoft's MACTripleDES class, there are better choices for MAC algorithms than CBC-MAC (such as CMAC), and better choices for ciphers than Triple DES (such as AES). The specific combination of AES and CMAC is even standardized in RFC 4493, which provides detailed implementation instructions and test vectors to verify correctness.
In particular, plain CBC-MAC is not secure for variable-length messages, if the message length is not authenticated. While there are ways to fix this vulnerability, e.g. by prepending the length to the message before computing the MAC, it's generally preferable to use an algorithm that is secure "out of the box", like CMAC.
(Also, since you mention a "keyphrase" in your question, I hope you're actually feeding it through a proper key derivation function before using it as a key for Triple DES (or any other block cipher). In particular, if the keyphrase is user-supplied, and thus likely to have low entropy, you really should be using a key-stretching KDF like PBKDF2, scrypt or Argon2.)

Related

How to license my c# application [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
License for C# desktop application
I want to make my program lock after some days of trial use and if a user purchase a license, can use the program for some months.
I dont know a way to do this. An idea is to make a local temp key when the program is installed, and lock it after the days passed(the problem here is that user can change date and time of his computer.. the philosophy of the program is to be used online and offline, so i cant compare dates from my server to the computer).
And the other thing is, how to make a license service. I can generate lots of serial keys and then when a user pays i can give him a serial, and every time the program starts i can check if the serial is in my web service.
Am i in a good road?? Any suggestions?
If this application is written in C# and you want to write your own licencing functionality, you will first need to obfuscate the executable before it is deployed. This is to stop people reading your CIL code (stored in the .exe) with a disassembler.
To licence the software you will want to choose an encryption method. For such encryption a symmetric method is essentially equivalent to an asymmetric method (as you have to provide the key in any case). The encryption method can be chosen using
public enum EncryptionAlgorithm { Des = 1, Rc2, Rijndael, TripleDes };
for each of the methods and their details, see Wikipedia. The Rijndael encryption algorithm has been designed to replace the aging DES algorithm. Like DES, it is a block cipher. It uses 128-bit, 192-bit or 256-bit keys and is a good choice. In the following I will assume that you will not be storing the encryption key in the code (hard coded) but supply it in a separate file (a ‘product key’); so you will supply two licence files the product key to enable decryption and the encrypted licence file.
Once you have chosen an encryption method, it is common-place to come up with a hash or algorithm to work on the product key/initialisation vector (IV); you take a 128-bit key (for example) and scramble it using some method/transform. The key (that is randomly/pseudo-randomly generated for each user you deploy the software to) is then used to generate the IV.
You then use the 'random' key, the IV and the selected encryption method to encrypt some licence text (that includes licence dates).
internal ICryptoTransform GetCryptoServiceProvider(byte[] bK, byte[] iVec){ ... }
To decrypt the file using your method you essentially perform the reverse process. One thing to note about licencing, is that you should not spend too much time worrying about people cracking the software. Make it very hard using a method like the above, but don't invest too much time coming up with an ever increasingly complex methodology because if some (admittedly very talented) hacker wants to crack your code it is likely he will. Moreover, you have to assume the user will not break the law and share licence files! I cannot comment from experience on using an external company to run the licencing of your code (I have always written my own), however it is likely to be an expensive option.
I hope this is of some help.
Although it highly depends on your exact requirements, target technology (Winforms, WPF, Silverlight etc...) I would suggest using a third party licensing component such as Quick License Manager, Licensing Pro dotNet.
While rolling your own solution is going to be cheaper, the possibility of it being cracked or circumvented is much higher. To use a third party solution means you have an external team or company dedicated to keeping the licensing model secure and more reliable.
Best regards,

.NET: Difference between PasswordDeriveBytes and Rfc2898DeriveBytes

I'm trying to understand some C#-code, I have been handed, which deals with cryptography, and specifically uses PasswordDeriveBytes from System.Security.Cryptography.
In the .NET docs , it says that PasswordDeriveBytes uses "an extension of the PBKDF1 algorithm" which is later in the document specified as "the PKCS#5 v2.0 standard", which is PBKDF2 (as far as I can tell). Everywhere on the net I've found (including here on Stack Exchange), though, everyone says "use Rfc2898DeriveBytes, cause Password* is deprecated and uses PBKDF1". But the only difference in the docs at msdn.microsoft.com seems to be that the Rfc*-version specifically mentions PBKDF2, where Password* says "extension of PBKDF1" and "PKCS#5 v 2.0".
So, can anyone tell me what the difference is between the two classes (if any) and why I should use one rather than the other for PBKDF2 password key derivation?
Now, other code, that deals with the same data, explicitly uses PBKDF2, and works, so that would suggest that indeed PasswordDeriveBytes also uses PBKDF2, or that PBKDF2 is simply compatible with PBKDF1 under certain circumstances, but I want to know for sure that it's not some side effect of some random thing, and that things just magically works (and eventually probably will magically and spectacularly break) without anyone really understanding why.
If you instantiate PasswordDeriveBytes and make a single call to the GetBytes method passing a value which is smaller than the output size of the underlying digest algorithm then you get back a value from the PBKDF1 algorithm.
If you make two calls to GetBytes for the same object you may encounter a counting bug in the implementation.
PBKDF1 is only described to output up to the size of the hash algorithm (e.g. 20 bytes for SHA-1), but the PasswordDeriveBytes class has made up a formula to support up to 1000 times the hash output size. So a large value produced by this class may not be easily attainable in another platform.
If you instantiate Rfc2898DeriveBytes you get a streaming implementation of the PBKDF2 algorithm. The most obvious difference of PBKDF2 over PBKDF1 is that PBKDF2 allows the generation of an arbitrary amount of data (the limit is (2^32-1)*hashOutputSize; or for SHA-1 85,899,345,900 bytes). PBKDF2 also uses a more complex construction (in particular, HMAC over direct digest) to make recovering the input password from an output value more difficult.
The "streaming" in the implementation is that the concatenation of GetBytes(5) and GetBytes(3) is the same as GetBytes(8). Unlike in PasswordDeriveBytes, this works correctly in Rfc2898DeriveBytes.
PBKDF1 was originally created to generate DES keys, published in PKCS #5 v1.5 in 1993.
PBKDF2 was published in PKCS #5 v2.0 (which was republished as RFC2898) in 1999. A slide deck which should be found at ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-5v2/pkcs5v2-0.pdf (but seems to be having issues so ftp://ftp.dfn-cert.de/pub/pca/docs/PKCS/ftp.rsa.com/99workshop/pkcs5_v2.0.ppt may hve to do) further summarizes differences. (The slide deck was written by RSA Security, the creators of PBKDF1 and PBKDF2, and they are the people who recommend PBKDF2 over PBKDF1).
I think a great answer to this would be found here:
C# PasswordDeriveBytes Confusion
But to sumup:
Microsoft's implementation of original PKCS#5 (aka PBKDF1) include insecure extensions to provide more bytes than the hash function can provide (see bug reports here and here).
Even if it was not buggy you should avoid undocumented, proprietary extensions to standards (or you might never be able to decrypt your data in the future - at least not outside Windows.)
I strongly suggest you to use the newer Rfc2898DeriveBytes which implements PBKDF2 (PKCS#5 v2) which is available since .NET 2.0.
Here's a blog post detailing the differences:
http://blogs.msdn.com/b/shawnfa/archive/2004/04/14/generating-a-key-from-a-password.aspx
PBKDF2 can be used to generate keys of any length, which is very useful for password-based encryption (it can generate any key length as required by the symmetric cipher) but means less for secure password storage. It also applies the salt using HMAC instead of concatenation like PBKDF1, which has better security properties in cases of weak salts.
PKCS#5 v2.0 defines both PBKDF1 and PBKDF2, the former for reasons of backwards compatibility and also recommends you use PBKDF2 for new applications. I've no idea why the latter is better than the former, but the two .NET classes do seem to use different but interoperable algorithms. (Possibly because only the resulting key is being exchanged, not the inputs + KDF.)

which algorithm is better for encrypt and decrypt data inside a project?

which algorithm is better for encrypt and decrypt data inside a project?
i designed and developed a site like below :
htttp://www.soscharge.com
this site is about mobile charge codes ...
i want to encrypt mobile charge codes during insert to database and decrypt them for showing to users...
hash algorithm is not a good idea about this purpose (one way algorithm)
i heard something about symmetric and asymmetric algorithms (but i want to learn how can i write a simple and powerfull algorithm by myself)
thanks in advance
never - NEVER write your encryption-algorithms yourself if you are not an expert and get paid for it! Seriously: you will never get a good and secure algorithm working just by yourself. Use the tools in the Framework - System.Security.Cryptography namespace! And you don't ask for synchronous vs. asynchronous but I guess you are thinking on symmetric vs. assymetric algorithms
now to the answer:
as you have full controll of your database and an outsider should not be able to get to it you can use symmetric key algorithms because you protect your "secret" (the key) on your system and the user will never see it (or so it should be - if your system is secure can only a IT-guy tell you)
which algorithm is better for encrypt and decrypt data inside a project?
You didn't give us any criteria on which to evaluate "better."
Frankly, it sounds like you're not a security expert. This stuff is so easy to get wrong, even if you pick the "best" algorithm (look at the recent RSA debacle). If you have secrets that truly need to be safeguarded, you should hire a security expert. Your stakeholders will thank you later.
(but i want to learn how can i write a simple and powerfull algorithm by myself)
Take a course. Read a book (or two; the Bruce Schneier books are decent). Practice for about 10,000 hours.
i heard something about synchronous and asynchronous algorithms
Symmetric and asymmetric, perhaps? I mean, this tells us all we need to know about your level of expertise on this subject.
Seriously, don't do this yourself. Get an expert to help you.
I assume that you need symmetric algo, by now best choice is AES. It's easy, strong and has implementations for most platforms and languages.

How to use BouncyCastle in C# for Blowfish one-way hashing?

I've seen a ton of questions asked about Blowfish and C# and the usual answer is BouncyCastle. However, the project has basically no documentation and I can't find my way around the directory structure to even find unit tests as examples. I mean, is Blowfish known as Asn1, Bcpg, Crypto(in general?), EC, Ocsp, Pkcs, or what? I lack the domain knowledge of knowing what all of the acronyms in the source code means.
Is there any useful articles or blogs or something that has succeeded in using the C# BouncyCastle API for Blowfish? My primary need is to use Blowfish for password hashing.
For password hashing I would recommend going with bcrypt which internally uses Blowfish. The advantage of using bcrypt is that you can easily configure how expensive it is in generating your output hash. This is important as the biggest problem with many popular hash algorithms is that they work very quickly and this allows a brute force attack to run through many permutations to find a match. By specifying a large work factor you can make it slow to run (in computer terms but still fast in human terms) and so a brute force attack becomes unfeasable.
There are C# implementations already available.
Also you should check out: Why does BCrypt.net GenerateSalt(31) return straight away?
And the codeplex implementation: bcrypt.codeplex.com

How to obfuscate string constants?

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.

Categories