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
Related
I have read round all the articles on StackOverflow and while a lot of them come close to the solution I want, none appear to work.
I simply want to take an existing private key to create a signature of a piece of data. This then becomes part of a data file which includes a header describing the parameters used. Next comes the signed version of a datafile, lastly the datafile itself (a hex file). Concatentation of files is not the issue, generating a certificate using the private and public key pairs I have is. The keys are of the format ("-----BEGIN PRIVATE KEY-----") I can generate signature files easily enough from scratch, but the software that will read the final file is expecting a 256 bye signature, whereas mine (using RSA-256) is only producing 32 byte signatures. It only has access to the public key for decryption and validation of the file signature.
I have come up across a number of errors such as keysets not being valid, not existing, the ComputeHash function not working and causing a crash. I suspect I need to provide more information to my RSACryptographicService through CSPParameters but am not sure what is necessary and sufficient to do so.
I would like to avoid digging into the mathematics behind the algorithm such as manually setting/reading the modulus / P/Q values etc. Can anyone propose a simple way to do this or tell me where I am going wrong? Code is available on request.
The comments you are getting saying 256-byte signature is too long are absurd. Ignore those.
256 bit (32 bytes) would be a very small signature, that cannot be correct. I believe what you're actually looking for is 2048-bit (256-byte) RSA signatures. Those are more sensible by today's standards (though a step larger doesn't hurt).
In terms of importing your key, and not setting key components manually, you should look into "PEM" format RSA keys. There are several nuget packages out there to handle them. Otherwise you can strip the header/footer and decode the base64 yourself and import the key components with some of the built in X509 classes.
.NET does not natively support PEM format keys, and as such, I recommend using a reputable crypto library such as BouncyCastle, as they support PEM key parsing in their RSA algorithms.
This existing stackoverflow link describes how to import keys in BouncyCastle:
Reading PEM RSA Public Key Only using Bouncy Castle
I'm looking for an advice regarding cryptography.
I'm working on a .Net application which I need to create a license for it, so I plan to create an encrypted license file which my application will use to know if it is licensed or not.
Handling license is as following:
License Generation:
Generate unique symmetric key.
Use symmetric key to encrypt license information.
Use asymmetric public key to encrypt symmetric key.
Write encrypted symmetric key and encrypted license information to file.
License Decryption:
My application will read license file.
Decrypt symmetric key using asymmetric private key which is embedded
xml file inside dll.
Use decrypted symmetric key to decrypt license information.
My questions are:
If the dll which is responsible for decrypting the license has the asymmetric private key as xml embedded resource, is it possible to spy on the dll to get the key and generate a new license?
Is there another technique I can use which is more secure?
As a very general overview, the simplest way is to sign (there's no real need to encrypt anything really) the information with a private key, and verify the signature with the corresponding public key. That's it. The private key is kept safe and no valid new signatures can be generated without it, so if someone changes the signed information the signature becomes invalid. There's no need for extra symmetric encryption on top of it - it's pointless work as far as I'm concerned.
There are plenty of libraries that already do this easily enough, but it's also not that hard to do it manually. https://github.com/dnauck/Portable.Licensing is one I used before.
Edit: also yes, in general it's very easy to decompile .net assemblies, including extracting resources from them.
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#.
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.
Signing an assembly in .NET involves a public/private key pair. As far as I can tell from what I've read .NET uses the RSA algorithm and the private key to sign the assembly, checking it with the embedded public key.
I know how to retrieve the public key (Assembly.PublicKey). I was wondering, if that key could be used to decrypt a short string that contains some data encrypted with the private key.
The docs I've read so far (e.g.) seem to imply that only the other way round is possible: That I would have to use the public key to encrypt and the private key to decrypt - but I don't really want to include that in the assembly, do I.
I guess it would be ok, if I just signed the string. But how?
I'm a bit at a loss how to start this. Does anybody have a code snippet?
Also, encrypting / signing of the small string would ideally happen in PHP, since I want to offload that to a web server and all we have so far is your generic PHP/MySQL hosted website.
Use Case: I'm trying to come up with a lightweight licensing scheme for a software we are about to release to beta testers. Since the software will probably be freeware, all we really want to achieve is
know who has the software installed (email address)
let the software expire after a given period, after which the user will have to get a new license
this is as easy as filling out a form and waiting for an automated email with the key to arrive
we are trying to reduce the likelyhood of old versions coming back to bite our reputation / haunt us
Being able to encrypt a tuple (expiry date, fingerprint) and decrypt that at startup would make an easy licensing module: The first time the application is started, the user is asked for email address, name, organisation. This information is posted to the webserver along with an md5 fingerprint of some system info (nic, computer name, assembly major and minor version). The webserver answers by email (checks validity of email address) with an encrypted version of the tuple (expiry date, fingerprint) that is then saved to disk. On startup, this can be decrypted and compared with current date and regenerated fingerprint.
EDIT: OK, so I don't have all the answers to my question yet. But it looks like .NET won't make it easy to use the private key for encryption (if that is at all possible, the answers don't really agree on that).
The route I will take is this (based on my use case):
I will use the private key to sign the license.
I will use the public key to verify the license was signed by the private key
I will post another question aimed at PHP devs on how to use the .NET keys (produced by sn.exe) to sign some text
I am not really worried about the user seeing the license, as it is a hash anyway and computed from stuff he allready knows. All I want is to make it too hard to be worth any bother for your typical building architect to copy my software without me knowing (remember, the software will be freeware - all I want is a paper trail of who has it installed...)
Thank you very much for your answers.
You cannot decrypt using the public key. That way, the whole point of "public" would be lost.
(You might, however, be able to sign something using the private key, then verify the signature using the public key. That's what the framework uses the keys for - the assembly is signed, and the public key is used to verify the signature.)
This can be done using SignedXml http://msdn.microsoft.com/en-us/library/ms229745.aspx. At a lower level you can prob use RSAPKCS1SignatureDeformatter and RSAPKCS1SignatureFormatter. These work by encrypting a hash of the data then comparing the data with the (decrypted) hash the other end. I believe the hashing is used because private key encryption can only handle small data. Not sure about reusing the assembly public key, if it is causing problems just use a separate key pair.
Word of warning, check out this as these classes can result in 20 second hang ups! http://www.pcreview.co.uk/forums/thread-3428177.php
This approach is vulnerable to the signature verification code being tampered with using Reflexil but that is another matter.
I wrote the following but rereading I think you already got this: You aren't really trying to encrypt or hide data from the user, you want to stop them from creating or tampering the license. You are right that a public private key encryption algorithm can be used for this. This is known as Signing using a private key (server side license generation). And verification of the signature using a public key (license checking in the app). I mention this terminology as it'll help with research.
Not in .NET.
In many traditional public-key encryption algorithm, like RSA, you can encrypt and decrypt both ways, typically one way is called "encryption" and the other "signing", even though you actually end up with an encrypted version of something both ways.
However, in .NET the RSA implementation has been crippled, and when signing will only produce digests of the input, not the full processed information.
It seems there's some disagreement about what can and cannot be done with RSA, so let me edit my answer to be more specific.
I'm talking about RSA math, not any particular RSA implementation.
RSA math allows you to encode information either of the two keys (private or public), and the encoded data can only be decoded with the other of the two keys.
Typically, you encode with a public key, encrypting the information, and decode it with the private key, decrypting the information. Or, you take a hash of the information, encode it with the private key, signing the hash, and decode the hash with the public key, in order to compare and verify the signature.
Typical implementations does not allow one to do full encoding of data from private to public, only by hashing the data, but the math behind RSA fully allows this.
In RSA Public keys are used for encryption, private keys are used for decryption. You can't use a public key to decrypt anything...
In RSA the only actual difference between a public key and a private key is which one you keep secret.
So you can use a public key as the encryption key and decrypt with the private key, or use the private key as the encryption key and decrypt with the public key.
Encrypting with the private key is used for digital signatures (anybody can decode with the public key).
But as #Lasse V. Karlsen pointed out, .Net might make it more difficult than it should be...
I think both direction are possible encrypt with public and decrypt with private and encrypt with private key. The second is the way how digital signature works.
Warning! This answer is wrong but I'm going to leave it here none-the-less because the series of comments attached are, I think of sufficient interest to others to keep the answer around. Ok it makes me look like an idiot but thats nothing new to me ;) Vote as you wish.
A public key can be used to:-
Encrypt something that can only be decrypted with the private key
Authenticate something signed with the private key
It can not be used to decrypt something to encrypted by a private key. Its for this reason that the Public/Private key system is refered to as an Asymetric system.