B4A Library Base64 and Encryption library

Here's a library that, for the moment, can perform Base64 encoding and decoding and symmetric algorithm encryption and decryption. Tested symmetric algorithms are DES, Triple DES and AES (Rijndael).

As the Java encryption rountines are all byte array oriented you will need my ByteConverter library to run the demo.

EDIT :- Version 1.1 posted. Asymmetric algorithms, Signing and MACs now implemented. See post#2 for details.
 

Attachments

  • Encryption1.1.zip
    25.4 KB · Views: 9,180
  • Encryption_java_source.zip
    27.2 KB · Views: 2,272
Last edited by a moderator:

me68

Member
Licensed User
Longtime User
Hello!

I generate a license file with openssl on a pc like following:

B4X:
openssl smime -sign -in license-in.txt -signer [email protected] -inkey [email protected]_key.pem -passin pass:******** -out license.txt

This file should be verified from our android app via Mac/KeyPairGenerator functions from your library.

So i do not need to generate a keypair first and use the public key for verifying hash, i own already a public key.

But if i load the public key via PublicKeyFromBytes, i run in an error

B4X:
java.security.spec.InvalidKeySpecException: java.lang.RuntimeException: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag

I load the public key first via File.ReadString and convert it via StringToBytes to needed byte array.

B4X:
   Log("CheckLicenseFile")
   Dim sLicenseContent As String
   Dim sPublicKeyContent As String
   Dim mMac As Mac
   Dim kpg As KeyPairGenerator
   Dim sigdata(0) As Byte
   Dim abPublicKeyGeneratedContent(0) As Byte
   Dim sPublicKeyGeneratedContent As String
   Dim abPublicKeyContent(0) As Byte
   Dim abLicenseContent(0) As Byte
   Dim bOk As Boolean

    sLicenseContent = File.ReadString(DBFilePath, "license.txt")
    sPublicKeyContent = File.ReadString(DBFilePath, "[email protected]")

    'Log(sLicenseContent)
    'Log(sPublicKeyContent)

    abLicenseContent = bc.StringToBytes(sLicenseContent, "UTF8")
    abPublicKeyContent = bc.StringToBytes(sPublicKeyContent, "UTF8")

    kpg.Initialize("RSA", 2048)
    kpg.GenerateKey
    Log("------------------------------------")
    Log("kpg.PublicKey=" & kpg.PublicKey)
    Log("------------------------------------")
    abPublicKeyGeneratedContent = kpg.PublicKeyToBytes
    sPublicKeyGeneratedContent = bc.StringFromBytes(abPublicKeyGeneratedContent, "UTF8")
    Log("sPublicKeyGeneratedContent=" & sPublicKeyGeneratedContent)
    kpg.PublicKeyFromBytes(abPublicKeyContent)
    Log("------------------------------------")
    Log("kpg.PublicKey=" & kpg.PublicKey)
    mMac.Initialise("HMACSHA256", kpg.PublicKey)
    mMac.Update(abLicenseContent)
    sigdata = mMac.Sign
    bOk = mMac.Verify(sigdata)

    Log(bOk & CRLF & bc.HexFromBytes(sigdata) & "Mac is " & sigdata.Length & " bytes")

Something wrong with data formats. I have already generated first a keypair via GenerateKey to see the data format, but i can't solve the data format error. My public key:

B4X:
-----BEGIN CERTIFICATE-----
MIIDNDCCAhwCCQDG/jEpoU9PETANBgkqhkiG9w0BAQsFADBcMQswCQYDVQQGEwJB
VDETMBEGA1UECAwKQnVyZ2VubGFuZDEWMBQGA1UEBwwNRGV1dHNjaGtyZXV0ejEg
MB4GCSqGSIb3DQEJARYRZS1tb2JpbGl0eUBnbXguYXQwHhcNMTUxMDE4MDg0OTI4
WhcNMjUxMDE1MDg0OTI4WjBcMQswCQYDVQQGEwJBVDETMBEGA1UECAwKQnVyZ2Vu
bGFuZDEWMBQGA1UEBwwNRGV1dHNjaGtyZXV0ejEgMB4GCSqGSIb3DQEJARYRZS1t
b2JpbGl0eUBnbXguYXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDY
DYfkiAbJNwE8WIzN/XaQa/YOHpmHJZhf3OriMFQB9OVbUe2ltGcZ7vsKNKts0LU3
Rc7EsODZgguQ/IGniASxPXNgjGAC6+fthyPiOUvFZ48or7G3HxY0BiSCli2RERIB
vLGYpE+VnuEgZGff7nes+e/1pDF8ez7/oFutkg/KjSf0XKOlmDNuv+HoEov8kFa8
bFH3dsLw0fBK8C66TcaQmmBFQXTWOnyCe+RyHfBsWqapH21TwkWNou88HtE8t42o
iR9aMlMC8JQQxnH3fvmCubTWQuX+MKUf9X43fEfKijVec+yQmVqoTBF8XARk3SbN
Gi79k4sKuDfqKWZhSM1zAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAIbVqBffS2NE
xBNp4A05YGL0LAjW8S7Tez1Jr1hUABGaKABv2dvW+OIFKVH/17CKsjR+bNNO9303
jntH0LAQ/OghrM/aoo7vtyVsQMGfdmkEoWsKhiqlEQ8B3bVgwRTn0UC0SckJxAdm
iARTm5m+eYNjwNIaIWNOskUnCVL1THxfmEHXv0CSBWb0oaf8GwzAibYj0m7XgBmx
yq4OZHW9eKzDtlBb+1M+SCJ8Q2/6iQgMsXbeb1sPRPdG7wpxJPvt2D3KmCdK8wGQ
0dHAQ14ulzOd3hxeN66lmM/Fy+bFY09kHdmUawETErfXZH/IDoFYjUbqcq8f6HFW
kpGbvgSLma4=
-----END CERTIFICATE-----

Martin
 

me68

Member
Licensed User
Longtime User
Hello!

I solved my issue in the meantime:

First i changed the openssl commands from gen a smime file to gen a digital signature file, because there is no asn1-Interpreter available to B4A.

So now i do following:

gen.bat:
B4X:
@echo off
set editor="C:\Program Files (x86)\Notepad++\notepad++.exe" -nosession
%editor% license.txt
openssl dgst -sha256 -sign [email protected]_private_key.pem -out license.bin license.txt
openssl enc -e -base64 -in license.bin>license.sig

license.txt:
B4X:
User=username
Features=Car State File Intervall,Remote View
ExpirationDate=2015-12-31

I push license.txt & license.sig to android device afterwords and use it in our app:

B4X:
Sub VerifyLicenseFile As Boolean
Try
    Dim bVerified As Boolean
    Dim isLicense As InputStream
    Dim isLicenseSignature As InputStream
    Dim isPublicKeyContent As InputStream
    Dim sig As Signature
    Dim kpg As KeyPairGenerator
    Dim base64 As Base64

    bVerified = False

    isLicense = File.OpenInput(DBFilePath, "license.txt")
    isLicenseSignature = File.OpenInput(DBFilePath, "license.sig")
    isPublicKeyContent = File.OpenInput(File.DirAssets, "[email protected]")

    Dim abLicense(isLicense.BytesAvailable) As Byte
    Dim abLicenseSignature(isLicenseSignature.BytesAvailable) As Byte
    Dim abPublicKeyContent(isPublicKeyContent.BytesAvailable) As Byte

    isLicense.ReadBytes(abLicense, 0, isLicense.BytesAvailable)
    isLicenseSignature.ReadBytes(abLicenseSignature, 0, isLicenseSignature.BytesAvailable)
    isPublicKeyContent.ReadBytes(abPublicKeyContent, 0, isPublicKeyContent.BytesAvailable)

    isLicense.Close
    isLicenseSignature.Close
    isPublicKeyContent.Close

    kpg.Initialize("RSA", 2048)
    kpg.PublicKeyFromBytes(base64.DecodeBtoB(abPublicKeyContent, 0, abPublicKeyContent.Length))

    sig.Initialise("SHA256WithRSAEncryption", sig.SIGNATURE_VERIFY, kpg.PublicKey)
    sig.Update(abLicense)

    bVerified = sig.Verify(base64.DecodeBtoB(abLicenseSignature, 0, abLicenseSignature.Length))
    Log("caniOn license file is " & bVerified)

    Return bVerified
Catch
    MainLog(LastException.Message)
End Try
    Log("caniOn license file is " & bVerified)
    Return False
End Sub

Note: [email protected]64.txt contains only the public key in base64 itself - no "-----BEGIN PUBLIC KEY-----"!

That's it!


Martin :)
 

falbertini

Member
Licensed User
Longtime User
Hello,
I have been using this library for years, and everything worked fine.
But with the newest version of Android ( 6 ) is not working. I have find this error because some of my customers had an Android 6 device and the app was not working..
I dont't have a Android 6 device, so I tried it on the emulator (Genymotion).
Attached you can find a simple program to reproduce the problem: on Android 6 I get a different value after encryption.
You can find two screenshot, showing the bytes value from an Android 4 device and from a Android 6 device.
Thanks
 

Attachments

  • TestEncryption.zip
    478.6 KB · Views: 502
Last edited:

androidvh

Member
Licensed User
Longtime User
Hello Andrew,

can you please give a short answer to post #85 and #86?

I have test the libary with Basic4Andorid version 5.5 and SDK 23.
It is the same problem.

Kind regards
Volker
 

Kwame Twum

Active Member
Licensed User
Longtime User
Any chance to get a php function for decrypting strings encrypted by this code and vice versa?​
 

dcoun

Member
Licensed User
Longtime User
Thank you for the prompt answer
Can I use the same jar for B4i and B4J, or do I need modifications and re-compile?
 

b4x-de

Active Member
Licensed User
Longtime User
I know the library implements the Java Cryptography Architecture (JCA). I’m interested in creating and verifying signatures, so I read here:
https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html#Signature

When initializing a MAC object to create and verify a RSA-signature I need the algorithm as the first parameter. The above link from JCA guides me to the following page for signature algorithm names, like “SHA1withRSA” and “SHA512withRSA”.
https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#Signature

But when I try to use these Java Standard Names form the documentation page I receive the following runtime exception:
java.security.NoSuchAlgorithmException: Algorithm SHA512withRSA not available

In post#84 @me68 (Martin) figured out, to take “SHA256WithRSAEncryption” as algorithm name. Unfortunately the algorithm names are not documented in the Encryption library itself. But where can I find a complete list?

Thanks,
Thomas
 
Top