blah blah blah is here! blah blah » Close

up0down
link

Hi,

I'm developing a security application in which the end users need to decrypt data from encrypted blobs.

The crucial part of this however is that for security to remain intact, at least simple verification of the data must be performed. My idea was to use public key cryptography, as the idea of that system is that if one has the private key well controlled, nobody could encrypt a chosen valid message that the public key would decrypt.

The idea is, I want to send out a public key to all users of the application, and then encrypt data for those users using the matching private key. Only I or anyone I authorize would have access to the private key; hence, only those people could send valid messages to the endusers with the public key.

I looked at RSACryptoServiceProvider but, oddly, if you don't include private parameters, the cipher is only good for encrypting, not for decrypting. Even though in theory public key crypto is not dependent on which key is used for which, the RSA algorithm implementation in C# appears to care. If you send a CspBlob to the enduser that does NOT contain the private data, their instance of RSACryptoServiceProvider will be unable to use the Decrypt function.

Obviously a symmetric crypto system isn't feasible, at least for the entire project. Symmetric crypto could be used to encrypt the payload itself, but we still need public key crypto to convey the session key to the enduser along with the ciphertext payload.

So either way, we need a way to encrypt something at my end using a private key, that ONLY people with the matching public key can decrypt; and just as importantly, nobody else can encrypt something that will be decryptable by the public key, so nothing from me can be forged.

Ideas?

Thanks

fm

last answered 2 years ago

4 answers

up0down
link

hello, my advice is to make ur own crypto system and not depend on premade one, for example study the algorithm of RSA and make a lil change to that algorithm in ur own way and you can have the system you want.

up0down
link

To my knowledge, it's not possible when using the RSACryptoServiceProvider class to encrypt with the private key and decrypt with the public key.

What you can do is to first encrypt your data (normally just the key for subsequent symmetric decryption) using the RSA public key which the end user can then decrypt using the private key in the normal way.

However, as a protection against forgery, you can also use a different RSA key pair to 'sign' the encrypted data (after first hashing it) with the private key which the end user can then 'verify' with the public key.

Needless to say, the disadvantage of this system is that the end user needs to know two keys, one (public) for verification and another (private) for decryption.

up0down
link

V, would this mean that I have to provide a unique private key to each user of the application and then keep a collection of the matching public keys at my end?

So if I wanted to distribute a message to, say, 100 users of the app, I'd have to encrypt it 100 times, using 100 public keys?

Or would a single public key pair work for your double-key solution?

fm

vulpes
17279

You'd need to create just two public/private key pairs for the application as a whole. Each user would then need to be given the public key of one of the pairs to verify the message and the private key of the other pair to decrypt it.

up0down
link

I never thought of using signing, and it may solve the entire problem.

What about using a symmetric crypto algorithm to actually encrypt the bulk data, and allow the enduser to know the symmetric key; then, using DSA to hash and sign the encrypted bits with a private key; the enduser app only knows the matching public key and can use it for verification.

This means that an enduser may indeed be able to produce a valid encrypted message, but that message will not match the signed signature hash.

Only disadvantage I see to this is that minor changes to the source text will not significantly change the encrypted bits. (Maybe this is where I should still use RSA and just give the enduser the private key for actual decryption?)

I understand that any app can be modified with IL disassembly and resource editing, and that theoretically it would be possible for someone to alter the executable in such a way to ignore invalid signatures or even skip the signature check entirely, but this is not my primary concern for this project. I'd like to at least get it so that there's no way of forging a message EXCEPT for directly modifying the executable.

fm

vulpes
17279

If you're thinking about creating a public/private key pair for signing purposes using either DSA or RSA and then using the same public key to encrypt the data using a symmetric algorithm, you're going to have a problem with the key size. Of the four symmetric algorithms supported by .NET, the maximum key size is Rijndael (32 bytes). However, RSA requires a minimum key size of 48 bytes and DSA requires 64 bytes. I suppose you could use the first 32 bytes or some other 32 byte subset as the symmetric key but, personally, I still prefer the idea of using two keys. Even, if you only used the 8 byte DES algorithm for the symmetric part, it would be far more secure.

fmillion
490

I was planning on embedding BOTH a symmetic key and a public signing key. I can use Rijndael to bulk-encrypt the actual data, and then sign the encrypted data with a DSA key. The recipient app would first verify the signature using the DSA algorithm and if it is valid, proceed with decrypting the message using Rijndael. The problem I see is that a person could extract the Rijndael key and subsequently use it to decrypt messages OUTSIDE the application. I still just wish there was a cipher allowing decryption only with public key...

Feedback