Skip to content

Commit 052d8a3

Browse files
committed
encryption decryption method added
1 parent 836fcd9 commit 052d8a3

File tree

4 files changed

+205
-0
lines changed

4 files changed

+205
-0
lines changed

android/src/main/java/com/encryption/EncryptionModule.kt

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@ package com.encryption
22

33
import com.facebook.react.bridge.ReactApplicationContext
44
import com.facebook.react.module.annotations.ReactModule
5+
import javax.crypto.Cipher
6+
import javax.crypto.spec.IvParameterSpec
7+
import javax.crypto.spec.SecretKeySpec
8+
import java.security.SecureRandom
9+
import android.util.Base64
10+
import android.util.Log
511

612
@ReactModule(name = EncryptionModule.NAME)
713
class EncryptionModule(reactContext: ReactApplicationContext) :
@@ -17,7 +23,76 @@ class EncryptionModule(reactContext: ReactApplicationContext) :
1723
return a * b
1824
}
1925

26+
override fun encrypt(data: String, key: String): String {
27+
return try {
28+
Log.d(TAG, "Starting encryption...")
29+
30+
// Validate key length
31+
if (key.toByteArray().size != 16) {
32+
val errorMessage = "Error: Key must be 16 bytes (128 bits) long."
33+
Log.e(TAG, "Encryption failed: $errorMessage")
34+
return errorMessage
35+
}
36+
37+
// Generate a random IV
38+
val iv = ByteArray(16)
39+
SecureRandom().nextBytes(iv)
40+
val ivSpec = IvParameterSpec(iv)
41+
42+
val secretKey = SecretKeySpec(key.toByteArray(), "AES")
43+
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
44+
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec)
45+
val encryptedData = cipher.doFinal(data.toByteArray())
46+
47+
// Combine IV and encrypted data
48+
val combined = iv + encryptedData
49+
val base64 = Base64.encodeToString(combined, Base64.DEFAULT)
50+
51+
Log.d(TAG, "Encryption successful. Encrypted data (Base64): $base64")
52+
base64 // Return the encrypted data
53+
} catch (e: Exception) {
54+
val errorMessage = "Error: Encryption failed - ${e.message}"
55+
Log.e(TAG, errorMessage, e)
56+
errorMessage // Return the error message
57+
}
58+
}
59+
60+
61+
override fun decrypt(encryptedData: String, key: String): String {
62+
return try {
63+
Log.d(TAG, "Starting decryption...")
64+
65+
// Validate key length
66+
if (key.toByteArray().size != 16) {
67+
val errorMessage = "Error: Key must be 16 bytes (128 bits) long."
68+
Log.e(TAG, "Decryption failed: $errorMessage")
69+
return errorMessage
70+
}
71+
72+
val decodedData = Base64.decode(encryptedData, Base64.DEFAULT)
73+
74+
// Extract IV and encrypted data
75+
val iv = decodedData.copyOfRange(0, 16)
76+
val encryptedBytes = decodedData.copyOfRange(16, decodedData.size)
77+
val ivSpec = IvParameterSpec(iv)
78+
79+
val secretKey = SecretKeySpec(key.toByteArray(), "AES")
80+
val cipher = Cipher.getInstance("AES/CBC/PKCS5Padding")
81+
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec)
82+
val decryptedData = cipher.doFinal(encryptedBytes)
83+
84+
val result = String(decryptedData)
85+
Log.d(TAG, "Decryption successful. Decrypted data: $result")
86+
result // Return the decrypted data
87+
} catch (e: Exception) {
88+
val errorMessage = "Error: Decryption failed - ${e.message}"
89+
Log.e(TAG, errorMessage, e)
90+
errorMessage // Return the error message
91+
}
92+
}
93+
2094
companion object {
2195
const val NAME = "Encryption"
96+
private const val TAG = "AESEncryptionModule"
2297
}
2398
}

ios/Encryption.mm

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
#import "Encryption.h"
2+
#import <CommonCrypto/CommonCrypto.h>
3+
24

35
@implementation Encryption
46
RCT_EXPORT_MODULE()
@@ -9,6 +11,126 @@ - (NSNumber *)multiply:(double)a b:(double)b {
911
return result;
1012
}
1113

14+
// Method to encrypt data
15+
- (NSString *)encrypt:(NSString *)data key:(NSString *)key {
16+
NSError *error = nil;
17+
NSString *encryptedString = [self encryptData:data key:key error:&error];
18+
19+
if (error) {
20+
return @"error";
21+
// return @{
22+
// @"error": @{
23+
// @"code": @(error.code),
24+
// @"message": error.localizedDescription
25+
// }
26+
// };
27+
}
28+
29+
return encryptedString;
30+
31+
// return @{
32+
// @"result": encryptedString
33+
// };
34+
}
35+
36+
- (NSString *)encryptData:(NSString *)data key:(NSString *)key error:(NSError **)error {
37+
NSData *dataToEncrypt = [data dataUsingEncoding:NSUTF8StringEncoding];
38+
NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
39+
40+
size_t bufferSize = kCCBlockSizeAES128 + dataToEncrypt.length + kCCBlockSizeAES128;
41+
void *encryptedBuffer = malloc(bufferSize);
42+
size_t numBytesEncrypted = 0;
43+
44+
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
45+
kCCAlgorithmAES,
46+
kCCOptionPKCS7Padding,
47+
keyData.bytes,
48+
keyData.length,
49+
NULL,
50+
dataToEncrypt.bytes,
51+
dataToEncrypt.length,
52+
encryptedBuffer,
53+
bufferSize,
54+
&numBytesEncrypted);
55+
56+
if (cryptStatus == kCCSuccess) {
57+
NSData *encryptedData = [NSData dataWithBytesNoCopy:encryptedBuffer length:numBytesEncrypted];
58+
return [encryptedData base64EncodedStringWithOptions:0];
59+
} else {
60+
free(encryptedBuffer);
61+
if (error) {
62+
*error = [NSError errorWithDomain:@"EncryptionError"
63+
code:cryptStatus
64+
userInfo:@{NSLocalizedDescriptionKey: @"Failed to encrypt data"}];
65+
}
66+
return nil;
67+
}
68+
}
69+
70+
- (NSString *)decrypt:(NSString *)encryptedData key:(NSString *)key {
71+
NSError *error = nil;
72+
NSString *decryptedString = [self decryptData:encryptedData key:key error:&error];
73+
74+
if (error) {
75+
return @"Error";
76+
// return @{
77+
// @"error": @{
78+
// @"code": @(error.code),
79+
// @"message": error.localizedDescription
80+
// }
81+
// };
82+
}
83+
84+
return decryptedString;
85+
86+
// return @{
87+
// @"result": decryptedString
88+
// };
89+
}
90+
91+
- (NSString *)decryptData:(NSString *)encryptedData key:(NSString *)key error:(NSError **)error {
92+
NSData *encryptedDataBytes = [[NSData alloc] initWithBase64EncodedString:encryptedData options:0];
93+
if (!encryptedDataBytes) {
94+
if (error) {
95+
*error = [NSError errorWithDomain:@"DecryptionError"
96+
code:-1
97+
userInfo:@{NSLocalizedDescriptionKey: @"Invalid encrypted data"}];
98+
}
99+
return nil;
100+
}
101+
102+
NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding];
103+
size_t bufferSize = encryptedDataBytes.length + kCCBlockSizeAES128;
104+
void *decryptedBuffer = malloc(bufferSize);
105+
size_t numBytesDecrypted = 0;
106+
107+
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
108+
kCCAlgorithmAES,
109+
kCCOptionPKCS7Padding,
110+
keyData.bytes,
111+
keyData.length,
112+
NULL,
113+
encryptedDataBytes.bytes,
114+
encryptedDataBytes.length,
115+
decryptedBuffer,
116+
bufferSize,
117+
&numBytesDecrypted);
118+
119+
if (cryptStatus == kCCSuccess) {
120+
NSData *decryptedData = [NSData dataWithBytesNoCopy:decryptedBuffer length:numBytesDecrypted];
121+
NSString *decryptedString = [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];
122+
return decryptedString;
123+
} else {
124+
free(decryptedBuffer);
125+
if (error) {
126+
*error = [NSError errorWithDomain:@"DecryptionError"
127+
code:cryptStatus
128+
userInfo:@{NSLocalizedDescriptionKey: @"Failed to decrypt data"}];
129+
}
130+
return nil;
131+
}
132+
}
133+
12134
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
13135
(const facebook::react::ObjCTurboModule::InitParams &)params
14136
{

src/NativeEncryption.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { TurboModuleRegistry } from 'react-native';
33

44
export interface Spec extends TurboModule {
55
multiply(a: number, b: number): number;
6+
encrypt(data: string, key: string): string;
7+
decrypt(data: string, key: string): string;
68
}
79

810
export default TurboModuleRegistry.getEnforcing<Spec>('Encryption');

src/index.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,9 @@ import Encryption from './NativeEncryption';
33
export function multiply(a: number, b: number): number {
44
return Encryption.multiply(a, b);
55
}
6+
export function encrypt(data: string, key: string): string {
7+
return Encryption.encrypt(data, key);
8+
}
9+
export function decrypt(data: string, key: string): string {
10+
return Encryption.decrypt(data, key);
11+
}

0 commit comments

Comments
 (0)