diff --git a/node_modules/react-native-webview/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java b/node_modules/react-native-webview/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java
index ab869cf..08ce7ce 100644
--- a/node_modules/react-native-webview/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java
+++ b/node_modules/react-native-webview/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java
@@ -84,6 +84,12 @@ import java.util.Map;
 
 import javax.annotation.Nullable;
 
+import java.security.cert.X509Certificate;
+import java.security.PrivateKey;
+import android.webkit.ClientCertRequest;
+import android.os.AsyncTask;
+import android.security.KeyChain;
+
 /**
  * Manages instances of {@link WebView}
  * <p>
@@ -140,6 +146,8 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
   protected @Nullable String mUserAgent = null;
   protected @Nullable String mUserAgentWithApplicationName = null;
 
+  private static String certificateAlias = null;
+
   public RNCWebViewManager() {
     mWebViewConfig = new WebViewConfig() {
       public void configWebView(WebView webView) {
@@ -151,6 +159,10 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
     mWebViewConfig = webViewConfig;
   }
 
+  public static void setCertificateAlias(String alias) {
+    certificateAlias = alias;
+  }
+
   protected static void dispatchEvent(WebView webView, Event event) {
     ReactContext reactContext = (ReactContext) webView.getContext();
     EventDispatcher eventDispatcher =
@@ -562,7 +574,7 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
   @Override
   protected void addEventEmitters(ThemedReactContext reactContext, WebView view) {
     // Do not register default touch emitter and let WebView implementation handle touches
-    view.setWebViewClient(new RNCWebViewClient());
+    view.setWebViewClient(new RNCWebViewClient(reactContext));
   }
 
   @Override
@@ -742,12 +754,56 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
 
   protected static class RNCWebViewClient extends WebViewClient {
 
+    protected ReactContext reactContext;
     protected boolean mLastLoadFailed = false;
     protected @Nullable
     ReadableArray mUrlPrefixesForDefaultIntent;
     protected RNCWebView.ProgressChangedFilter progressChangedFilter = null;
     protected @Nullable String ignoreErrFailedForThisURL = null;
 
+    public RNCWebViewClient(ReactContext reactContext) {
+      this.reactContext = reactContext;
+    }
+
+    @Override
+    public void onReceivedClientCertRequest(WebView view, ClientCertRequest request) {
+      class SslStuff {
+        PrivateKey privKey;
+        X509Certificate[] certChain;
+
+        public SslStuff(PrivateKey privKey, X509Certificate[] certChain) {
+          this.privKey = privKey;
+          this.certChain = certChain;
+        }
+      }
+
+      if (certificateAlias != null) {
+        AsyncTask<Void, Void, SslStuff> task = new AsyncTask<Void, Void, SslStuff>() {
+          @Override
+          protected SslStuff doInBackground(Void... params) {
+            try {
+              PrivateKey privKey = KeyChain.getPrivateKey(reactContext, certificateAlias);
+              X509Certificate[] certChain = KeyChain.getCertificateChain(reactContext, certificateAlias);
+
+              return new SslStuff(privKey, certChain);
+            } catch (Exception e) {
+              return null;
+            }
+          }
+
+          @Override
+          protected void onPostExecute(SslStuff sslStuff) {
+            if (sslStuff != null) {
+              request.proceed(sslStuff.privKey, sslStuff.certChain);
+            }
+          }
+        };
+        task.execute();
+      } else {
+        super.onReceivedClientCertRequest(view, request);
+      }
+    }
+
     public void setIgnoreErrFailedForThisURL(@Nullable String url) {
       ignoreErrFailedForThisURL = url;
     }
diff --git a/node_modules/react-native-webview/apple/RNCWebView.m b/node_modules/react-native-webview/apple/RNCWebView.m
index 02b4238..04bad05 100644
--- a/node_modules/react-native-webview/apple/RNCWebView.m
+++ b/node_modules/react-native-webview/apple/RNCWebView.m
@@ -17,6 +17,9 @@
 
 #import "objc/runtime.h"
 
+#import "SecureStorage.h"
+#import <MMKV/MMKV.h>
+
 static NSTimer *keyboardTimer;
 static NSString *const HistoryShimName = @"ReactNativeHistoryShim";
 static NSString *const MessageHandlerName = @"ReactNativeWebView";
@@ -737,6 +740,68 @@ + (void)setCustomCertificatesForHost:(nullable NSDictionary*)certificates {
     customCertificatesForHost = certificates;
 }
 
+-(NSURLCredential *)getUrlCredential:(NSURLAuthenticationChallenge *)challenge path:(NSString *)path password:(NSString *)password
+{
+  NSString *authMethod = [[challenge protectionSpace] authenticationMethod];
+  SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
+
+  if ([authMethod isEqualToString:NSURLAuthenticationMethodServerTrust] || path == nil || password == nil) {
+    return [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
+  } else if (path && password) {
+    NSMutableArray *policies = [NSMutableArray array];
+    [policies addObject:(__bridge_transfer id)SecPolicyCreateSSL(true, (__bridge CFStringRef)challenge.protectionSpace.host)];
+    SecTrustSetPolicies(serverTrust, (__bridge CFArrayRef)policies);
+
+    SecTrustResultType result;
+    SecTrustEvaluate(serverTrust, &result);
+
+    if (![[NSFileManager defaultManager] fileExistsAtPath:path])
+    {
+      return [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
+    }
+
+    NSData *p12data = [NSData dataWithContentsOfFile:path];
+    NSDictionary* options = @{ (id)kSecImportExportPassphrase:password };
+    CFArrayRef rawItems = NULL;
+    OSStatus status = SecPKCS12Import((__bridge CFDataRef)p12data,
+                                      (__bridge CFDictionaryRef)options,
+                                      &rawItems);
+
+    if (status != noErr) {
+      return [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
+    }
+
+    NSArray* items = (NSArray*)CFBridgingRelease(rawItems);
+    NSDictionary* firstItem = nil;
+    if ((status == errSecSuccess) && ([items count]>0)) {
+        firstItem = items[0];
+    }
+
+    SecIdentityRef identity = (SecIdentityRef)CFBridgingRetain(firstItem[(id)kSecImportItemIdentity]);
+    SecCertificateRef certificate = NULL;
+    if (identity) {
+        SecIdentityCopyCertificate(identity, &certificate);
+        if (certificate) { CFRelease(certificate); }
+    }
+
+    NSMutableArray *certificates = [[NSMutableArray alloc] init];
+    [certificates addObject:CFBridgingRelease(certificate)];
+
+    return [NSURLCredential credentialWithIdentity:identity certificates:certificates persistence:NSURLCredentialPersistenceNone];
+  }
+
+  return [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
+}
+
+- (NSString *)stringToHex:(NSString *)string
+{
+  char *utf8 = (char *)[string UTF8String];
+  NSMutableString *hex = [NSMutableString string];
+  while (*utf8) [hex appendFormat:@"%02X", *utf8++ & 0x00FF];
+
+  return [[NSString stringWithFormat:@"%@", hex] lowercaseString];
+}
+
 - (void)                    webView:(WKWebView *)webView
   didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
                   completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable))completionHandler
@@ -746,7 +811,34 @@ - (void)                    webView:(WKWebView *)webView
         host = webView.URL.host;
     }
     if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodClientCertificate) {
-        completionHandler(NSURLSessionAuthChallengeUseCredential, clientAuthenticationCredential);
+        NSString *host = challenge.protectionSpace.host;
+  
+        // Read the clientSSL info from MMKV
+        __block NSDictionary *clientSSL;
+        SecureStorage *secureStorage = [[SecureStorage alloc] init];
+
+        // https://github.com/ammarahm-ed/react-native-mmkv-storage/blob/master/src/loader.js#L31
+        [secureStorage getSecureKey:[self stringToHex:@"com.MMKV.default"] callback:^(NSArray *response) {
+          // Error happened
+          if ([response objectAtIndex:0] != [NSNull null]) {
+              return;
+          }
+          NSString *key = [response objectAtIndex:1];
+          NSData *cryptKey = [key dataUsingEncoding:NSUTF8StringEncoding];
+          MMKV *mmkv = [MMKV mmkvWithID:@"default" cryptKey:cryptKey mode:MMKVMultiProcess];
+
+          clientSSL = [mmkv getObjectOfClass:[NSDictionary class] forKey:host];
+        }];
+
+        NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
+
+        if (clientSSL != (id)[NSNull null]) {
+          NSString *path = [clientSSL objectForKey:@"path"];
+          NSString *password = [clientSSL objectForKey:@"password"];
+          credential = [self getUrlCredential:challenge path:path password:password];
+        }
+
+        completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
         return;
     }
     if ([[challenge protectionSpace] serverTrust] != nil && customCertificatesForHost != nil && host != nil) {