Quantcast
Channel: Active questions tagged react-native+typescript - Stack Overflow
Viewing all articles
Browse latest Browse all 6213

Differing string values when passed between JavaScript (React Native) and Swift (via a Native module Objective-C definition)

$
0
0

I'm trying to send string data (specifically PEM formatted keys) out from a Native Module (written in Swift) through a Typescript exported function and into the main JS functions of a React Native app.

If I do an end-to-end test in Swift (converting the key data to strings, then to data and back again to simulate the transfer of the strings to and from JavaScript then all the logic works. I'm able to turn the data back into a key and use it to sign/encrypt. I've tried adjusting the encoding, using UTF8 and UTF16 strings but nothing seems to make it fail like it does when coming back into the native module.

The Typescript module definition

declare module 'encrypto' {  interface KeyPair {      publicKey: string;      privateKey: string;  }  export function generateKeys(keySize: number): Promise<KeyPair>;  export function getPublicKeyAsPEM(publicKey: string): Promise<string>;  export function encrypt(message: string, publicKeyAsPEM: string): Promise<string>;}export { Encrypto };export default Encrypto;

The Encrypto.m file

#import <React/RCTBridgeModule.h>@interface RCT_EXTERN_MODULE(Encrypto, NSObject)+ (BOOL)requiresMainQueueSetup {    return false;}RCT_EXTERN_METHOD(generateKeys:(int) keySize                  withResolver:(RCTPromiseResolveBlock) resolve                  withRejecter:(RCTPromiseRejectBlock) reject)RCT_EXTERN_METHOD(getPublicKeyPEM:(NSString) key                  withResolver:(RCTPromiseResolveBlock) resolve                  withRejecter:(RCTPromiseRejectBlock) reject)RCT_EXTERN_METHOD(encrypt:(NSString) message                  withPublicKeyAsPEM:(NSString) publicKeyAsPEM                  withResolver:(RCTPromiseResolveBlock) resolve                  withRejecter:(RCTPromiseRejectBlock) reject)@end

The Encryto.swift file

@objc(Encrypto)class Encrypto: NSObject {    @objc(generateKeys:withResolver:withRejecter:)    func generateKeys(keySize: Int,                      resolve: @escaping (RCTPromiseResolveBlock),                      reject:@escaping (RCTPromiseRejectBlock)) {        do {            let (publicKey, privateKey) = try .generateRSAKeys(keySize)            resolve([ "privateKey" : privateKey.base64EncodedString(),"publicKey" : publicKey.base64EncodedString() ])        } catch {            let error = error            reject("", "Key generation failed", error)        }    }    @objc(getPublicKeyPEM:withResolver:withRejecter:)    func getPublicKeyPEM(_ base64PublicKey: String,                         resolve: @escaping (RCTPromiseResolveBlock),                         reject: @escaping (RCTPromiseRejectBlock)) {        do {            guard let publicKeyData = Data(base64Encoded: base64PublicKey) else {                reject("", "Could not decode public key (is it Base64 encoded?)." ,NSError())                return            }            let pemFormattedPublicKey = try pemForPublicKey(publicKeyData)            resolve(pemFormattedPublicKey)        } catch {            let error = error            reject("", "Public Key PEM production failed", error)        }    }    @objc(encrypt:withPublicKeyAsPEM:withResolver:withRejecter:)    func encrypt(_ message:String,                 publicKeyAsPEM: String,                 resolve: @escaping (RCTPromiseResolveBlock),                 reject: @escaping (RCTPromiseRejectBlock)) {        do {            let publicKeyData = try publicKeyFromPEM(publicKeyAsPEM)            let encrypted = try encrypt(key, publicKeyData: publicKeyData)            resolve(encrypted)        } catch {            let error = error            reject("", "Encryption failed", error)        }    }}

If I log the PEM string in the Javascript, before it calls encrypt, I get this:

-----BEGIN RSA PRIVATE KEY-----MIIBCgKCAQEAqGloHcWKLYUGZZ4C2VsFNtFlMu1LgjbV7tHxwVGhNapz7YJASFqRhjAAOI68w4nKv/cq+rHsy7V4B7rCcttNAu0/fttvRrGpB4Yhh6EZQbSdoUasPSwg7d81kiipcs20CNr+b0SL4Ajb7ld5Sb9JRWnjfYHmh9DuKkcl+hzXKtejQuwvz/ZOzrdT+FJn1/tIKynv12li8JqoZwLaq3Glzu/ZwXYptg9E27v1Fj6+YbaFekrsM98dnt/RB6EkVqxhthIxjhYgCu9u56LZmUpa/ozSh+swpAR/xsewvcMX+geFMSklVgF04P2tEmJgz1bZjJ4OCa3zrezfLbmaKob65wIDAQAB-----END RSA PRIVATE KEY-----

and when I log the same string coming into the Swift function implementation I see this:

-----BEGIN RSA PRIVATE KEY-----MIIBCgKCAQEAqGloHcWKLYUGZZ4C2VsFNtFlMu1LgjbV7tHxwVGhNapz7YJASFqRhjAAOI68w4nKv/cq+rHsy7V4B7rCcttNAu0/fttvRrGpB4Yhh6EZQbSdoUasPSwg7d81kiipcs20CNr+b0SL4Ajb7ld5Sb9JRWnjfYHmh9DuKkcl+hzXKtejQuwvz/ZOzrdT+FJn1/tIKynv12li8JqoZwLaq3Glzu/ZwXYptg9E27v1Fj6+YbaFekrsM98dnt/RB6EkVqxhthIxjhYgCu9u56LZmUpa/ozSh+swpAR/xsewvcMX+geFMSklVgF04P2tEmJgz1bZjJ4OCa3zrezfLbmaKob65wIDAQAB-----END RSA PRIVATE KEY-----

and to make the calls into the Native module I'm simply doing...

  const keypair:KeyPair = await Encrypto.generateKeys(2048);  const publicKeyPem = await Encrypto.getPublicKeyPEM(keypair.publicKey);  const encryptedMessage = await Encrypto.encrypt("a message", publicKeyPem);

The getPublicKeyPEM function is able to successfully convert the key string passed in from Javascript and send back the resulting PEM string. But when that PEM string comes back for the subsequent encrypt call is is unable to successfully extract the key from it in order to perform the encrypt and despite both PEM files looking identical.

Does anyone have any ideas whats going on or what I could try please?


Viewing all articles
Browse latest Browse all 6213

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>