B4A Library RSA: Convert OpenSSL Public Key to/from B4x

What is it good for:

If you want to use RSA encryption with (Apache) servers (PHP) you will have OpenSSL which does the en-/decryption on the server side. On B4x there is a nice lib from Agraham which I use: https://www.b4x.com/android/forum/threads/base64-and-encryption-library.6839/

What it does:

OpensSSL uses a ASN1 formated string which contains the RSA modulus and exponent. Here is a 4096 Bit RSA file:

B4X:
-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAySG7cNjinbmWGSJULRE3
YwZtXexemk7zDryRvl6LtIjVIacmVZh6aXh+D5Lt1z6ndBVUvJZwdlhaar9e0LOY
+yw9FO58wRwmMQBCdPoDKJnU4iq8Xts5XUxbMt58qg9XvzW3o0o5pDu8Xw00mGiH
gdAnFYh2f/5ShLzqn60aIcTGkGVA/NbLTQdlrZsnCIjIbv8YLyTEhJdkgVZXQ26T
PmzIa7YppjRu4BBxOdkpk4l/nW+AhJpEuQ5Z5xGF9kUvDlVMjQQ+/7CQpyuIBC1G
/RrPi7NVbr4uys0A2ERnW6adO48mFRFbb8kUnHEhgLSbzkuT7Vo42gwShbv28DS4
7zPNQRdIRe2klUQf0WV0zUa42pREM/X9gQ8lJ6C2YE54vplZdX698a0t7bAOkGzY
5rhLDs0Hk9+AiMe0SMmTBmpDxHP1P2k3BOBtUfqESumlILsvdGJEYfLot6PEuvtE
TNFZQn5LNVUm8MExrFDoqUPXFDwIeQFpBbb+QlE0+TznhRbcHH8sMoIQaPKEYdeA
E76daSiMKoYUnAREIqpDujreF99GYTIeFPPaqPl3K1NhH4ETmsvjetHV19l4tkSQ
oZWSeGaKaD9WmOMWkrLlUzKznkamUp41/mwd5xuo4d2NEpULeeX/5tOmYUATMMiv
DFrPyecYn+UfWjznTXcq9jsCAwEAAQ==
-----END PUBLIC KEY-----

which usualy comes Base64 encoded:

B4X:
LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEFNSUlDQ2dLQ0FnRUF5U0c3Y05qaW5ibVdHU0pVTFJFMwpZd1p0WGV4ZW1rN3pEcnlSdmw2THRJalZJYWNtVlpoNmFYaCtENUx0MXo2bmRCVlV2Slp3ZGxoYWFyOWUwTE9ZCit5dzlGTzU4d1J3bU1RQkNkUG9ES0puVTRpcThYdHM1WFV4Yk10NThxZzlYdnpXM28wbzVwRHU4WHcwMG1HaUgKZ2RBbkZZaDJmLzVTaEx6cW42MGFJY1RHa0dWQS9OYkxUUWRsclpzbkNJaklidjhZTHlURWhKZGtnVlpYUTI2VApQbXpJYTdZcHBqUnU0QkJ4T2RrcGs0bC9uVytBaEpwRXVRNVo1eEdGOWtVdkRsVk1qUVErLzdDUXB5dUlCQzFHCi9SclBpN05WYnI0dXlzMEEyRVJuVzZhZE80OG1GUkZiYjhrVW5IRWhnTFNiemt1VDdWbzQyZ3dTaGJ2MjhEUzQKN3pQTlFSZElSZTJrbFVRZjBXVjB6VWE0MnBSRU0vWDlnUThsSjZDMllFNTR2cGxaZFg2OThhMHQ3YkFPa0d6WQo1cmhMRHMwSGs5K0FpTWUwU01tVEJtcER4SFAxUDJrM0JPQnRVZnFFU3VtbElMc3ZkR0pFWWZMb3Q2UEV1dnRFClRORlpRbjVMTlZVbThNRXhyRkRvcVVQWEZEd0llUUZwQmJiK1FsRTArVHpuaFJiY0hIOHNNb0lRYVBLRVlkZUEKRTc2ZGFTaU1Lb1lVbkFSRUlxcER1anJlRjk5R1lUSWVGUFBhcVBsM0sxTmhINEVUbXN2amV0SFYxOWw0dGtTUQpvWldTZUdhS2FEOVdtT01Xa3JMbFV6S3pua2FtVXA0MS9td2Q1eHVvNGQyTkVwVUxlZVgvNXRPbVlVQVRNTWl2CkRGclB5ZWNZbitVZldqem5UWGNxOWpzQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQ==

Easy: It's the first one just Base64 encoded. So the lib needs this one. Conversation is done inside.

Agrahams library uses the inner Base64 string converted to bytes of the first "Begin/End Public Key". I don't want to get too deep here. It's a ASN1 string (see Google if you are interested).

My lib converts in both directions. So it's easy to do RSA between B4x and "the outside". If you use Visual Studio here's a secret: VS expects the modulus and the exponent as raw values (these are inside the ASN1 string). But this one is about B4x.


Used libs:

- RSAKeyConverter (see attachement)
- encryption
- Byteconverter
- StringUtils

How to use:

Copy it to additional lib's (as always)

It has 2 methods:

- r.OpenSSL2B4x -> Convert OpenSSL Public Key (Base64 encoded) to a ByteArray (used by encryption library)
- r.B4x2OpenSSL -> Convert encryption library ByteArray to a OpenSSL Public Key (Base64 encoded)

Code example:

B4X:
Dim OpenSSLKey As String
OpenSSLKey="LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQ0lqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FnOEFNSUlDQ2dLQ0FnRUF5U0c3Y05qaW5ibVdHU0pVTFJFMwpZd1p0WGV4ZW1rN3pEcnlSdmw2THRJalZJYWNtVlpoNmFYaCtENUx0MXo2bmRCVlV2Slp3ZGxoYWFyOWUwTE9ZCit5dzlGTzU4d1J3bU1RQkNkUG9ES0puVTRpcThYdHM1WFV4Yk10NThxZzlYdnpXM28wbzVwRHU4WHcwMG1HaUgKZ2RBbkZZaDJmLzVTaEx6cW42MGFJY1RHa0dWQS9OYkxUUWRsclpzbkNJaklidjhZTHlURWhKZGtnVlpYUTI2VApQbXpJYTdZcHBqUnU0QkJ4T2RrcGs0bC9uVytBaEpwRXVRNVo1eEdGOWtVdkRsVk1qUVErLzdDUXB5dUlCQzFHCi9SclBpN05WYnI0dXlzMEEyRVJuVzZhZE80OG1GUkZiYjhrVW5IRWhnTFNiemt1VDdWbzQyZ3dTaGJ2MjhEUzQKN3pQTlFSZElSZTJrbFVRZjBXVjB6VWE0MnBSRU0vWDlnUThsSjZDMllFNTR2cGxaZFg2OThhMHQ3YkFPa0d6WQo1cmhMRHMwSGs5K0FpTWUwU01tVEJtcER4SFAxUDJrM0JPQnRVZnFFU3VtbElMc3ZkR0pFWWZMb3Q2UEV1dnRFClRORlpRbjVMTlZVbThNRXhyRkRvcVVQWEZEd0llUUZwQmJiK1FsRTArVHpuaFJiY0hIOHNNb0lRYVBLRVlkZUEKRTc2ZGFTaU1Lb1lVbkFSRUlxcER1anJlRjk5R1lUSWVGUFBhcVBsM0sxTmhINEVUbXN2amV0SFYxOWw0dGtTUQpvWldTZUdhS2FEOVdtT01Xa3JMbFV6S3pua2FtVXA0MS9td2Q1eHVvNGQyTkVwVUxlZVgvNXRPbVlVQVRNTWl2CkRGclB5ZWNZbitVZldqem5UWGNxOWpzQ0F3RUFBUT09Ci0tLS0tRU5EIFBVQkxJQyBLRVktLS0tLQ=="

Public ServerPubKeyString As String
Public ServerPubKeyBytes(0) As Byte
       
Public OwnPubKeyString As String
Public OwnPubKeyBytes(0) As Byte
Public OwnPrivKeyBytes(0) As Byte
Public OwnPrivKeyString, OwnPrivKey, OwnPubKey64StringExport As String
   
Public ServerKPG As KeyPairGenerator
Public OwnKPG As KeyPairGenerator
Public OwnC, ServerC As Cipher

Dim r As RSAKeyConverter

ServerC.Initialize("RSA/ECB/PKCS1Padding")
ServerKPG.Initialize("RSA", 4096)
ServerPubKeyBytes=r.OpenSSL2B4x(OpenSSLKey) ' -> Convert from OpenSSL
ServerKPG.PublicKeyFromBytes(ServerPubKeyBytes)


OwnC.Initialize("RSA/ECB/PKCS1Padding")
OwnKPG.Initialize("RSA", 4096)
OwnKPG.GenerateKey
OwnPrivKeyBytes=OwnKPG.PrivateKeyToBytes
OwnPubKeyBytes=OwnKPG.PublicKeyToBytes

OwnPubKey64StringExport=r.B4x2OpenSSL(OwnPubKeyBytes) '' -> Convert to OpenSSL   

ServerPubKeyBytes=r.OpenSSL2B4x(OwnPubKey64StringExport) 'Test: Convert it back again
ServerKPG.PublicKeyFromBytes(ServerPubKeyBytes) ' load it

1. Get the Server's Public Key (Base64 encoded) from the server (php, etc.)
2. For the example I've put the Key in a string "OpenSSLKey"
3. Dim a new instance "Dim r As RSAKeyConverter" (no initialize needed)
4. Use it (see code example)
 

Attachments

  • RSAKeyConverterLib.zip
    2.8 KB · Views: 327

mmanso

Active Member
Licensed User
Longtime User
Hi there,

I'm trying to create a string crypted with RSA using an openssl key file.

I've succeeded using your library like this:

B4X:
Dim ForeignPrivKeyBytes(0) As Byte
Dim keyEncodedBytes(0) As Byte
Dim keyEncodedStr As String
Dim signKey As String = $"-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAySG7cNjinbmWGSJULRE3
YwZtXexemk7zDryRvl6LtIjVIacmVZh6aXh+D5Lt1z6ndBVUvJZwdlhaar9e0LOY
+yw9FO58wRwmMQBCdPoDKJnU4iq8Xts5XUxbMt58qg9XvzW3o0o5pDu8Xw00mGiH
gdAnFYh2f/5ShLzqn60aIcTGkGVA/NbLTQdlrZsnCIjIbv8YLyTEhJdkgVZXQ26T
PmzIa7YppjRu4BBxOdkpk4l/nW+AhJpEuQ5Z5xGF9kUvDlVMjQQ+/7CQpyuIBC1G
/RrPi7NVbr4uys0A2ERnW6adO48mFRFbb8kUnHEhgLSbzkuT7Vo42gwShbv28DS4
7zPNQRdIRe2klUQf0WV0zUa42pREM/X9gQ8lJ6C2YE54vplZdX698a0t7bAOkGzY
5rhLDs0Hk9+AiMe0SMmTBmpDxHP1P2k3BOBtUfqESumlILsvdGJEYfLot6PEuvtE
TNFZQn5LNVUm8MExrFDoqUPXFDwIeQFpBbb+QlE0+TznhRbcHH8sMoIQaPKEYdeA
E76daSiMKoYUnAREIqpDujreF99GYTIeFPPaqPl3K1NhH4ETmsvjetHV19l4tkSQ
oZWSeGaKaD9WmOMWkrLlUzKznkamUp41/mwd5xuo4d2NEpULeeX/5tOmYUATMMiv
DFrPyecYn+UfWjznTXcq9jsCAwEAAQ==
-----END PUBLIC KEY-----"$

keyEncodedBytes = Bconv.StringToBytes(signKey, "UTF8")
keyEncodedStr = su.EncodeBase64(keyEncodedBytes)
ForeignPrivKeyBytes = r.OpenSSL2B4x(keyEncodedStr)

All this works ok. My question now is, how can I use ForeignPrivKeyBytes to encrypt a string with it? I was trying this route:

B4X:
c.Initialize("RSA/ECB/PKCS1Padding")
ForeignKPG.Initialize("RSA", 1024)

But can't figure it out...

Am I going into the right direction?

Thanks a lot.
 

KMatle

Expert
Licensed User
Longtime User
how can I use ForeignPrivKeyBytes to encrypt a string with it

Sorry. Didn't see you post. This is not how RSA works. Encryption is done with the Public Key only! DEcryption is done with the Private Key. Advantage: You can publish the public key to anyone. Only you can decrypt it.
 
Top