Re: OpenNETCF Cryptography questions - using RSA for licensing strategy

Tech-Archive recommends: Fix windows errors by optimizing your registry

From: gcrasher (gcrasher76_at_yahoo.com)
Date: 09/16/04


Date: 16 Sep 2004 08:27:05 -0700

Thanks for your quick response.

Maybe I confused things by saying I was creating the keypair on the
device. I thought it shouldn't matter, but really the desktop is the
sender of the message so lets say I create the keypair on the desktop
and encrypt a message using the private key. Why can't the device now
decrypt this message with knowledge of the public key only? This is
what I can't understand or get to work.

Also remember I am not trying to hide data, only verify the sender.
Thats why I need to encrypt with a private key and decrypt with a
public key.

"casey chesnut" <casey@MORE_spam_PLEASEbrains-N-brawn.com> wrote in message news:<OTZxps5mEHA.3352@TK2MSFTNGP15.phx.gbl>...
> the public / private keys are stored on the device.
> the CryptoAPI does this ... on the desktop too.
> they are named rSaContainer and rSaContainerImp,
> depending if it is for the devices key pair or being imported respectively.
> the code is in RSACryptoServiceProvider.cs
>
> the following code worked for me.
> it creates the private key on the device,
> passes the private key and plainText to a WS.
> the WS loads the private key and encrypts,
> then returns the cipherText and public key.
> device loads public key and decrypts.
>
> /// DEVICE CODE /////////
> //create key pair on device
> RSACryptoServiceProvider rsa = new
> RSACryptoServiceProvider(KeySpec.KEYEXCHANGE, true);
> string privKey = rsa.ToXmlString(true);
> string pubKey = rsa.ToXmlString(false);
>
> string strData = "text for server to encrypt";
> byte [] baData = Format.GetBytes(strData);
>
> //call web service on device to encrypt
> CryptoServ.Crypto cServ = new CryptoServ.Crypto();
> cServ.Url = csUrl;
>
> string outPubKey;
> string retCipher = cServ.AsymRsaDec(strData, privKey, out outPubKey);
> byte [] outCipher = Format.GetB64(retCipher);
>
> //decrypt on device
> RSACryptoServiceProvider rsa2 = new RSACryptoServiceProvider();
> rsa2.FromXmlString(outPubKey);
> byte [] baUnEnc = rsa2.DecryptValue(outCipher);
> Format.SameBytes(baData, baUnEnc);
>
> MessageBox.Show("success");
>
> /// WEB SERVICE CODE ON DESKTOP ///////
> [WebMethod]
> public string AsymRsaDec(string plain, string privKey, out string outPubKey)
> {
> byte[] _plain = GetBytes(plain);
> RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
> rsa.FromXmlString(privKey);
> byte[] ciphertext = rsa.Encrypt(_plain, false);
> outPubKey = rsa.ToXmlString(false);
> return GetBase64(ciphertext);
> }
>
> casey
>
> "gcrasher" <gcrasher76@yahoo.com> wrote in message
> news:d06bbb7f.0409151053.5f0c066a@posting.google.com...
> > I've been trying to figure this out for a while and don't understand
> > what's going on.
> >
> > I'm using RSA algorithm to implement a licensing strategy in which the
> > hardware ID is sent to me, encrypted, and sent back to be decrypted on
> > the device, thus verifying that I actually created the data. This
> > requires encrypting on the desktop using my secure private key, and
> > unencrypting on the device using a public key.
> >
> > For the device I'm using the OpenNET.Security.Cryptography classes and
> > System.Security.Cryptography classes on the desktop (for my license
> > creation utility).
> >
> > I'm not understanding how the key containers work on the device using
> > OpenNETCF classes and I'm guessing that is part of my problem. Unless
> > I create the public/private keys on the device, I get a NTE_BAD_KEY
> > error when trying to decrypt on the device. When a new key set is
> > generated on the device (not to be used, just to *reset* the device so
> > I can attempt to provide my own public key), the old public key no
> > longer decrypts the old data it used to decrypt. If I use the keys the
> > device last generated then my code works fine.
> >
> > It seems that when creating the keys on the device, the public key is
> > stored somehow and even though I am specifying my own public key, the
> > OpenNETCF classes somehow are utilizing or checking that container
> > (maybe?). This decryption will need to occur on devices where the keys
> > were not generated. How is it possible for me to provide the public
> > key myself? Anyone have any ideas how I can get this working the way I
> > need to?
> >
> > Thanks!
> >
> >
> > I've included the code being used below:
> >
> > --------------------------------------
> > ---Create key pair using the device---
> > --------------------------------------
> >
> > using OpenNET.Security.Cryptography;
> >
> > RSACryptoServiceProvider rsa = new
> > RSACryptoServiceProvider(OpenNETCF.Security.Cryptography.NativeMethods.KeySpec.KEYEXCHANGE,
> > true);
> >
> > // Save the public key to pubkey.txt
> > FileStream fs = new FileStream("pubkey.txt", FileMode.Create);
> > StreamWriter sw = new StreamWriter(fs);
> > sw.Write(rsa.ToXmlString(false));
> >
> > // Save the private key to privkey.txt
> > fs = new FileStream("privkey.txt", FileMode.Create);
> > sw = new StreamWriter(fs);
> > sw.Write(rsa.ToXmlString(true));
> >
> > ---------------------------------
> > ---Encrypt data on the desktop---
> > ---------------------------------
> >
> > using System.Security.Cryptography;
> >
> > string plain = "Text to be encrypted.";
> > RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
> >
> > // Get the XML string from the privkey.txt file
> > FileStream fs = new FileStream("privkey.txt", FileMode.Open);
> > StreamReader sr = new StreamReader(fs);
> > string privateKeyString = sr.ReadToEnd();
> >
> > // Load private key
> > rsa.FromXmlString(privateKeyString);
> >
> > // convert the plaintext to a byte array using UTF-8
> > UTF8Encoding utf8 = new UTF8Encoding();
> > byte[] plaintext = utf8.GetBytes(plain);
> >
> > // Encrypt the plaintext
> > byte[] ciphertext = rsa.Encrypt(plaintext, false);
> >
> > // Create encrypted output file.
> > FileStream ciphertextfile = new FileStream(outputFile,
> > FileMode.Create);
> > ciphertextfile.Write(ciphertext, 0, ciphertext.Length);
> >
> >
> > -----------------------------------
> > ---Decrypt data using the device---
> > -----------------------------------
> >
> > using OpenNET.Security.Cryptography;
> >
> > string publicKey =
> > <RSAKeyValue><Modulus>qe9vUaTreNvSRynh36T4b74VRqdCOEHhX1xrkdmrwkRBs5yhRBAD+BM2yB5kL7aA
> > BLvW+biQAZCfVDnh3wIMUuzd9pwYaU8FtL8pnq7EEu6ps3a5C7M63fZTj1slFSiTMiGY6rCMOCajSFeOEULMPF
> > Ukj5wJ8WBjWWtRU1HYt/U=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
> >
> > RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
> > UTF8Encoding utf8 = new UTF8Encoding();
> >
> > // Read encrypted file.
> > byte[] encryptedBytes = Utility.ReadFile(encryptedFileName);
> >
> > // Set public key.
> > rsa.FromXmlString(publicKey);
> >
> > // Decrypt bytes.
> > string unencryptedString = new
> > String(utf8.GetChars(rsa.DecryptValue(encryptedBytes)));



Relevant Pages