UNPKG

rn-encryption

Version:
668 lines (558 loc) 21.2 kB
# 📚 **React Native Integration Guide for `rn-encryption` Library** This guide explains how to directly access methods from the `rn-encryption` library in a **React Native project**, including usage examples for AES, RSA, Hashing, HMAC, Random String, and Base64 utilities. - **Mobile (iOS & Android): Utilizes native implementations through JSI (JavaScript Interface) via Turbo Modules for encryption.** - **Web: Leverages crypto.subtle for encryption functionality. https://www.npmjs.com/package/web-secure-encryption is being used to support encryption for web.** --- ## 📑 **Table of Contents** 1. [Library Installation](#1-library-installation) 2. [Requirements](#2-new_arch_needed) 3. [Setup in React Native](#3-setup-in-react-native) 4. [Direct Method Import](#4-direct-method-import) 5. [API Overview](#5-api-overview) 6. [Usage Examples](#6-usage-examples) 7. [Troubleshooting](#7-troubleshooting) 8. [Best Practices](#8-best-practices) 9. [FAQ](#9-faq) 10. [Security Best Practices](#security-best-practices) --- ## 🚀 **1. Library Installation** ### 1.1 **Add Dependency** Install the library using npm or yarn: ```bash expo install @yourorg/native-encryption # OR npm install rn-encryption --save # OR yarn add rn-encryption ``` ### 1.2 **Rebuild the Project** For Android: ```bash cd android && ./gradlew clean && cd .. npx react-native run-android ``` For iOS: ```bash cd ios && pod install && cd .. npx react-native run-ios ``` --- ## **2.Requirements** ### 2.1 **New Architecture required** New architecture required. React native >= 0.76.5 Works with Expo **Bare Workflow** & **Vanilla React Native** ### 2.2 **iOS: Cryptokit from swift is being used for encryption. Minimin support iOS version is 13.0** --- ## ⚙️ **3. Setup in React Native** No additional configuration is required. The methods can be **directly imported** and used. --- ## 📦 **4. Direct Method Import** You can directly import the methods you need: ```tsx import { encryptAES, decryptAES, encryptRSA, decryptRSA, hashSHA256, hashSHA512, hmacSHA256, base64Encode, base64Decode, generateRandomString, generateAESKey, generateRSAKeyPair, generateECDSAKeyPair, signDataECDSA, verifySignatureECDSA, encryptAsyncAES, decryptAsyncAES, encryptAsyncRSA, decryptAsyncRSA, encryptFile, decryptFile, } from 'rn-encryption';; ``` - **Each method can be accessed directly without a default object wrapper.** - **Please note that encryptFile/decryptFile methods are not available for web yet.** - **All web methods have promises while few native methods can be called without promises.** --- ## 📚 **5. API Overview** ### 🔒 **AES Encryption/Decryption** - **`generateAESKey(keySize: number): string`** - **`encryptAES(data: string, key: string): string`** - **`decryptAES(data: string, key: string): string`** ### 🔑 **RSA Encryption/Decryption** - **`generateRSAKeyPair(): keypair`** - **`encryptRSA(data: string, publicKey: string): string`** - **`decryptRSA(data: string, privateKey: string): string`** ### 🛡️ **SHA Hashing** - **`hashSHA256(input: string): string`** - **`hashSHA512(input: string): string`** ### 📝 **HMAC-SHA256** - **`hmacSHA256(data: string, key: string): string`** ### 🎲 **Random String Generation** - **`generateRandomString(input: number): string`** ### 📝 **Base64 Encoding/Decoding** - **`base64Encode(input: string): string`** - **`base64Decode(input: string): string`** ### 🔒 **ECDA Encryption/Decryption** - **`generateECDSAKeyPair(): keypair`** - **`signDataECDSA(data: string, key: string): string`** - **`verifySignatureECDSA(data: string,signatureBase64: string, key: string): boolean`** ### 🔒 **Asynchronous Methods** - **`encryptAsyncAES(data: string, key: string): Promise<string>`** - **`decryptAsyncAES(data: string, key: string): Promise<string>`** - **`encryptAsyncRSA(data: string, key: string): Promise<string>`** - **`decryptAsyncRSA(data: string, key: string): Promise<string>`** - **`encryptFile(inputPath: string,outputPath: string, key: string): Promise<string>`** - **`decryptFile(inputPath: string, key: string): Promise<string>`** --- ## 🛠️ **6.Native Usage Examples** ```tsx import { useState } from 'react'; import { View, StyleSheet, Text, Button } from 'react-native'; import { encryptAES, decryptAES, encryptRSA, decryptRSA, hashSHA256, hashSHA512, hmacSHA256, base64Encode, base64Decode, generateRandomString, generateAESKey, generateRSAKeyPair, generateECDSAKeyPair, signDataECDSA, verifySignatureECDSA, encryptAsyncAES, decryptAsyncAES, encryptAsyncRSA, decryptAsyncRSA, encryptFile, decryptFile } from 'rn-encryption'; import RNFS from 'react-native-fs'; interface EncryptionError { name: string; message: string; } export default function DashboardScreen() { const [result, setResult] = useState(''); // Encryption/Decryption result const inputPath = `${RNFS.DocumentDirectoryPath}/data.txt`; const outputPath = `${RNFS.DocumentDirectoryPath}/data.enc`; const decryptedPath = `${RNFS.DocumentDirectoryPath}/data-decrypted.txt`; function handleRSAEncryption() { const plaintext = 'Hello, RSA Encryption!'; const generatedKeys = generateRSAKeyPair(); try { // Step 1: Encrypt the plaintext using the Public Key const encryptedData = encryptRSA(plaintext, generatedKeys.publicKey); // Step 2: Decrypt the encrypted data using the Private Key const decryptedData = decryptRSA(encryptedData, generatedKeys.privateKey); // Step 3: Validation if (decryptedData === plaintext) { console.log('✅ RSA Encryption and Decryption Successful!'); } else { console.error('❌ Decrypted data does not match original plaintext!'); } } catch (error) { console.error('⚠️ RSA Error:', error); } } async function handleAsyncRSAEncryption() { const plaintext = 'Hello, RSA Encryption!'; const generatedKeys = generateRSAKeyPair(); try { // Step 1: Encrypt the plaintext using the Public Key const encryptedData = await encryptAsyncRSA( plaintext, generatedKeys.publicKey ); // Step 2: Decrypt the encrypted data using the Private Key const decryptedData = await decryptAsyncRSA( encryptedData, generatedKeys.privateKey ); // Step 3: Validation if (decryptedData === plaintext) { console.log('✅ RSA Encryption and Decryption Successful!'); } else { console.error('❌ Decrypted data does not match original plaintext!'); } } catch (error) { console.error('⚠️ RSA Error:', error); } } const handleAESEncryption = () => { const sampleObject = { name: 'John Doe', age: 30, roles: ['admin', 'editor'], }; try { const generatedKey = generateAESKey(256); const jsonString = JSON.stringify(sampleObject); const encryptedString = encryptAES(jsonString, generatedKey); // Decrypt and parse JSON const decryptedJsonString = decryptAES(encryptedString, generatedKey); const decryptedObject = JSON.parse(decryptedJsonString); console.log('Decrypted Object:', decryptedObject); } catch (err: unknown) { if (err instanceof Error) { let error = err.cause as EncryptionError; console.log('❌ Error:123', error.message); } else { console.log('❌ Unknown Error:', err); } setResult('An error occurred during encryption/decryption.'); } }; const handleAsyncESEncryption = async () => { const sampleObject = { name: 'John Doe', age: 30, roles: ['admin', 'editor'], }; try { const generatedKey = generateAESKey(256); const jsonString = JSON.stringify(sampleObject); const encryptedString = await encryptAsyncAES(jsonString, generatedKey); console.log('encrypted Object:', encryptedString); // Decrypt and parse JSON const decryptedJsonString = await decryptAsyncAES( encryptedString, generatedKey ); const decryptedObject = JSON.parse(decryptedJsonString); console.log('Decrypted Object:', decryptedObject); } catch (err: unknown) { if (err instanceof Error) { let error = err.cause as EncryptionError; console.log('❌ Error:123', error.message); } else { console.log('❌ Unknown Error:', err); } setResult('An error occurred during encryption/decryption.'); } }; const hashing = () => { try { console.log('--- Hashing ---'); const sha256Hash = hashSHA256('Hello Hashing'); console.log('SHA-256 Hash:', sha256Hash); const sha512Hash = hashSHA512('Hello Hashing'); console.log('SHA-512 Hash:', sha512Hash); } catch (err) { console.log('error is', err); } }; const hmac = () => { try { console.log('--- HMAC ---'); const hmackey = generateHMACKey(256); const hmachash = hmacSHA256('Hello HMAC', hmackey); const hmackey512 = generateHMACKey(512); const hmachash512 = hmacSHA256('Hello HMAC', hmackey512); console.log('HMAC-SHA256:', hmachash, hmachash512); } catch (err) { console.log('error is', err); } }; const signData = () => { const keyPair = generateECDSAKeyPair(); const data = 'Hello, ECDSA!'; const signature = signDataECDSA(data, keyPair.privateKey); const isValid = verifySignatureECDSA(data, signature, keyPair.publicKey); console.log('Signature:', signature); console.log('Is Valid Signature:', isValid); }; const base64 = () => { try { console.log('--- Base64 Encoding/Decoding ---'); const base64Encoded = base64Encode('Hello Base64 Encoding'); console.log('Base64 Encoded:', base64Encoded); const base64Decoded = base64Decode(base64Encoded); console.log('Base64 Decoded:', base64Decoded); } catch (err) { console.log('error is', err); } }; const createRandomString = () => { try { console.log('--- Utilities ---'); const randomString = generateRandomString(16); console.log('Random String:', randomString); } catch (err) { console.log('error is', err); } }; async function handleEncryptFileAES() { try { // Step 1: Write Sample Data to a File await RNFS.writeFile(inputPath, 'This is a sensitive file content.', 'utf8'); console.log(`File written at: ${inputPath}`); const generatedKey = generateAESKey(256); console.log('generatedKey ', generatedKey); // Step 2: Encrypt the File const encryptedFilePath = await encryptFile(inputPath, outputPath, generatedKey); console.log('Encrypted File Path:', encryptedFilePath); // Step 3: Verify Encrypted File const encryptedFileExists = await RNFS.exists(outputPath); console.log('Encrypted File Exists:', encryptedFileExists); const decryptedContent = await decryptFile(outputPath, generatedKey); console.log('Decrypted File Content:', decryptedContent); // Step 5: Write Decrypted Content to a New File await RNFS.writeFile(decryptedPath, decryptedContent, 'utf8'); console.log(`Decrypted file saved at: ${decryptedPath}`); } catch (error) { console.error('Encryption Error:', error); } } return ( <View style={{ flex: 1, alignItems: 'center', paddingTop: 80 }}> <Button title="Encrypt & Decrypt AES" onPress={handleAESEncryption} /> <Button title="Async Encrypt & Decrypt AES" onPress={handleAsyncESEncryption} /> <Button title="Encrypt & Decrypt File" onPress={handleEncryptFileAES} /> <Button title="Encrypt & Decrypt RSA" onPress={handleRSAEncryption} /> <Button title="Encrypt & Decrypt RSA" onPress={handleAsyncRSAEncryption} /> <Button title="Hashing" onPress={hashing} /> <Button title="HMAC" onPress={hmac} /> <Button title="Base64 Encoding" onPress={base64} /> <Button title="Generate random" onPress={createRandomString} /> <Button title="Sign & Validate data" onPress={signData} /> <Text style={styles.resultText}>{result}</Text> </View> ); } const styles = StyleSheet.create({ inputContainer: { marginVertical: 20, alignItems: 'center', width: '80%', }, textInput: { borderWidth: 1, borderColor: '#ccc', borderRadius: 5, padding: 10, width: '100%', marginTop: 10, }, resultText: { marginVertical: 20, textAlign: 'center', fontSize: 16, }, counterWrapper: { height: 150, justifyContent: 'center', alignItems: 'center', }, counterView: { width: 280, height: 140, }, text: { marginBottom: 20, fontSize: 16, }, }); ``` ## 🛠️ **7.Web Usage Examples** ```tsx import { View, Text, StyleSheet, Button } from 'react-native'; import { generateAESKey, encryptAES, decryptAES, generateRSAKeyPair, encryptRSA, decryptRSA, generateECDSAKeyPair, signDataECDSA, verifySignatureECDSA, generateHMACKey, hmacSHA256, hmacSHA512, hashSHA256, hashSHA512, generateRandomString, base64Decode, base64Encode } from 'rn-encryption'; export default function HomeScreen() { const handleAESEncryption = async () => { const sampleObject = { name: 'John Doe', age: 30, roles: ['admin', 'editor'], }; try { const generatedKey = await generateAESKey(); const jsonString = JSON.stringify(sampleObject); const encryptedString = await encryptAES(jsonString, generatedKey); // Decrypt and parse JSON const decryptedJsonString = await decryptAES(encryptedString, generatedKey); const decryptedObject = JSON.parse(decryptedJsonString); console.log('Decrypted Object:', generatedKey, ); } catch (err: unknown) { console.log('❌ Error:123', err); } }; async function handleAsyncRSAEncryption() { const plaintext = 'Hello, RSA Encryption!'; const generatedKeys = await generateRSAKeyPair(); try { // Step 1: Encrypt the plaintext using the Public Key const encryptedData = await encryptRSA( plaintext, generatedKeys.publicKey ); // Step 2: Decrypt the encrypted data using the Private Key const decryptedData = await decryptRSA( encryptedData, generatedKeys.privateKey ); // Step 3: Validation if (decryptedData === plaintext) { console.log('✅ RSA Encryption and Decryption Successful!'); } else { console.error('❌ Decrypted data does not match original plaintext!'); } } catch (error) { console.error('⚠️ RSA Error:', error); } } const hashing = async () => { try { console.log('--- Hashing ---'); const sha256Hash = await hashSHA256('Hello Hashing'); console.log('SHA-256 Hash:', sha256Hash); const sha512Hash = await hashSHA512('Hello Hashing'); console.log('SHA-512 Hash:', sha512Hash); } catch (err) { console.log('error is', err); } }; const hmac = async() => { try { const macKey = await generateHMACKey(256) console.log('--- HMAC ---',macKey); const hmachash = await hmacSHA256('Hello HMAC', macKey); console.log('HMAC-SHA256:', hmachash); } catch (err) { console.log('error is', err); } }; const base64 = async () => { try { console.log('--- Base64 Encoding/Decoding ---'); const base64Encoded = await base64Encode('Hello Base64 Encoding'); console.log('Base64 Encoded:', base64Encoded); const base64Decoded =await base64Decode(base64Encoded); console.log('Base64 Decoded:', base64Decoded); } catch (err) { console.log('error is', err); } }; const createRandomString = async () => { try { console.log('--- Utilities ---'); const randomString = await generateRandomString(16); console.log('Random String:', randomString); } catch (err) { console.log('error is', err); } }; const signData = async () => { const keyPair = await generateECDSAKeyPair(); const data = 'Hello, ECDSA!'; const signature = await signDataECDSA(data, keyPair.privateKey); const isValid = await verifySignatureECDSA(data, signature, keyPair.publicKey); console.log('Signature:', signature); console.log('Is Valid Signature:', isValid); }; return ( <View style={styles.container}> <Text style={styles.header}>Dynamic Routing Example</Text> <Button title="Encrypt & Decrypt AES" onPress={handleAESEncryption} /> <Button title="Encrypt & Decrypt RSA" onPress={handleAsyncRSAEncryption} /> <Button title="Sign data" onPress={signData} /> <Button title="Hashing" onPress={hashing} /> <Button title="HMAC" onPress={hmac} /> <Button title="Base64 Encoding" onPress={base64} /> <Button title="Generate random" onPress={createRandomString} /> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, padding: 16, justifyContent: 'center', backgroundColor: '#f4f4f4', }, header: { fontSize: 20, fontWeight: 'bold', marginBottom: 16, textAlign: 'center', }, item: { padding: 16, marginVertical: 8, backgroundColor: '#fff', borderRadius: 8, shadowColor: '#000', shadowOpacity: 0.1, shadowRadius: 4, elevation: 2, }, text: { fontSize: 16, }, }); ``` # **Keychain Integration for keys** - **Key Storage:** It is recommended to save encryption keys in Keychain (iOS) and Keystore (Android) for enhanced security. - **Example Implementation:** You can refer to an example in this repository for guidance. - **Customization:** The provided example serves as a sample implementation and can be modified according to specific requirements. --- ## 🐞 **8. Troubleshooting** 1. **Library Not Found:** - Run `npx react-native link rn-encryption`. - Clean and rebuild the project. 2. **AES Key Size Error:** - Ensure the AES key is **16, 24, or 32 characters**. 3. **RSA Key Parsing Issue:** - Verify the RSA key is in **Base64-encoded PEM format**. 4. **Permission Issues:** - Ensure native permissions are set correctly in **AndroidManifest.xml** or **iOS Podfile**. --- ## ✅ **9. Best Practices** 1. **Do Not Hardcode Keys:** Use `.env` or secure storage for keys. 2. **Handle Errors Gracefully:** Wrap calls in `try-catch` blocks. 3. **Validate Key Sizes:** Ensure AES and RSA keys meet size requirements. --- ## ❓ **10. FAQ** **Q: Does the library support both Android and iOS?** A: Partially, `rn-encryption` fully supports ios and encryptAES & decryptAES for Android platforms. **Q: Can I use the library in Expo?** A: Yes, if you're using **Expo Bare Workflow**. **Q: How do I debug encryption issues?** A: Add console logs and verify that keys and data are correctly passed. --- ## **11. Security Best Practices** 1. Use Strong Keys: Always use AES-256 for symmetric encryption and RSA-2048 for asymmetric encryption. 2. Key Storage: Store keys securely using Android Keystore and iOS Keychain. 3. Avoid Hardcoding Keys: Do not hardcode encryption keys directly in the app. ### 📚 **Encryption Mechanisms: Android (JCA) vs iOS (CryptoKit)** | **Feature** | **Android (JCA)** | **iOS (CryptoKit)** | |--------------------------------|-------------------------------------|----------------------------------| | **Symmetric Encryption** | ✅ AES-256-GCM | ✅ AES-256-GCM | | **Asymmetric Encryption** | ✅ RSA-2048 | ✅ RSA-2048 | | **Key Derivation** | ✅ PBKDF2 | ✅ PBKDF2 / ✅ HKDF | | **Hashing** | ✅ SHA-256, ✅ SHA-512 | ✅ SHA-256, ✅ SHA-512 | | **Message Authentication** | ✅ HMAC-SHA256 | ✅ HMAC-SHA256 | | **Digital Signatures** | ✅ ECDSA | ✅ ECDSA (via CryptoKit) | | **Key Management** | ✅ Android Keystore | ✅ iOS Keychain | | **Initialization Vector (IV)** | ✅ SecureRandom (12/16 Bytes) | ✅ Randomized IV (12 Bytes) | | **Authentication Tag** | ✅ Built-in (GCM Mode) | ✅ Built-in (GCM Mode) | | **Error Handling** | ✅ Strong Validation | ✅ Strong Validation | | **Performance** | ⚡ Optimized for Android | ⚡ Optimized for iOS | | **Parallel Processing** | ✅ Supported in GCM | ✅ Supported in GCM | | **Cryptographic Library** | ✅ Java Cryptography (JCA) | ✅ CryptoKit |