RSA / CryptoEX Question...

Tex8503

Active Member
Licensed User
Longtime User
Soo.... I'm still working on my encrypted installer. I've decided on RSA because of the public/private key nature and am using CryptoEX to do so.

I read here ( RSA Private Key Encryption - CodeProject ) that you should be able to sign data with the private key and decrypt it with the public.

But when I try this with my app - it doesn't seem to work.

I generated my public/private keys with this code originally:
B4X:
   'Make new Public/Private Key
   privatekey() = Rsa.ExportKey(True)
   publickey() = Rsa.ExportKey(False)
   
   FileOpen(c1,"privatekey.bin",cRandom)
      Bin.New1(c1,True)
      bin.WriteBytes(privatekey())
   FileClose(c1)
   
   FileOpen(c1,"publickey.bin",cRandom)
      Bin.New1(c1,True)
      bin.WriteBytes(publickey())
   FileClose(c1)
   'End Making New Keys


Then I've got the following code:
B4X:
   'regen public key
   FileOpen(c1,"publickey.bin",cRandom)      
      bin.New1(c1,True)
      arraysize = FileSize("publickey.bin")
      Dim rebuiltpublickey(arraysize) As byte
      bin.ReadBytes(rebuiltpublickey(),arraysize)
   FileClose(c1)

   'regen private key
   FileOpen(c1,"privatekey.bin",cRandom)
      bin.New1(c1,True)
      arraysize = FileSize("privatekey.bin")
      Dim rebuiltprivatekey(arraysize) As byte
      bin.ReadBytes(rebuiltprivatekey(),arraysize)
   FileClose(c1)
   
   'encrypt data
   FileOpen(c1,"license.bin",cRandom)
      Rsa.ImportKey(rebuiltprivatekey())
      code() = Rsa.EncryptString(b64key,False)
      Bin.New1(c1,True)
      bin.WriteBytes(code())
   FileClose(c1)
   
   'getsize & data from license.bin
   FileOpen(c1,"license.bin",cRandom)
      bin.New1(c1,True)
      arraysize = FileSize("license.bin")
      Dim code(arraysize) As byte
      bin.ReadBytes(code(),arraysize)
   FileClose(c1)
   
   'decrypt license.bin
   FileOpen(c1,"testresults-decrypted.txt",cWrite)
      Rsa.ImportKey(rebuiltpublickey())
      decode = Rsa.DecryptString(code(),False)
      FileWrite(c1,decode)
      origdata = b64.Base64ToString(decode)
      FileWrite(c1,origdata)
   FileClose(c1)
End Sub

The encrypt piece seems to work and it can create license.bin - but when I go to decrypt it, it dies on the Rsa.ImportKey(rebuiltpublickey()) line with an error of : "bad key".

Any ideas?

EDIT:
I should add my goal is to be able to create keys with my PC based app and the private key. Then I'm writing a second piece that would just have the public key and would reside on the PPC device side to decrypt the data. But right now I'm testing this all on the PC.
 
Last edited:

Tex8503

Active Member
Licensed User
Longtime User
I answered my own question. The simple answer is : I'm an idiot. I needed to read that page more.

You can't encrypt the data and do what I'm trying to do. BUT you can send the data as plain text and a verification signature. Then you can run the verify again the data and check if it passes or fails. Not great if you don't want people to know what data you're sharing - but good if you're trying to check the validity of the data.
 

Zenerdiode

Active Member
Licensed User
...that you should be able to sign data with the private key and decrypt it with the public.

You appear to be using the keys the wrong way round :confused:

RSA is an asymmetric encryption. A public and private key is generated. The public key is distributed, well, publically. It doesn't matter who has it. Data is then encrypted with the public key. However, anyone else who has your public key can't use that same public key to decrypt the data. Only your private key, that is never distributed and only you hold, is able to decrypt the data.
 
Last edited:

Tex8503

Active Member
Licensed User
Longtime User
Yeah. It appeared I was trying to use it in a way it wasn't meant to be used. For a licensing scheme - It seemed like encrypting the data was a good idea - but you wouldn't want to distribute the private key to allow its decryption - but you can't read the data with the public key and the public key also can't encrypt the data to do a decent comparison - so this wasn't working for me.

But as I stated in my 2nd post, I found a way to do what I wanted (to have our encryption software store the private key and then to have our installers utilize the public key - and its by signing the data rather than encrypting it.

Rather than encrypting the person's device info directly - I'm transmitting data about the software/hardware via plain text (well encoded into Base 64...) and signing that data with the private key. Then the installation files have that data in a registration file and ship with the public key. Then at runtime, I check the license file against the public key to verify it hasn't been tampered with and then grab the same data in the license file from the unit (data that can't be tampered with) and encode it in base64. If both match, then the device is licensed - if they don't, then the license file doesn't match the device and it should fail.

It probably isn't the BEST way of doing it - but for our purposes, it works. Mainly because it'd be so hard to break those keys and we're not transmitting user data, it's not a problem. If someone reverse engineered the plain text info we're transmitting - they'd just get the app name, version number and the configuration or serial number of the device we're registering the software for.

I think this will end up being more secure than any other symmetrical encryption system as there's no pass phrase to transmit that has to be included with the distributed application at runtime. If someone were to find that key - they could create as many licenses as they wanted. But here, we're not transmitting any data that could be used to create new registrations. The only way they could break this scheme is to somehow try and spoof the serial number of the hardware...
 

mjcoon

Well-Known Member
Licensed User
You appear to be using the keys the wrong way round :confused:

RSA is an asymmetric encryption. A public and private key is generated. The public key is distributed, well, publically. It doesn't matter who has it. Data is then encrypted with the public key. However, anyone else who has your public key can't use that same public key to decrypt the data. Only your private key, that is never distributed and only you hold, is able to decrypt the data.

That is true for encryption for secrecy. The secret is destined to be read only by the one person who holds the secret key. But it seems that Tex8503 doesn't really want secrecy, he wants validation of authenticity of the licence. This is much more like checking a signature, not encryption for secrecy.

However this application differs from the usual signature check, in which anyone with the widely distributed public key can check a signature. This is because the licence itself is tied to the destination device, which provides verification of the recipient as well. In effect the full signature is only available when the serial number is added in.

Mike (who spent years working on a complex commercial cryptographic system - now re-implemented - before retiring).
 

Tex8503

Active Member
Licensed User
Longtime User
Ha... Mike.... That's a better way of explaining it than I did... and you're actually mentioning something I should do.

In my current version - I'm transmitting the serial number as well. But the truth is that I don't need to transmit ANY plain text data (the three pieces I'm verifying are app name, app version (both of which are stored in the app), and device config or serial number (which can only be pulled off the device's sdk and are hardbuilt in).

So In actuality, because I can generate all that data at runtime - I shouldn't need to transmit the plain text - just the signature that i'll check against the data that I can build at runtime.

Well... that made my morning a little better! :)
 
Top