3

This question can be a possible duplicate of the question here, but I need a little bit more info on the subject. My partner(android) and me(ios) are trying to exchange some data, which is an identity key. This key is generated through the curve25519 wrapper of the Signal Protocol. The key consists of a public as well as a private key. The key is of the type defined here as ECKeyPair. Now I want to transfer the publicKey as NSData with each other, read iOS to Android and vice versa. The approaches taken and resulting issues are listed below.

  1. From iOS, tried to make the data(publicKey) as a base64 encoded string and used json serialisation to transfer to Android, But android is not able to decode the base64 string correctly. I feel its because while converting the key to base64 the data size is changed somehow, for eg when I print the data the size is always more than the 32 bytes its supposed to be. The algorithm which check for the data validation rejects the public key from within the Android implementation saying not a valid data for the key.

  2. Tried to transfer the public key from Android to iOS by casting as a ByteArray. The byte array created from the Android consists of Signed Integers and I am not able to invoke Data(bytes: <Array<UInt8>>) because its applicable to Unsigned Integers. When I try to convert this to signed Integers then it results in a similar validity check failure like in point one mentioned above.

An almost similar scenario is described in this issue here. So I would like to know the following.

  1. Why is it that some data, which is base64 encoded in a particular plateform, like iOS, differes when decoded in another platform, say Android.
  2. Why cant iOS succesfully read in a ByteArray created by an Android OS. Or am I mistaken? If so please guide me.
  3. How can I transfer data between iOS and Android successfully like in this particular case? I am familiar with normal data transfers like images or files, but its just not working in my case of cryptographic data. I know about ProtoBuff and for the sake of feasibility I would prefer json or likewise.

Adding some details that might be helpfull.

  1. The publickey generated at iOS

The publickey generated at iOS

  1. The public key generated at Android.

    [12,-55,99,72,15,-101,99,-13,99,-56,-47,19,-21,90,-17,-39,-119,-33,44,-87,-18,-24,-53,-29,-100,34,-60,69,-61,24,8,92].

    Do note the difference in signs between iOS and Android.

    Any help is appreciated. Thank You

EDIT: Adding the exception screen shot at android. ScrrenShot

As you can see the data is discarded as BadKey Type. I transferred the data from iOS to Android by Base64Encoding to string.

Mostafa Arian Nejad
  • 1,278
  • 1
  • 19
  • 32
Athul George
  • 154
  • 11
  • You have way to much questions for one post. Why didnt you start with one problem? For instance transferring a byte array from Android to iOs? Something which does have nothing to do with encryption or keys. – greenapps Mar 05 '18 at 08:54
  • I tried to explain my case so it could be more clear. My requirement is that if its transferring byte array from iOS to android, it must also pass validation by encryption algorithms. Hope i am clear. – Athul George Mar 05 '18 at 09:04
  • 1
    Yes you are clear. And you were already clear. Did you read my comment? – greenapps Mar 05 '18 at 09:12
  • Actually, you are not clear at all, since you provide no information about what the problem is. Saying "...But android is not able to decode the base64 string correctly..." is not useful information. If there is an error message, include that message together with the relevant code. If there is an exception include the complete stacktrace along with the relevant code. I don't know iOS but the Java classes on Android are designed to interoperate with other platforms using standard formats. – President James K. Polk Mar 05 '18 at 20:09
  • I have edited my post, Added the exception at Android when i try to invoke the constructor for the class. It fails the validation check of data. – Athul George Mar 06 '18 at 06:27
  • The main problem here is that you try to solve too many problems at the same time. You say that you think something might be wrong with your base64 encoding/decoding, but yet you try to do encryption with the data. Fix one problem at a time. Do you have problem with base64 then fix the problem. It's easy to verify if your base64 works or not, without complicating it with encryption etc. – Ebbe M. Pedersen Mar 06 '18 at 15:52
  • Could you show us how you create a key from Base64 encoded text? – apex39 Mar 09 '18 at 08:24
  • @AthulGeorge did you resolved this issue. Am also faced same issue now. If possible please update here how you resolved . Thank you in advance. – Sathish Gadde Oct 13 '20 at 08:26
  • @SathishGadde Added an answer to it. Check and see if it works for you. – Athul George Dec 29 '20 at 11:28

1 Answers1

0

Its long time but for that particular scenario I used Hex String. Please be known hex string conversion for large data like videos is impractical as it freezes the device.

Also, sometime later for another project, I have implemented a simple encryption between Android and iOS. And these are what I used. Maybe this will help. These use base64 encoding.

Android Encryption and Decryption

val cryptor = AES256JNCryptor();
val password = "6dpC295ei9"
val text = yourString.toByteArray(charset("UTF-8"))
val encrypt =  cryptor.encryptData(text, password.toCharArray())  // your encryption
val encode = Base64.encodeToString(encrypt, Base64.NO_WRAP)  // encryptedtext


val decode = Base64.decode(encode, Base64.NO_WRAP)
val text = String(cryptor.decryptData(decode, password.toCharArray())) // your decryption

iOS Encryption and Decryption

let password = "6dpC295ei9"
extension String {
    var encrypted : String? {
        guard let plainData = data(using: .utf8) else {
            return nil
        }
        return RNCryptor.encrypt(data: plainData, withPassword: password).base64EncodedString(options: .init(rawValue: 0))
    }
    
    var decrypted : String? {
        guard let cipherData = Data.init(base64Encoded: self, options: .init(rawValue: 0)), let plainData = try? RNCryptor.decrypt(data: cipherData, withPassword: password), let plainText = String(bytes: plainData, encoding: .utf8) else {
            return "~ DECRYPTION FAILED ~"
        }
        return plainText
    }
}
Athul George
  • 154
  • 11