2
votes

I am trying to generate the matching public key on iOS to store the shared public key from Android for asymmetric key cryptography operations. what is the best way to share the public key from Android so that same can be re-created on iOS?

I am using Apple's SecKeyWrapper class for creating the publicKey using addPublicKey:keyBits: method. Though the secItemAdd seem to be succeeding, it is consistently failing to return the generated PublicKeyRef from SecItemMatching(), as it is always nil though the status is success. Facing exactly same behaviour as discussed in below link: (however, suggested solution isn't working either): iOS keychain issue. SecKeyRef always is null as result of SecItemCopyMatching()

I have tried the following approaches:

Approach # 1. Android : Extracted Modulus & Exponent from RSAPublicKey, encoded each into Base64Encoding separately and shared with iOS. iOS : Created corresponding NSData components from the shared Modulus & exponent and created Key data object using SCZ-BasicEncodingRules classes's berData operation to create the raw key object and shared this output with SecKeyWrapper for key generation.

Approach # 2. Android : Extracted Modulus & Exponent from RSAPublicKey, encoded each into UTF8Encoding separately and shared with iOS. iOS : Created corresponding NSData components from the shared Modulus & exponent and created Key data object using SCZ-BasicEncodingRules classes's berData operation to create the raw key object and shared this output with SecKeyWrapper for key generation. Reference : https://github.com/StCredZero/SCZ-BasicEncodingRules-iOS

Alternatively, also tried CryptoUtil classes to generate the KeyObject from Modulus & exponent, which is yielding the exact same behaviour.

Approach # 3. Android : On RSAPublcKey called .toString() and encoded the output string to base64Encoding and shared with iOS. iOS: Created NSData from base64Encoded key and shared this output with SecKeyWrapper for key generation., which is agin resulting the same!

Approach # 4. Android : On RSAPublcKey called .toString() and encoded the output string to base64Encoding and shared with iOS. iOS : Tried to create KeyData object using method described by wingsofhermes, which is anyway instantly returning false with wrong format.

That being said, I am not able to distinguish if the input key data is going wrong or key generation @ iOS is going wrong. Any help is greatly appreciated!

1

1 Answers

1
votes

Upon further study, I found that iOS's secKeyWrapper can only accept key's data in ASN.1 DER format. Any attempts to pass data in any other format would definitely fail on iOS.

Solved the problem by dumping the RSA keys in PEM format and used the approach from following link to read PEM and convert to ASN.1 DER format and passed the same to SecKeyWrapper! http://blog.flirble.org/2011/01/05/rsa-public-key-openssl-ios/

Alternate approach: Problem could have also be solved by using OpenSSL libraries for iOS (refer Generate Public Key From Modulus & Exponent on iOS using OpenSSL) and create RSA objects with input modulus & exponent (base64encoded) data for the public key shared from any other platform.