{"id":4615,"url":"https://github.com/MaxToyberman/react-native-ssl-pinning","last_synced_at":"2025-08-04T01:32:46.070Z","repository":{"id":33441465,"uuid":"121344660","full_name":"MaxToyberman/react-native-ssl-pinning","owner":"MaxToyberman","description":"React Native ssl pinning and cookies handling based on okhttp3 on (Android). and AFNetworking on (iOS)","archived":false,"fork":false,"pushed_at":"2025-07-02T06:59:24.000Z","size":491,"stargazers_count":385,"open_issues_count":72,"forks_count":113,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-08-02T12:46:53.032Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MaxToyberman.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-02-13T05:55:49.000Z","updated_at":"2025-08-02T12:39:26.000Z","dependencies_parsed_at":"2023-12-19T10:08:25.055Z","dependency_job_id":"bd7d600c-0f6f-4bb7-af3e-b0d9e51732f8","html_url":"https://github.com/MaxToyberman/react-native-ssl-pinning","commit_stats":{"total_commits":169,"total_committers":20,"mean_commits":8.45,"dds":0.3668639053254438,"last_synced_commit":"43e858b47729067091156f83a31e84e1414bc651"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/MaxToyberman/react-native-ssl-pinning","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MaxToyberman%2Freact-native-ssl-pinning","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MaxToyberman%2Freact-native-ssl-pinning/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MaxToyberman%2Freact-native-ssl-pinning/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MaxToyberman%2Freact-native-ssl-pinning/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MaxToyberman","download_url":"https://codeload.github.com/MaxToyberman/react-native-ssl-pinning/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MaxToyberman%2Freact-native-ssl-pinning/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268636476,"owners_count":24282093,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-03T02:00:12.545Z","response_time":2577,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-01-05T20:17:17.994Z","updated_at":"2025-08-04T01:32:46.048Z","avatar_url":"https://github.com/MaxToyberman.png","language":"Java","funding_links":[],"categories":["Components","Java"],"sub_categories":["System"],"readme":"\n# react-native-ssl-pinning\n\nReact-Native ssl pinning \u0026 public key pinning using OkHttp 3 in Android, and AFNetworking on iOS. \n\n## NOTES:\n\n- for RN 0.60.0 or later use `react-native-ssl-pinning@latest`\n\n\n## Getting started\n\n`$ npm install react-native-ssl-pinning --save`\n\n\n### Mostly automatic installation\n\n\u003e If you are using `React Native 0.60.+` [the link should happen automatically](https://github.com/react-native-community/cli/blob/master/docs/autolinking.md). in iOS run pod install\n\n`$ react-native link react-native-ssl-pinning`\n\n### Manual installation\n\n\n#### iOS\n\n1. In XCode, in the project navigator, right click `Libraries` ➜ `Add Files to [your project's name]`\n2. Go to `node_modules` ➜ `react-native-ssl-pinning` and add `RNSslPinning.xcodeproj`\n3. In XCode, in the project navigator, select your project. Add `libRNSslPinning.a` to your project's `Build Phases` ➜ `Link Binary With Libraries`\n4. Run your project (`Cmd+R`)\u003c\n\n#### Android\n\nAdd maven { url \"https://jitpack.io\" } to project level build.gradle like this: \n```\nallprojects {\n    repositories {\n\tmaven { url \"https://jitpack.io\" }\n    }\n}\n```\n1. Open up `android/app/src/main/java/[...]/MainActivity.java`\n  - Add `import com.toyberman.RNSslPinningPackage;` to the imports at the top of the file\n  - Add `new RNSslPinningPackage()` to the list returned by the `getPackages()` method\n2. Append the following lines to `android/settings.gradle`:\n  \t```\n  \tinclude ':react-native-ssl-pinning'\n  \tproject(':react-native-ssl-pinning').projectDir = new File(rootProject.projectDir, \t'../node_modules/react-native-ssl-pinning/android')\n  \t```\n3. Insert the following lines inside the dependencies block in `android/app/build.gradle`:\n  \t```\n      compile project(':react-native-ssl-pinning')\n  \t```\n\n\n## Usage\n\n#### Create the certificates:\n\n1. openssl s_client -showcerts -servername google.com -connect google.com:443 \u003c/dev/null\n\n2. Copy the certificate (Usally the first one in the chain), and paste it using nano or other editor like so , nano mycert.pem\n3. convert it to .cer with this command\nopenssl x509 -in mycert.pem -outform der -out mycert.cer \n```\nFor more ways to obtain the server certificate please refer:\nhttps://stackoverflow.com/questions/7885785/using-openssl-to-get-the-certificate-from-a-server\n```\n#### iOS\n - drag mycert.cer to Xcode project, mark your target and 'Copy items if needed'\n - (skip this if you are using certificate pinning) no extra step needed for public key pinning,  AFNetworking will extract the public key from the certificate. \n\n#### Android\n -  Only if using certificate pinning : place your .cer files under src/main/assets/\n\n - For public key pinning the public key should be extracted by the following options\n: (replace google with your domain)\n\t- ```openssl s_client -servername google.com -connect google.com:443 | openssl x509 -pubkey -noout | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | openssl enc -base64```\n\t- Turn on pinning with a broken configuration and read the expected configuration when the connection fails.\n\t\t```javascript\n\t\tfetch(\"https://publicobject.com\", {\n\t\t\tmethod: \"GET\" ,\n\t\t\tpkPinning: true,\n\t\t\tsslPinning: {\n\t\t\t\tcerts: [\"sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\"] \n\t\t\t}\n\t\t})\n\t\t```\n\t\t- Now look at your logcat ,   As expected, this fails with a certificate pinning exception: \u003cpre\u003ejavax.net.ssl.SSLPeerUnverifiedException: Certificate pinning failure!\n\t\tPeer certificate chain:\n\t\tsha256/afwiKY3RxoMmLkuRW1l7QsPZTJPwDS2pdDROQjXw8ig=: CN=publicobject.com, OU=PositiveSSL\n\t\tsha256/klO23nT2ehFDXCfx3eHTDRESMz3asj1muO+4aIdjiuY=: CN=COMODO RSA Secure Server CA\n\t\tsha256/grX4Ta9HpZx6tSHkmCrvpApTQGo67CYDnvprLg5yRME=: CN=COMODO RSA Certification Authority\n\t\tsha256/lCppFqbkrlJ3EcVFAkeip0+44VaoJUymbnOaEUk7tEU=: CN=AddTrust External CA Root\n\t\tPinned certificates for publicobject.com:\n\t\tsha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\n\t\tat okhttp3.CertificatePinner.check(CertificatePinner.java)\n\t\tat okhttp3.Connection.upgradeToTls(Connection.java)\n\t\tat okhttp3.Connection.connect(Connection.java)\n\t\tat okhttp3.Connection.connectAndSetOwner(Connection.java)\n\t\t- Follow up by pasting the public key hashes from the exception into the certificate pinner's configuration\n \n ### Certificate Pinning\n\n```javascript\nimport {fetch} from 'react-native-ssl-pinning';\n\nfetch(url, {\n\tmethod: \"POST\" ,\n\ttimeoutInterval: communication_timeout, // milliseconds\n\tbody: body,\n\t// your certificates array (needed only in android) ios will pick it automatically\n\tsslPinning: {\n\t\tcerts: [\"cert1\",\"cert2\"] // your certificates name (without extension), for example cert1.cer, cert2.cer\n\t},\n\theaders: {\n\t\tAccept: \"application/json; charset=utf-8\", \"Access-Control-Allow-Origin\": \"*\", \"e_platform\": \"mobile\",\n\t}\n})\n.then(response =\u003e {\n\tconsole.log(`response received ${response}`)\n})\n.catch(err =\u003e {\n\tconsole.log(`error: ${err}`)\n})\n```\n ### Public Key Pinning\n```javascript\nimport {fetch} from 'react-native-ssl-pinning';\n\nfetch(\"https://publicobject.com\", {\n      method: \"GET\" ,\n      timeoutInterval: 10000, // milliseconds\n      // your certificates array (needed only in android) ios will pick it automatically\n      pkPinning: true,\n      sslPinning: {\n        certs: [\"sha256//r8udi/Mxd6pLO7y7hZyUMWq8YnFnIWXCqeHsTDRqy8=\",\n        \"sha256/YLh1dUR9y6Kja30RrAn7JKnbQG/uEtLMkBgFF2Fuihg=\",\n        \"sha256/Vjs8r4z+80wjNcr1YKepWQboSIRi63WsWXhIMN+eWys=\"\n      ]\n      },\n      headers: {\n        Accept: \"application/json; charset=utf-8\", \"Access-Control-Allow-Origin\": \"*\", \"e_platform\": \"mobile\",\n      }\n\t})\n\t\n```\n### Disable Pinning\n```javascript\n\n fetch(\"https://publicobject.com\", {\n      method: \"GET\" ,\n      timeoutInterval: 10000, // milliseconds\n      disableAllSecurity: true,\n      headers: {\n        Accept: \"application/json; charset=utf-8\", \"Access-Control-Allow-Origin\": \"*\", \"e_platform\": \"mobile\",\n      }\n\t})\n\t\t\n```\n### Case Sensitive Headers\n```javascript\n\n fetch(\"https://publicobject.com\", {\n      method: \"GET\" ,\n      timeoutInterval: 10000, // milliseconds\n      caseSensitiveHeaders: true, //in case you want headers to be case Sensitive\n      headers: {\n\t\tAccept: \"application/json; charset=utf-8\", \"Access-Control-Allow-Origin\": \"*\", \"e_platform\": \"mobile\",\n\t\tSOAPAction: \"testAction\",\n      }\n\t})\n\n\n```\n ### Cookies Handling\n\n```javascript\nimport {removeCookieByName} from 'react-native-ssl-pinning';\n\n\nremoveCookieByName('cookieName')\n.then(res =\u003e{\n\tconsole.log('removeCookieByName');\n})\n\ngetCookies('domain')\n.then(cookies =\u003e {\n// do what you need with your cookies\n})\n\n```\n\n## Debug Interceptors \u0026 Request/Response Observers\n\nThis library now supports custom debug interceptors and request/response observers to help with debugging network requests in development builds. These features are only active in DEBUG builds for security reasons.\n\n### Summary of Recent Enhancements\n\n**Latest Updates (June 2025):**\n1. **Android Custom Debug Interceptor Support** - Added ability to inject custom OkHttp interceptors for debugging network traffic\n2. **Android Debug Interceptor Refactoring** - Improved code organization by extracting interceptor logic into a dedicated method\n3. **iOS Request/Response Observers** - Added observer methods to monitor network requests and responses on iOS for debugging purposes\n\n### Android Debug Interceptor\n\nAdd custom debug interceptors to monitor and modify HTTP requests/responses in Android:\n\n```java\n// In your Android application code (Java/Kotlin)\nimport com.toyberman.Utils.OkHttpUtils;\nimport okhttp3.Interceptor;\nimport okhttp3.logging.HttpLoggingInterceptor;\n\n// Example: Add a custom logging interceptor\nInterceptor customInterceptor = new HttpLoggingInterceptor()\n    .setLevel(HttpLoggingInterceptor.Level.BODY);\n\n// Add the interceptor (only works in DEBUG builds)\nOkHttpUtils.addInterceptorForDebug(customInterceptor);\n```\n\n**Features:**\n- Only active in DEBUG builds for security\n- Supports any OkHttp interceptor\n- Useful for detailed request/response logging\n- Can be used for request modification during development\n\n### iOS Request/Response Observers\n\nMonitor network requests and responses on iOS using observer methods:\n\n```objc\n// In your iOS application code (Objective-C)\n#import \"RNSslPinning.h\"\n\n// Set request observer to monitor outgoing requests\n[RNSslPinning setRequestObserver:^(NSURLRequest *request) {\n    NSLog(@\"Request: %@ %@\", request.HTTPMethod, request.URL);\n    // Add your custom request monitoring logic here\n}];\n\n// Set response observer to monitor responses with timing\n[RNSslPinning setResponseObserver:^(NSURLRequest *request, NSHTTPURLResponse *response, NSData *data, NSTimeInterval startTime) {\n    NSTimeInterval duration = ([[NSDate date] timeIntervalSince1970] * 1000.0) - startTime;\n    NSLog(@\"Response: %ld for %@ (%.2fms)\", (long)response.statusCode, request.URL, duration);\n    // Add your custom response monitoring logic here\n}];\n```\n\n**Features:**\n- Only active in DEBUG builds for security  \n- Monitor all outgoing requests\n- Track response data, status codes, and timing\n- Handle both successful responses and error cases\n- Captures original request details for correlation\n\n### Use Cases\n\n- **Network Debugging**: Monitor request/response flow during development\n- **Performance Analysis**: Track request timing and response sizes\n- **SSL/TLS Troubleshooting**: Debug certificate pinning issues\n- **API Development**: Verify request formats and response handling\n- **Integration Testing**: Monitor network calls during automated tests\n\n**Note**: These debugging features are automatically disabled in production builds for security and performance reasons.\n\n  ## Multipart request (FormData)\n\n```javascript\nlet formData = new FormData()\n\n#You could add a key/value pair to this using #FormData.append:\n\nformData.append('username', 'Chris');\n\n# Adding a file to the request\nformData.append('file', {\n\t\tname: encodeURIComponent(response.fileName),\n\t\tfileName: encodeURIComponent(response.fileName),\n\t\ttype: this._extractFileType(response.fileName),\n\t\turi: response.uri\n})\n\nfetch(url, {\n\tmethod: \"POST\" ,\n\ttimeoutInterval: communication_timeout, // milliseconds\n\tbody: {\n\t\tformData: request,\n\t},\n\tsslPinning: {\n\t\tcerts: [\"cert1\",\"cert2\"]\n\t},\n\theaders: {\n\t\taccept: 'application/json, text/plain, /',\n\t}\n})\n\ndon't add 'content-type': 'multipart/form-data; charset=UTF-8',\nSetting the Content-Type header manually means it's missing the boundary parameter. Remove that header and allow fetch to generate the full content type.\n```\n\n## License\nThis project is licensed under the terms of the MIT license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMaxToyberman%2Freact-native-ssl-pinning","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FMaxToyberman%2Freact-native-ssl-pinning","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMaxToyberman%2Freact-native-ssl-pinning/lists"}