How to decrypt TrafficScript encrypted value - c#

We are using TrafficScript running under a Stingray Traffic Manager to encrypt a string and store that encrypted value in a cookie. Like so:
$encrypt = "string to encrypt";
$passphrase = "passphrase";
$encrypted= string.base64encode(string.encrypt($encrypt, $passphrase));
http.setResponseCookie("encrypted", $encrypted, "path=/");
What I'd then like to do is decrypt that cookie value in C#, however, I've not been able to achieve it thus far. I suspect this is because the exact details of the algorithm used by the TrafficScript isn't documented fully. The reference guide states:
string.encrypt( string, passphrase ) - Encrypts a string using the provided pass phrase. The returned string is encrypted using the AES block cipher, using an expanded form of the passphrase as the cipher key. A MAC is also added to ensure the integrity of the string.
I've tried AesManaged but get an exception 'Length of the data to decrypt is invalid'.
Can anyone provide any pointers?

I didn't manage to find a way to do this purely with TrafficScript.
So I ended up writing a Java Extension and running that from inside my TrafiicScript rule. It was made possible by reusing some code posted in a blog by Joseph Ssenyange which details how to write cross platform encryption for Java and C#.

Related

Importing PKCS#8 encrypted key to RSACng?

If I have encrypted RSA key in PKCS#8, can I somehow import it to RSACng as CngKeyBlobFormat.Pkcs8PrivateBlob? Or does this CngKeyBlobFormat.Pkcs8PrivateBlob just shows the CngKey that during import the key must be decoded from DER to get key parameters and then they are imported into RSACng, thus the answer is no?
CNG understands how to decrypt encrypted PKCS#8, but you need to give it a password. Since .NET doesn't ask you for the password (and it gets passed via a manner other than the properties) there isn't a good way to do it.
Your options are pretty much:
P/Invoke so you can specify the NCRYPTBUFFER_PKCS_SECRET value.
Change your process so that you have an unencrypted PKCS#8.
Change your process so that you have a PFX/PKCS#12 instead of an encrypted PKCS#8 (and then change to reading it via X509Certificate2).
Wait for a future version of .NET Core, which will have the ability to load a PKCS#8, encrypted PKCS#8, and some other formats, directly into the RSA/DSA/ECDsa/ECDiffieHellman objects (feature is currently in the master branch).
Find a library which can decrypt it for you. Bouncy Castle can probably do it.
See also: Digital signature in c# without using BouncyCastle

Method for simple decryption, hard encryption

I'm looking for something like an inverse RSA algorithm. Normally, e.g. in RSA, a public key is used to encrypt the text, but it's virtually impossible to decrypt the text without the private key. What I'm looking for is a method that can decrypt a text using a public key easily, but for encrypting the text and reaching the same ciphertext, a private and a public key should be needed. Is there such a method at all?
My first attempt was to use the RSA crypto service that's build into .NETs system.security.cryptography and just decrypt my plain text (instead of decrypting it). However, that doesn't work as the implementation (or the method, haven't looked at it in that detail) is not able to decrypt arbitrary text, even if the string length is ok. Afterwards I would have encrypted the cipher text to reach the plain text again, but as said, already the first step doesn't work.
The background is the following: From some known information, I want to be able to generate a string which serves as serial number for a program. That should involve some kind of key that I want to store only in the number generator but not in the program that I deploy. The program itself should only be able to decrypt the number and extract the information from the text. The reason for using that kind of asymmetric cipher is that even if the program got cracked, nobody should ever know the key that is used to generate the serial numbers.

Is this a bad encryption practice?

So I am trying to encrypt my files and authentication password.
I am currently using (A)Password Derived Byte[], (B)Clear Byte[] and a strong (C)string to encrypt it.
In my program, I hardcoded the (A)Password Derived in there. I also harcoded a (B)Encrypted version of Clear Byte[] and a (C)Encrypted version of string.
To decrypt my file/password, I must:
1. Decrypt Encrypted version of (B)Clear Byte[] using (A)Password Byte.
2. Decrypt Encrypted version of (C)String using (A)Password Byte.
3. Use the (B) Clear Byte, (C) Clear string to decrypt the file/password.
If this is not a good practice, could someone please provide me suggestions/methods I should use ?
I am developing it in c#
If you want something that only your program can read then you should use DPAPI. In C# This is wrapped up in the ProtectedData class.
Your code is not safe, the code could easily be reverse engineered and decrypted. Using DPAPI means that only your user can access the data you protect in your application.
You use the protecteddata class like this:
ProtectedData.Protect( data, s_aditionalEntropy, DataProtectionScope.CurrentUser );
I decided to go with my own approach mentioned above because no one was able to post a answer I could use.

Encrypt string in C# and decrypt it in Delphi

I'm writing a web app in ASP.Net that creates a licence key for a Windows app written in Delphi. For simplicity I'm going to use a email address and date.
I want to encrypt it in C# and email that info to the person then when the Windows app starts up the person enters in the encrypted string.
Every time the Windows app starts it checks that licence by decrypting it and comparing to todays date.
How can I do this to ensure the C# encryption will decrpyt succesffuly in Delphi?
"the world was full of bad security systems designed by people who read Applied Cryptography"
While the trivial answer is 'use the same algorithm and make sure you have the same keys and initial vector', this answer only exposes the true problem you are going to have: How are you going to protect the encryption key? Mail it along with the license? Embed it in the application? The truth is that there is no protocol that can bootstrap itself w/o a root of trust, either a public trusted authority or a shared secret. A shared secret is easy to code, but complete useless in practice (which means AES, 3DES, XDES or any other similar cipher are not the answer), so you need an scheme that starts based on public key cryptography. For such, to encrypt something for the beneficiary of the license, you need the public key of the said beneficiary, which would make provisioning difficult (license site sends public key, you encrypt license, send email etc). It is much better to send the license in clear text, but signed with your private key. Then your application can validate the signature on the license and use it, if not tampered with.
S-MIME is such a scheme. PGP is just as good. Writing your own code in C# and Delphi is possible, but strongly discouraged. See Cryptographic Signatures.
AES for Delphi and AES for C#.
You can use standard RSA or DSA signature algorithms to do what you want. For C#, these are standard algorithms built into the runtime. For Delphi, you have some choices. See Free Encryption library for Delphi.
Once you have chosen an encryption library for Delphi, you can now do the following:
The C# server signs the user's e-mail address and date using the chosen signature algorithm with your private key.
The Delphi client verifies the license using the same signature algorithm.
Once the Delphi client knows the signature is valid, you can then test the e-mail address / date and decide whether or not to allow your program to run.
I have done exactly the kind of signature verification you want/need using the DSA algorithm, LockBox, and C#.
One thing to be aware of is that C# encryption uses big-endian numbers, while LockBox / Windows CryptoAPI uses little-endian numbers. This probably means you need to reverse endian-ness of both the public key variables and the signature itself before sending it to the Delphi client for verification. Check your crypto library documentation.
One last note: others have proposed using symmetric encryption algorithms like AES / 3DES / etc. The problem with this approach is that your "secret" encryption key is shared between server and client. It is possible that someone could recover the key by reverse-engineering your compiled EXE and then create a "key generator" - a worst-case scenario being a fake activation server that passes out "authentic" encrypted licenses. By using assymetric crypto and keeping the private key secret, you won't have this problem. Users would have to crack every new version of your EXE or else pass around signed authentic licenses - much more inconvenient.
Use the same encryption / decryption algorithm in both delphi and c#.
You can either find the code for an encryption algorithm for C# and then convert the code in the decryption algorithm into Delphi. Likely if you pick a popular encryption you'll be able to find both encryption and decryption algorithms already in many different languages.

.net Cryptography - is there a way to tell that something has been decrypted wrong?

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.

Categories