The way that RSACryptoServiceProvider works is that we encrypt with a
public key and decrypt with a private key. This architecture works
great for people sending messages to me. However, I now have the
opposite application:

I want to put a license file on a destination computer and be sure
that it remains unaltered. It would be great if I could encrypt it
with a private key at our office and transmit the public key and the
encrypted file to the destination computer, where anybody can decrypt
it and read it, but not change it because we have the private key at
our office.

I've read posts to "simply reverse the public and private RSA keys"
but tried several variations of switching RsaParameters.D, DP, P, DQ,
Modulus and others, to no avail.

I'm sure that a solution exists, just that I do not know it.

How do I, in C# .NET, send a license file to a destination computer,
with a public key, anybody can read it, but only we can change it?

Thanks.

Re: Reverse usage of public/private RSA encryption keys for licensing? by Rob

Rob
Mon Nov 22 23:43:29 CST 2004

Reversing the public and private key bytes won't work at all. They are
mathematically linked.

In order to use the private key to ensure data hasn't been tampered with and
originated from the sole person possessing the private key, you must use the
RSACryptoServiceProvider's SignData method. The clients can then use your
RSA public key and call the RSACryptoServiceProvider's VerifyData method.

If you want to get more formal, you can use the RSAPKCS1SignatureFormatter
and RSAPKCS1SignatureDeformatter classes in conjunction with the
RSACryptoServiceProvider, and this will create standard RSA PKCS#1 version
1.5 signatures.

Just as a note, this won't encrypt the original data, but will create a
signature. The client can verify the signature against the same data to
ensure the data hasn't been altered.

-Rob Teixeira


<charismatic_evangelist@yahoo.com> wrote in message
news:dd8e1652.0411222115.706e19db@posting.google.com...
> The way that RSACryptoServiceProvider works is that we encrypt with a
> public key and decrypt with a private key. This architecture works
> great for people sending messages to me. However, I now have the
> opposite application:
>
> I want to put a license file on a destination computer and be sure
> that it remains unaltered. It would be great if I could encrypt it
> with a private key at our office and transmit the public key and the
> encrypted file to the destination computer, where anybody can decrypt
> it and read it, but not change it because we have the private key at
> our office.
>
> I've read posts to "simply reverse the public and private RSA keys"
> but tried several variations of switching RsaParameters.D, DP, P, DQ,
> Modulus and others, to no avail.
>
> I'm sure that a solution exists, just that I do not know it.
>
> How do I, in C# .NET, send a license file to a destination computer,
> with a public key, anybody can read it, but only we can change it?
>
> Thanks.



Re: Reverse usage of public/private RSA encryption keys for licensing? by William

William
Tue Nov 23 01:45:41 CST 2004

It works both ways otherwise you would not be able to decrypt the signature
to get the clear hash to validate the new calculated hash against. Other
implementations allow this directly. .Net allows encrypting the hash only
with the private key. And only allows you to verify the signature
(encrypted hash) using the public key. That is probably a very good thing
as it would probably confuse the heck out of people if it allowed otherwise.
Keeping your private key private is the major idea. Hash your license using
SHA1 or something and encrypt the hash using private key.
RSACryptoServiceProvider.SignData and .VerifyData are easy methods to do
all this for you. The rest of your license could be clear text (i.e. xml)
with the signature in base64. The client gets the signature bytes and runs
VerifyData passing in the clear text, hash algo, and encrypted signature
bytes. The method computes the hash and compares to the decrypted hash and
return true if equal; otherwise false. Naturally, you don't include the
signature when calculating your client hash as that was not included in the
server side hash. That way you validate that only the owner of the private
key could have signed the license. However, the client's public key still
needs to be secured as good as possible in your code or other. Otherwise a
creative user could change the public key and sign the license with their
own key pair. Obfuscating code using encryption can help in this regard.
Some obfuscators can prevent (at least for now) using ildasm/ilasm
round-tripping. Naturally if you can use ildasm on your assembly, then you
could change the public key or just remove your license "if" test(s),
thereby thwarting your public key security all together (e.g. walking around
your 1000ft high wall). You can't really get 100% protection, but you can
make it much harder for most.

--
William Stacey, MVP
http://mvp.support.microsoft.com

<charismatic_evangelist@yahoo.com> wrote in message
news:dd8e1652.0411222115.706e19db@posting.google.com...
> The way that RSACryptoServiceProvider works is that we encrypt with a
> public key and decrypt with a private key. This architecture works
> great for people sending messages to me. However, I now have the
> opposite application:
>
> I want to put a license file on a destination computer and be sure
> that it remains unaltered. It would be great if I could encrypt it
> with a private key at our office and transmit the public key and the
> encrypted file to the destination computer, where anybody can decrypt
> it and read it, but not change it because we have the private key at
> our office.
>
> I've read posts to "simply reverse the public and private RSA keys"
> but tried several variations of switching RsaParameters.D, DP, P, DQ,
> Modulus and others, to no avail.
>
> I'm sure that a solution exists, just that I do not know it.
>
> How do I, in C# .NET, send a license file to a destination computer,
> with a public key, anybody can read it, but only we can change it?
>
> Thanks.


Re: Reverse usage of public/private RSA encryption keys for licensing? by Valery

Valery
Tue Nov 23 04:56:09 CST 2004

Hi,
Use RSA singing. RSA signature with strong hash (ie. SHA1) provides much
better security than encryption of data with RSA private key (ie. what you
asked about). In fact, RSA signature was proven to be secure in random
oracle model with non-tight reduction to RSA problem (and it's even possible
to achieve tight reduction simply by adding of one single extra radom bit as
it was shown in Katz-Wang signature).

-Valery.
http://www.harper.no/valery

<charismatic_evangelist@yahoo.com> wrote in message
news:dd8e1652.0411222115.706e19db@posting.google.com...
> The way that RSACryptoServiceProvider works is that we encrypt with a
> public key and decrypt with a private key. This architecture works
> great for people sending messages to me. However, I now have the
> opposite application:
>
> I want to put a license file on a destination computer and be sure
> that it remains unaltered. It would be great if I could encrypt it
> with a private key at our office and transmit the public key and the
> encrypted file to the destination computer, where anybody can decrypt
> it and read it, but not change it because we have the private key at
> our office.
>
> I've read posts to "simply reverse the public and private RSA keys"
> but tried several variations of switching RsaParameters.D, DP, P, DQ,
> Modulus and others, to no avail.
>
> I'm sure that a solution exists, just that I do not know it.
>
> How do I, in C# .NET, send a license file to a destination computer,
> with a public key, anybody can read it, but only we can change it?
>
> Thanks.



Re: Reverse usage of public/private RSA encryption keys for licensing? by William

William
Tue Nov 23 09:34:04 CST 2004

> Use RSA singing. RSA signature with strong hash (ie. SHA1) provides much
> better security than encryption of data with RSA private key (ie. what you
> asked about).

Hi Valery. That seems to suggest that RSA signature entails more then just
encrypting the hash bytes? Is there more going on? TIA

--
William Stacey, MVP
http://mvp.support.microsoft.com



Re: Reverse usage of public/private RSA encryption keys for licensing? by Valery

Valery
Tue Nov 23 11:28:32 CST 2004

It's just that there is a theorem that proves that if we use random oracle
as hash (highest level of collision resistance), than existence of an
algorithm to forge signature (RSA private key encryption of random oracle
hash) gives ability to solve RSA problem with sufficient amount of signing
requests (non-tight reduction means that amount of signing requests could be
quite high). Hash is essential part of this theorem - ie. no hash - no
security prove. SHA1 doesn't provide the same level of collision resistance,
but having really good collision resistances properties (none has managed to
find SHA1 collision so far) it presents good practical substitution to the
random oracle. Using private exponent for encrypting arbitrary data doesn't
have any security prove.

-Valery.
http://www.harper.no/valery

"William Stacey [MVP]" <staceywREMOVE@mvps.org> wrote in message
news:OQhm1KX0EHA.1296@TK2MSFTNGP10.phx.gbl...
>> Use RSA singing. RSA signature with strong hash (ie. SHA1) provides much
>> better security than encryption of data with RSA private key (ie. what
>> you
>> asked about).
>
> Hi Valery. That seems to suggest that RSA signature entails more then
> just
> encrypting the hash bytes? Is there more going on? TIA
>
> --
> William Stacey, MVP
> http://mvp.support.microsoft.com
>
>



Re: Reverse usage of public/private RSA encryption keys for licensing? by Valery

Valery
Tue Nov 23 11:59:53 CST 2004

In other words, assuming special hash properties, there is a theorem that
proves that forging of RSA signature is at least as difficult as RSA problem
it-self. And without hash, no such proof exists - ie. without hash it may be
simpler to forger than to solve RSA problem.

-Valery.
http://www.harper.no/valery

"Valery Pryamikov" <Valery@nospam.harper.no> wrote in message
news:eIRHvEY0EHA.2012@TK2MSFTNGP15.phx.gbl...
> It's just that there is a theorem that proves that if we use random oracle
> as hash (highest level of collision resistance), than existence of an
> algorithm to forge signature (RSA private key encryption of random oracle
> hash) gives ability to solve RSA problem with sufficient amount of signing
> requests (non-tight reduction means that amount of signing requests could
> be quite high). Hash is essential part of this theorem - ie. no hash - no
> security prove. SHA1 doesn't provide the same level of collision
> resistance, but having really good collision resistances properties (none
> has managed to find SHA1 collision so far) it presents good practical
> substitution to the random oracle. Using private exponent for encrypting
> arbitrary data doesn't have any security prove.
>
> -Valery.
> http://www.harper.no/valery
>
> "William Stacey [MVP]" <staceywREMOVE@mvps.org> wrote in message
> news:OQhm1KX0EHA.1296@TK2MSFTNGP10.phx.gbl...
>>> Use RSA singing. RSA signature with strong hash (ie. SHA1) provides much
>>> better security than encryption of data with RSA private key (ie. what
>>> you
>>> asked about).
>>
>> Hi Valery. That seems to suggest that RSA signature entails more then
>> just
>> encrypting the hash bytes? Is there more going on? TIA
>>
>> --
>> William Stacey, MVP
>> http://mvp.support.microsoft.com
>>
>>
>
>



Re: Reverse usage of public/private RSA encryption keys for licensing? by charismatic_evangelist

charismatic_evangelist
Tue Nov 23 17:22:13 CST 2004

Thanks everybody for all your expertise! I (believe that I) have a
solution:

#1. Here at our office, I generate a RSA private and public key via:

System.Security.Cryptography.RSACryptoServiceProvider RSA;
RSA = new RSACryptoServiceProvider();

and save the keys via:

string privateParameters = RSA.ToXmlString(true));
string publicParameters = RSA.ToXmlString(false));

I then hash my data that I want to ensure non-tampering via:

byte[] rawData, hash;
System.Security.Cryptography.HashAlgorithm HashMan;
HashMan = new System.Security.Cryptography.SHA1CryptoServiceProvider();
hash = HashMan.ComputeHash(rawData);

I then make a signature of this hash with the RSA private Crypto:

signatureFormatter = new RSAPKCS1SignatureFormatter(RSA);
signatureFormatter.SetHashAlgorithm("SHA1");
signature = signatureFormatter.CreateSignature(hash);

... and prepend the 128-byte signature and the 20-byte hash in front
of the raw data and write back out to a new file, which becomes my
signed license file.

#2. At the destination computers, I instantiate a RSA Crypto provider:

RSAPublic = new RSACryptoServiceProvider();

and load it ONLY WITH THE PUBLIC KEY:

RSAPublic.FromXmlString(publicParameters);

I extract from the raw data the claimed signature and the claimed
hash:

byte[] rawSignature; // bytes 0 - 127 of raw data
byte[] rawHash; // bytes 128 - 147 of raw data

I skip over the first 148 (128 + 20) bytes of data to be validated and
compute a SHA1 hash of the bytes to be validated. If my hash equals
the hash stored in the file at location 128 for 20 bytes, then I
proceed, else error.

Then, I instantiate a signatureDeformatter with the public RSA Crypto:

signatureDeformatter = new RSAPKCS1SignatureDeformatter(RSAPublic);
signatureDeformatter.SetHashAlgorithm("SHA1");

and, finally, verify the signature with:

signatureDeformatter.VerifySignature(rawHash, rawSignature);

It seems to work with the few files I've tried. I thank all of you
for your valuabe input.


"Valery Pryamikov" <Valery@nospam.harper.no> wrote in message news:<#bENQWY0EHA.1264@TK2MSFTNGP12.phx.gbl>...
> In other words, assuming special hash properties, there is a theorem that
> proves that forging of RSA signature is at least as difficult as RSA problem
> it-self. And without hash, no such proof exists - ie. without hash it may be
> simpler to forger than to solve RSA problem.
>
> -Valery.
> http://www.harper.no/valery
>
> "Valery Pryamikov" <Valery@nospam.harper.no> wrote in message
> news:eIRHvEY0EHA.2012@TK2MSFTNGP15.phx.gbl...
> > It's just that there is a theorem that proves that if we use random oracle
> > as hash (highest level of collision resistance), than existence of an
> > algorithm to forge signature (RSA private key encryption of random oracle
> > hash) gives ability to solve RSA problem with sufficient amount of signing
> > requests (non-tight reduction means that amount of signing requests could
> > be quite high). Hash is essential part of this theorem - ie. no hash - no
> > security prove. SHA1 doesn't provide the same level of collision
> > resistance, but having really good collision resistances properties (none
> > has managed to find SHA1 collision so far) it presents good practical
> > substitution to the random oracle. Using private exponent for encrypting
> > arbitrary data doesn't have any security prove.
> >
> > -Valery.
> > http://www.harper.no/valery
> >
> > "William Stacey [MVP]" <staceywREMOVE@mvps.org> wrote in message
> > news:OQhm1KX0EHA.1296@TK2MSFTNGP10.phx.gbl...
> >>> Use RSA singing. RSA signature with strong hash (ie. SHA1) provides much
> >>> better security than encryption of data with RSA private key (ie. what
> >>> you
> >>> asked about).
> >>
> >> Hi Valery. That seems to suggest that RSA signature entails more then
> >> just
> >> encrypting the hash bytes? Is there more going on? TIA
> >>
> >> --
> >> William Stacey, MVP
> >> http://mvp.support.microsoft.com
> >>
> >>
> >
> >

Re: Reverse usage of public/private RSA encryption keys for licensing? by William

William
Tue Nov 23 23:48:00 CST 2004

Sound pretty good. However I would not transfer the hash twice (once
encrypted and once clear). Your hash is already in the signature, but
encrypted. Use VerifyData to verify signature using your data. Internally
it does a new hash of the data, decrypts the signature to get the orig hash
and compares the two.

--
William Stacey, MVP
http://mvp.support.microsoft.com

<charismatic_evangelist@yahoo.com> wrote in message
news:dd8e1652.0411231522.456f459@posting.google.com...
> Thanks everybody for all your expertise! I (believe that I) have a
> solution:
>
> #1. Here at our office, I generate a RSA private and public key via:
>
> System.Security.Cryptography.RSACryptoServiceProvider RSA;
> RSA = new RSACryptoServiceProvider();
>
> and save the keys via:
>
> string privateParameters = RSA.ToXmlString(true));
> string publicParameters = RSA.ToXmlString(false));
>
> I then hash my data that I want to ensure non-tampering via:
>
> byte[] rawData, hash;
> System.Security.Cryptography.HashAlgorithm HashMan;
> HashMan = new
System.Security.Cryptography.SHA1CryptoServiceProvider();
> hash = HashMan.ComputeHash(rawData);
>
> I then make a signature of this hash with the RSA private Crypto:
>
> signatureFormatter = new RSAPKCS1SignatureFormatter(RSA);
> signatureFormatter.SetHashAlgorithm("SHA1");
> signature = signatureFormatter.CreateSignature(hash);
>
> ... and prepend the 128-byte signature and the 20-byte hash in front
> of the raw data and write back out to a new file, which becomes my
> signed license file.
>
> #2. At the destination computers, I instantiate a RSA Crypto provider:
>
> RSAPublic = new RSACryptoServiceProvider();
>
> and load it ONLY WITH THE PUBLIC KEY:
>
> RSAPublic.FromXmlString(publicParameters);
>
> I extract from the raw data the claimed signature and the claimed
> hash:
>
> byte[] rawSignature; // bytes 0 - 127 of raw data
> byte[] rawHash; // bytes 128 - 147 of raw data
>
> I skip over the first 148 (128 + 20) bytes of data to be validated and
> compute a SHA1 hash of the bytes to be validated. If my hash equals
> the hash stored in the file at location 128 for 20 bytes, then I
> proceed, else error.
>
> Then, I instantiate a signatureDeformatter with the public RSA Crypto:
>
> signatureDeformatter = new RSAPKCS1SignatureDeformatter(RSAPublic);
> signatureDeformatter.SetHashAlgorithm("SHA1");
>
> and, finally, verify the signature with:
>
> signatureDeformatter.VerifySignature(rawHash, rawSignature);
>
> It seems to work with the few files I've tried. I thank all of you
> for your valuabe input.
>
>
> "Valery Pryamikov" <Valery@nospam.harper.no> wrote in message
news:<#bENQWY0EHA.1264@TK2MSFTNGP12.phx.gbl>...
> > In other words, assuming special hash properties, there is a theorem
that
> > proves that forging of RSA signature is at least as difficult as RSA
problem
> > it-self. And without hash, no such proof exists - ie. without hash it
may be
> > simpler to forger than to solve RSA problem.
> >
> > -Valery.
> > http://www.harper.no/valery
> >
> > "Valery Pryamikov" <Valery@nospam.harper.no> wrote in message
> > news:eIRHvEY0EHA.2012@TK2MSFTNGP15.phx.gbl...
> > > It's just that there is a theorem that proves that if we use random
oracle
> > > as hash (highest level of collision resistance), than existence of an
> > > algorithm to forge signature (RSA private key encryption of random
oracle
> > > hash) gives ability to solve RSA problem with sufficient amount of
signing
> > > requests (non-tight reduction means that amount of signing requests
could
> > > be quite high). Hash is essential part of this theorem - ie. no hash -
no
> > > security prove. SHA1 doesn't provide the same level of collision
> > > resistance, but having really good collision resistances properties
(none
> > > has managed to find SHA1 collision so far) it presents good practical
> > > substitution to the random oracle. Using private exponent for
encrypting
> > > arbitrary data doesn't have any security prove.
> > >
> > > -Valery.
> > > http://www.harper.no/valery
> > >
> > > "William Stacey [MVP]" <staceywREMOVE@mvps.org> wrote in message
> > > news:OQhm1KX0EHA.1296@TK2MSFTNGP10.phx.gbl...
> > >>> Use RSA singing. RSA signature with strong hash (ie. SHA1) provides
much
> > >>> better security than encryption of data with RSA private key (ie.
what
> > >>> you
> > >>> asked about).
> > >>
> > >> Hi Valery. That seems to suggest that RSA signature entails more
then
> > >> just
> > >> encrypting the hash bytes? Is there more going on? TIA
> > >>
> > >> --
> > >> William Stacey, MVP
> > >> http://mvp.support.microsoft.com
> > >>
> > >>
> > >
> > >


Re: Reverse usage of public/private RSA encryption keys for licensing? by Morten

Morten
Wed Nov 24 06:45:44 CST 2004

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

charismatic_evangelist@yahoo.com wrote:
| System.Security.Cryptography.RSACryptoServiceProvider RSA;
| RSA = new RSACryptoServiceProvider();

I don't know if this still applies, but I was taught to use

RSA rsa = RSA.Create(); // By default RSACryptoServiceProvider

instead of

RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();

- - I've haven't tested if this breaks any constrains in the formatter
though. Anyway, it could be used for the hash algorithm as well:

SHA1 sha = SHA1.Create(); // By default SHA1CryptoServiceProvider

This way you can change the implementation of RSA and SHA1 without
recompiling the source.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.5 (MingW32)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFBpIJ42XTueCwB3DoRAgAEAJ4+Fb+dJc3xsaJxzkTPcVmlHr7JiQCeMAl8
kfq+xH4uoZyZqmqdO1k92EE=
=acJZ
-----END PGP SIGNATURE-----

Re: Reverse usage of public/private RSA encryption keys for licensing? by William

William
Wed Nov 24 11:23:02 CST 2004

> RSA rsa = RSA.Create(); // By default RSACryptoServiceProvider
> instead of
> RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();

TMK, it is the same thing as RSA is an abstract base class and
RSACryptoServiceProvider is currently the only concret class that derives
from RSA. Some other stuff goes on in Create, but you end up with an
RSACryptoServiceProvider:

RSA rsa = RSA.Create();
Console.WriteLine("Type:"+rsa.GetType().ToString());
--Output
Type:System.Security.Cryptography.RSACryptoServiceProvider

--
William Stacey, MVP
http://mvp.support.microsoft.com


Reverse usage public/private RSA encryption keys licensing ... X509? by charismatic_evangelist

charismatic_evangelist
Thu Nov 25 13:10:37 CST 2004

I thank William Stacey for teaching me that I do not need to store
hash twice, and Morten Dahl for: RSA rsa = RSA.Create();

I now have a solution (to verify that our license has not been
tampered with) that works.

Further, I have recently become aware of X509 Certificates. Because
Microsoft C# .NET has a whole namespace for X509Certificates:

1. Can I alternatively use X509 to verify that our license has
remained untouched?

2. Is it worth the additional effort?

3. Is the X509 buzzword (A) so prevalent and (B) so respected that our
marketeers can brag about our using it and make our software more
marketable? :-)

Happy Thanksgiving!



"William Stacey [MVP]" <staceywREMOVE@mvps.org> wrote in message news:<uUw5Zsk0EHA.2040@tk2msftngp13.phx.gbl>...
> > RSA rsa = RSA.Create(); // By default RSACryptoServiceProvider
> > instead of
> > RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
>
> TMK, it is the same thing as RSA is an abstract base class and
> RSACryptoServiceProvider is currently the only concret class that derives
> from RSA. Some other stuff goes on in Create, but you end up with an
> RSACryptoServiceProvider:
>
> RSA rsa = RSA.Create();
> Console.WriteLine("Type:"+rsa.GetType().ToString());
> --Output
> Type:System.Security.Cryptography.RSACryptoServiceProvider

Re: Reverse usage public/private RSA encryption keys licensing ... X509? by Valery

Valery
Fri Nov 26 02:27:20 CST 2004

Hi,
Certificates bind public key to identity and validity timespan.
Additionally, X509 standard defines series of protocols such as exchange,
validation and keys revocation. If you find that you need any of protocols
or features defined by X509 standard (and you most probably will) - then you
must definitely use the standard instead of attempting to invent your own
scheme.

-Valery.

<charismatic_evangelist@yahoo.com> wrote in message
news:dd8e1652.0411251110.1e69fa5a@posting.google.com...
>I thank William Stacey for teaching me that I do not need to store
> hash twice, and Morten Dahl for: RSA rsa = RSA.Create();
>
> I now have a solution (to verify that our license has not been
> tampered with) that works.
>
> Further, I have recently become aware of X509 Certificates. Because
> Microsoft C# .NET has a whole namespace for X509Certificates:
>
> 1. Can I alternatively use X509 to verify that our license has
> remained untouched?
>
> 2. Is it worth the additional effort?
>
> 3. Is the X509 buzzword (A) so prevalent and (B) so respected that our
> marketeers can brag about our using it and make our software more
> marketable? :-)
>
> Happy Thanksgiving!
>
>
>
> "William Stacey [MVP]" <staceywREMOVE@mvps.org> wrote in message
> news:<uUw5Zsk0EHA.2040@tk2msftngp13.phx.gbl>...
>> > RSA rsa = RSA.Create(); // By default RSACryptoServiceProvider
>> > instead of
>> > RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
>>
>> TMK, it is the same thing as RSA is an abstract base class and
>> RSACryptoServiceProvider is currently the only concret class that derives
>> from RSA. Some other stuff goes on in Create, but you end up with an
>> RSACryptoServiceProvider:
>>
>> RSA rsa = RSA.Create();
>> Console.WriteLine("Type:"+rsa.GetType().ToString());
>> --Output
>> Type:System.Security.Cryptography.RSACryptoServiceProvider