Groups | Blog | Home
all groups > dotnet security > march 2005 >

dotnet security : Problem with RSACryptoServiceProvider ( incorrect usage of public-private keys ? )



Linas Kricenas
3/28/2005 6:26:23 PM
Hello,

I want to encypt a small ( I'm aware that max 117 bytes may be encryptes
with RSA ) portion of data with private key and later to decrypt it with a
public key which will be embeded in my code.

The problem I am expieriencing is that I _cannot_ decrypt anything with
public key - no matter whether data was encrypted with public or private
key. And I _can_ decrypt everything with private key that was encrypted with
public _or_ private key.

As far as I understand, only the following situations must be possible in
public-private key encryption:
1) encrypt_with_public / decrypt_with_private
2) encrypt_with_private / decrypt_with_public

Could You please take a look at the short example below and tell me what I
am doing wrong.
Thank You for Your time!

Linas

// A new public-private key pair is generated after instantiation
RSACryptoServiceProvider RSA = new
System.Security.Cryptography.RSACryptoServiceProvider();

string publicKey = RSA.ToXmlString( false ); // gets the public key as XML
string privateKey = RSA.ToXmlString( true ); // gets the private key as XML

// The private key contains a public one (at the beginning of XML string) -
I suppose it is normal
Console.WriteLine("\n\nPUBLIC KEY\n" + publicKey );
Console.WriteLine("\n\nPRIVATE KEY\n" + privateKey );

string str = "AAA";
RSACryptoServiceProvider RSA2 = new RSACryptoServiceProvider();
// Load private key
RSA2.FromXmlString( privateKey );

// Encrypt with private
byte[] EncryptedStrAsByt = RSA2.Encrypt(
System.Text.Encoding.Default.GetBytes( str ), false );
string EncryptedStrAsString = System.Text.Encoding.Default.GetString(
EncryptedStrAsByt );


RSACryptoServiceProvider RSA3 = new RSACryptoServiceProvider();
// Load public key
RSA3.FromXmlString( publicKey );

// Try to decrypt with public
byte[] DecryptedStrAsByt = RSA3.Decrypt(
System.Text.Encoding.Default.GetBytes( EncryptedStrAsString ), false );
string DecryptedStrAsString = System.Text.Encoding.Default.GetString(
DecryptedStrAsByt );

Console.WriteLine("Decrypted string = {0}", DecryptedStrAsString );

---------------------------------------------------------------------------
I get the following exception when trying to decrypt

System.Security.Cryptography.CryptographicException: Bad Key.
at
System.Security.Cryptography.RSACryptoServiceProvider._DecryptPKWin2KEnh(I
ntPtr hPubKey, Byte[] rgbKey, Boolean fOAEP)
at System.Security.Cryptography.RSACryptoServiceProvider.Decrypt(Byte[]
rgb,
Boolean fOAEP)
at Test.Main(String[] args) in d:\test\test.cs:line 116

Decryption succeeds if I change 'RSA3.FromXmlString( publicKey );' to
'RSA3.FromXmlString( privateKey );'

What is the problem ?

P.S. I tried to pass instance of CspParameters as a RSACryptoServiceProvider
constructors parameter but it does not work as I expect.

I don't want to use any key containers ( that are stored in user profile
data in registry if I understood correctly ) because a program that uses
decryption would run of various computers (could be spread as a demo
program, etc ).













Valery Pryamikov
3/28/2005 7:11:28 PM
Hi,

CAPI doesn't allows to encrypt with private key and decrypt with public key
(RSACryptoServiceProvier is p/invoking CAPI for performing its work).
there are only two things that CAPI allows you to use public key for:
- signature validation;
- encryption of other key (or other short piece of data), known as key
export;

This limitation is due to several reasons. The most important are:
- historical. CAPI was designed during the time of US Exporting restrictions
on strong cryptographic algorithm. This made it necessary to distinguish RSA
encryption (which was restricted to 512 bit modulus) and signing (that
didn't have such restriction).
- preventive. CAPI tries to protect you from shooting yourself in your leg
by prohibiting operations that's more often leads to subtle flaws and
protocol failures.
- others. like decryption is implemented by single routine that requires
long form of key (with both primes and their inverses) for using Chinese
remainder theorem and Gauss algorithm for gaining 75% performance during
decryption operation. Last is important for protecting against denial of
service when server is required to decrypt many requests from different
clients (ex. SSL session negotiation). Apparently this routine can't be used
with public key - knowledge of primes is the analogy to knowledge of private
key.

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

[quoted text, click to view]
Valery Pryamikov
3/28/2005 7:54:16 PM
A couple of other corrections:

[quoted text, click to view]

this is actually incorrect. Two main operations supported by public key
cryptosystems are:
- encryption;
- digital signatures;

encryption assumes using of public key for encrypting information and
private key for decrypting information.
Digital signatures assumes use of private key for signing transformation and
use of public key for signature validation.
Some public key cryptosystems allows signatures with message recovery (raw
RSA - i.e. RSA trapdoor permutation with private key applied to plain text
message). That message recovery is what you call decrypt with public key
operation. Problem with using RAW RSA encryption (or RAW RSA signature with
message recovery) is that RAW RSA IS BROKEN DEAD. If someone says you
otherwise it could be either due to insufficient knowledge of subject or
because of misuse of RSA acronym for naming many different things:
- RSA trapdoor permutation, which is one of the most important cryptographic
primitives and is very well indeed;
- raw RSA encryption system as it was described in the paper by Rivest,
Shamir, Adleman in 1977. i.e. using RSA trapdoor permutation on non padding
messages. This is drop dead long ago due to many terrible weaknesses that
were found since RSA invention.
- OAEP RSA - is very well and is provably secure.
- PKCS 1.5 RSA is quite well, even so not provably secure, and is subject to
several attacks (like Bleichenbacher's attack on RSA PKCS 1.5 reporting
padding errors back to adversary)
- RSA signature with prefix (i.e. message hash encrypted with private key).
This is very well and if we assume that hash provides us with specific
properties (behaves as random oracle) - RSA signature on such hash is
provably secure.

A number of attacks on raw RSA is so big that the are only two ways of
keeping your system safe against these attack is to use non-broken RSA
mode - or be really very proficient within the field (at least a couple of
decades), know all the attacks, how they could apply to your use of RSA
trapdoor permutation and make sure that your system is protected against
them. If I speak for me - I know that I don't qualify for the last - so I
stick to the first and only use schemes that are proven to be secure.

-Valery.
http://www.harper.no/valery
AddThis Social Bookmark Button