Xojo RSA Keys are different

I am experiencing issues converting encrypted data between Xojo and other environments such as PHP. In fact, I just can’t do it most likely because Xojo RSA Crypt generates a very different Public and Private than usual:

Xojo Private Key generated with Crypto.RSAGenerateKeyPair:

30820275020100300D06092A864886F70D01010105000482025F3082025B02010002818100D0F8B08EF811D9E6473153BA4733C672DC962FE02772A3C073F0E1D5A1149C926399314A946C8536D79D59EB62665B5A326B7D33F3F960B3F3996FEC2717AD22D489FEC3A5E5B1CB14F0C01FE75DC7A6838ED0F46C77A05B7B89560ECA070527A11B1554055F4B7C72FC337F58FA6B8835FA7F93D62E0EEEE9A0697E8DE2D1BB02011102818049C12F4184BB019C9198F05FDCE518DD3ECB986D3B1966F8A16413789334737EF5F9D529618FB68BD3A0F28F4FE7E401B7713B3F8348F4F437DBCD262BEA3D1AB6039B4731CF4A74543981EDE6D6AA589D6F996E7B31835E89F23B2323D462590B004AD50C36021795521C3D20B941734BE974E52349956D7124013674C110D1024100D19968A9442C323B3F598AE56EA72C4AB9DAB177E538C3CFB756F89B014F91B6FD86FF74DD21BF68FD71FA35DC78ECAA1A4400B68EB613F227EB1CBB70112B43024100FF3BB37B5498D7463C499A6DC0010E0B60F7ECC37F87E8553D59609038885CC9AF1341D8DAF9DB7B4E76E946F51F456CC4A108FEB8D228F15679F3FE28594C29024024FCF45A1B16DBB01A3CFA64B92C8F587B2697C9DD28228E114B954887C2BF5C8717D2BA452412B82CB9C2BE35F738D2B9574B6B82989A1BACB1051204B7BC57024100E134AD6CD22C81B6716E1ED94F0FFD55558F768E6177EB1E08F4826122D2AC397C5C4928C136D0B8180E9198F666E2E78051DAC2A313C9C5E2E41385E75DD9C9024100C4058212C84057B930B34C511147BCEE6ED3EAF883C6FF18596377C729CB9E3007BB5AC4FA98494C7DC67B67A357EB397D1EB954049931314EE0A05447FDB218

Other Private Key generated with PHP phpseclib (RSA module):

-----BEGIN RSA PRIVATE KEY----- MIICXgIBAAKBgQDEWswgIEU17/NK/7l6zgBtaWyTEkJlvlrRm4ccKmnQEmMZHF6u +Cm+5Uksn5mdKgWyviuFNKYPQAGidBe95peK6UEgH3ATxqVQlx9JEOKjg49TlNlJ 378xbmExLC10jNmC+2NqYVAsuF+TNcurVDZjHoDNgh+HxJJPr3XOv8urnwIDAQAB AoGBAKlgvZa0358QdqlqgMBbdWjsORmA9b+4fbU0WU9FkvNG+S8PFuoN7kzaks2o eyVku3edrgMBEII1L3PIezZ39J39hswE0mWc6aIcIDcm7LCaXeRcrgjzFHaABHQP tA/SKzUCh0t/NHOfYxQpxOqIqE71c97fl/U0EhQiZEcUV+m5AkEA+LQo+haaHgYD Hdhtow82eyJ+W1mLblNncg+wBcWkGRfSABKiKL8Tx9w22+SVjnV1xnMdXdP8uyXN fGvhNiGe/QJBAModeuLBCBdhKjCp31BNSQ4Z9hDkRRxJXv9FZA8wL5dgVgNoAyen WbRS7YMQmEkNoAq80K4kiFCuLEbYBN+6zcsCQQCNLSe9nyrpNBx8yqih0Tbp+xCj JleBzxJ/quwOuryGCgGJTQqD+sNtxlHVzRIghgjPF/Vpl7Z1PeZBZLO5GKi5AkEA mfr1qRVY3b73zpVMfbgzpRugPOQ7xr4bMq2h+nRCfbg2L2gppyc3D0tyiby12Eoa GLQa4+EPPTBEqUBgDjcaGwJAQtKW6jaCSBsP3Ck/b0rJ+L+wyfT4E7lfpuIh6jDJ 4HMlRNLvpaeXsJ3bZrHSGqQHpgV9/uUGKNjTAw0foKOT9w== -----END RSA PRIVATE KEY-----

Does anyone know how to implement an OpenSSL RSA Encrypt Decrypt in Xojo using these phpseclib style keys ?

The one is hex encoded, the other one base64?

DecodingBase64 the Xojo key would work ?

Since usually this key is a pure string, I will also need to convert DecodedBase64 result back to string right ?

You need to use the import and export methods on the Crypto module to make the key accessible to other tools.

Look at the BER and DER methods on the Crypto class.

Edit - Sorry, I should have just put the methods here for you:

[h]To convert an RSA private key to a PEM private key:[/h]

[code]Function EncodePEMPrivateKey(privateKey as MemoryBlock) As String
const header = “-----BEGIN RSA PRIVATE KEY-----”
const footer = “-----END RSA PRIVATE KEY-----”

dim keystr as String
try
keystr = crypto.DEREncodePrivateKey(privateKey)
keystr = EncodeBase64(keystr)
keystr = header + EndOfLine + keystr + EndOfLine + footer
catch ex as CryptoException
return “”
end try

return keystr
End Function
[/code]

[h]To convert an RSA public key to a PEM public key:[/h]

[code]Function EncodePEMPublicKey(publicKey as MemoryBlock) As String
const header = “-----BEGIN CERTIFICATE-----”
const footer = “-----END CERTIFICATE-----”

dim keystr as String
try
keystr = crypto.DEREncodePublicKey(publicKey)
keystr = EncodeBase64(keystr)
keystr = header + EndOfLine + keystr + EndOfLine + footer
catch ex as CryptoException
return “”
end try

return keystr
End Function
[/code]

You’ll need to check the output. If it’s blank. there was an error converting the key.

If you need to go in the other direction:

[h]To convert a PEM private key to an RSA private key:[/h]

[code]Function DecodePEMPrivateKey(PEMPrivateKey as String, ByRef EncodedKey as MemoryBlock) As Boolean
const header = “-----BEGIN RSA PRIVATE KEY-----”
const footer = “-----END RSA PRIVATE KEY-----”

//Make sure the header and footer exist
if instr(PEMPrivateKey,header)=0 or instr(PEMPrivateKey,footer) = 0 then
return False
end if

dim pos1 as integer = instr(PEMPrivateKey,header)+len(header)
dim pos2 as integer = instr(PEMPrivateKey,footer)
dim size as integer = pos2-pos1

if size <= 0 then
return False
end if

dim keystr as string = mid(PEMPrivateKey,pos1,size)

keystr = DecodeBase64(keystr)

try
encodedkey = crypto.BERDecodePrivateKey(keystr)

catch ex as CryptoException
return False
end try

return true
End Function
[/code]

[h]To convert a PEM public key to an RSA public key:[/h]

[code]Function DecodePEMPublicKey(PEMPublicKey as String, ByRef EncodedKey as MemoryBlock) As Boolean
const header = “-----BEGIN CERTIFICATE-----”
const footer = “-----END CERTIFICATE-----”

//Make sure the header and footer exist
if instr(PEMPublicKey,header)=0 or instr(PEMPublicKey,footer) = 0 then
return False
end if

dim pos1 as integer = instr(PEMPublicKey,header)+len(header)
dim pos2 as integer = instr(PEMPublicKey,footer)
dim size as integer = pos2-pos1

if size <= 0 then
return False
end if

dim keystr as string = mid(PEMPublicKey,pos1,size)

keystr = DecodeBase64(keystr)

try
encodedkey = crypto.BERDecodePublicKey(keystr)

catch ex as CryptoException
return False
end try

return true
End Function
[/code]

@Greg O’Lone Super Thanks! :slight_smile: I will test this tomorrow; and yes I will use for both directions :wink:

@Brock Nash This is for a Desktop app to encrypt and decrypt data exchanged between Xojo via TCP Socket and Debian server script; don’t know exactly what you’re looking for but I think you cannot use this routines if you’re looking to digitally sign your application for distribution. You would need to purchase a SSL certificate from a certified issuer. If you’re writing a Web application, then I can’t help you :frowning:

Hi Walter,

I’d be really interested in your progress using RSA encryption between Xojo and PHP. I’ve tried in the past and had no luck at all. I couldn’t get Xojo to use a PHP generated key, or PHP to use a Xojo generated key. I did convert the keys, but I may have made a mistake. I was just experimenting so didn’t really try for that long. Look forward to hearing if you have any success!

@Richard Vivash please go through this thread and read carefully. It works now with Greg’s help of course.

I am creating the keys using Xojo because it’s easier for me:

[code]// THIS CODE WILL GENERATE THE PRIVATE + PUBLIC KEYS IN BOTH FORMAT
// CREATE 4 TEXTAREA BOXES AND PASTE THIS CODE INTO A BUTTON

Dim XOJOprivateKey As String
Dim XOJOpublicKey As String

If Crypto.RSAGenerateKeyPair( 1024, XOJOprivateKey, XOJOpublicKey ) Then

// contains XOJO Private Key
TextArea1.Text = XOJOprivateKey

// contains XOJO Public Key
TextArea2.Text = XOJOpublicKey

// convert XOJO Private Key to PEM Private Key - Thanks to GREG O'LONE (Official Xojo Forum)
Dim keyStr As String = EncodeBase64(crypto.DEREncodePrivateKey(XOJOprivateKey))
TextArea3.Text = "-----BEGIN PRIVATE KEY-----" + EndOfLine + keyStr + EndOfLine + "-----END PRIVATE KEY-----"
// Note: TextArea3 contains the key you will use in PHP

// convert XOJO Public Key to PEM Public Key - Thanks to GREG O'LONE (Official Xojo Forum)
keyStr = EncodeBase64(crypto.DEREncodePublicKey(XOJOpublicKey))
TextArea4.Text = "-----BEGIN PUBLIC KEY-----" + EndOfLine + keyStr + EndOfLine + "-----END PUBLIC KEY-----"
// Note: TextArea4 contains the key you will use in PHP

End If[/code]

Now you add another button to encrypt a message that you want to send to Debian/PHP or whatever:

[code]// Encode a message as per Xojo manual

Dim kMessage As String = “Hello World!”

Dim msg As New MemoryBlock(kMessage.Len)
msg.StringValue(0, kMessage.Len) = kMessage

// Encrypt msg using XOJOpublicKey
Dim encryptedData As MemoryBlock = Crypto.RSAEncrypt( msg, TextArea2.Text )

// Optionaly …
Dim MIMEencoded As String = EncodeBase64(encryptedData)[/code]

What you want here, at least for test purposes, is the MIMEencoded variable content. Now we need to decrypt this in PHP right? So I think it is better to use an existing library like this otherwise you would need to recreate the wheel.

I have a Debian server with PHP; I assume you have downloaded the library and you are well versed with libraries in PHP; So now create a PHP script with this:

[code]include(‘Crypt/RSA.php’);
$rsa = new Crypt_RSA();
$rsa->loadKey($myPrivateKey); // privatekey is TextArea3.Text in your Xojo project

echo $rsa->decrypt(base64_decode($MIMEencoded)); // $MIMEencoded is your Xojo MIMEencoded string
[/code]

Et voilá! … you can figure out the other way round, lol

If you use this in a full duplex communication I think it is better to have two keys of each for both sides (not sure). Also, you may want to do something security related that prevents someone to replicate encryted data. I am storing an expiration time/date within an encrypted message so expired messages will be disregarded.

Debian speed test 1024 bit took me 0.05 secs
For 512 bit took 0.02

Hi Walter. As I said, I did do conversion on the keys and even wrote a thread on this forum about my issues, but as I was only experimenting and not putting it into a production app I never really spent too much time on it. I was thinking of using RSA for an app and may now resurrect that idea knowing that I won’t be wasting my time trying to get it to work :wink: Thanks!