@avieldr/react-native-rsa 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +453 -0
  3. package/Rsa.podspec +23 -0
  4. package/android/build.gradle +69 -0
  5. package/android/src/main/AndroidManifest.xml +2 -0
  6. package/android/src/main/java/com/rsa/RsaModule.kt +129 -0
  7. package/android/src/main/java/com/rsa/RsaPackage.kt +33 -0
  8. package/android/src/main/java/com/rsa/core/ASN1Utils.kt +201 -0
  9. package/android/src/main/java/com/rsa/core/Algorithms.kt +126 -0
  10. package/android/src/main/java/com/rsa/core/KeyUtils.kt +83 -0
  11. package/android/src/main/java/com/rsa/core/RSACipher.kt +71 -0
  12. package/android/src/main/java/com/rsa/core/RSAKeyGenerator.kt +125 -0
  13. package/android/src/main/java/com/rsa/core/RSASigner.kt +70 -0
  14. package/ios/ASN1Utils.swift +225 -0
  15. package/ios/Algorithms.swift +89 -0
  16. package/ios/KeyUtils.swift +125 -0
  17. package/ios/RSACipher.swift +77 -0
  18. package/ios/RSAKeyGenerator.swift +164 -0
  19. package/ios/RSASigner.swift +101 -0
  20. package/ios/Rsa.h +61 -0
  21. package/ios/Rsa.mm +216 -0
  22. package/lib/module/NativeRsa.js +16 -0
  23. package/lib/module/NativeRsa.js.map +1 -0
  24. package/lib/module/constants.js +24 -0
  25. package/lib/module/constants.js.map +1 -0
  26. package/lib/module/encoding.js +116 -0
  27. package/lib/module/encoding.js.map +1 -0
  28. package/lib/module/errors.js +135 -0
  29. package/lib/module/errors.js.map +1 -0
  30. package/lib/module/index.js +232 -0
  31. package/lib/module/index.js.map +1 -0
  32. package/lib/module/keyInfo.js +286 -0
  33. package/lib/module/keyInfo.js.map +1 -0
  34. package/lib/module/package.json +1 -0
  35. package/lib/module/types.js +2 -0
  36. package/lib/module/types.js.map +1 -0
  37. package/lib/typescript/package.json +1 -0
  38. package/lib/typescript/src/NativeRsa.d.ts +32 -0
  39. package/lib/typescript/src/NativeRsa.d.ts.map +1 -0
  40. package/lib/typescript/src/constants.d.ts +21 -0
  41. package/lib/typescript/src/constants.d.ts.map +1 -0
  42. package/lib/typescript/src/encoding.d.ts +30 -0
  43. package/lib/typescript/src/encoding.d.ts.map +1 -0
  44. package/lib/typescript/src/errors.d.ts +47 -0
  45. package/lib/typescript/src/errors.d.ts.map +1 -0
  46. package/lib/typescript/src/index.d.ts +122 -0
  47. package/lib/typescript/src/index.d.ts.map +1 -0
  48. package/lib/typescript/src/keyInfo.d.ts +7 -0
  49. package/lib/typescript/src/keyInfo.d.ts.map +1 -0
  50. package/lib/typescript/src/types.d.ts +63 -0
  51. package/lib/typescript/src/types.d.ts.map +1 -0
  52. package/package.json +133 -0
  53. package/src/NativeRsa.ts +59 -0
  54. package/src/constants.ts +25 -0
  55. package/src/encoding.ts +139 -0
  56. package/src/errors.ts +206 -0
  57. package/src/index.ts +305 -0
  58. package/src/keyInfo.ts +334 -0
  59. package/src/types.ts +85 -0
@@ -0,0 +1,164 @@
1
+ import Foundation
2
+ import Security
3
+
4
+ /**
5
+ * Result of RSA key pair generation, containing both keys as PEM strings.
6
+ * Exposed to Objective-C for bridge compatibility.
7
+ */
8
+ @objc public class RSAKeyPairResult: NSObject {
9
+ @objc public let publicKey: String
10
+ @objc public let privateKey: String
11
+
12
+ init(publicKey: String, privateKey: String) {
13
+ self.publicKey = publicKey
14
+ self.privateKey = privateKey
15
+ }
16
+ }
17
+
18
+ /**
19
+ * RSA key generation and conversion operations.
20
+ *
21
+ * Thread-safe singleton that provides:
22
+ * - Key pair generation (PKCS#1 or PKCS#8 private key format)
23
+ * - Public key extraction from a private key
24
+ * - Private key format conversion between PKCS#1 and PKCS#8
25
+ *
26
+ * Uses the iOS Security framework (`SecKey` APIs) for key generation and import.
27
+ * Delegates ASN.1 encoding to `ASN1Utils` and PEM/key-loading to `KeyUtils`.
28
+ */
29
+ @objc public final class RSAKeyGenerator: NSObject {
30
+
31
+ @objc public static let shared = RSAKeyGenerator()
32
+ private override init() { super.init() }
33
+
34
+ // MARK: - Key Pair Generation
35
+
36
+ /**
37
+ * Generate an RSA key pair using the iOS Security framework.
38
+ *
39
+ * - Parameters:
40
+ * - keySize: RSA key size in bits (e.g. 1024, 2048, 4096)
41
+ * - format: "pkcs1" or "pkcs8" — controls the private key output format.
42
+ * Public key is always SPKI ("BEGIN PUBLIC KEY").
43
+ * - Throws: If key generation or export fails
44
+ * - Returns: RSAKeyPairResult with public and private keys in PEM format
45
+ */
46
+ @objc public func generateKeyPair(keySize: Int, format: String) throws -> RSAKeyPairResult {
47
+ let attributes: [String: Any] = [
48
+ kSecAttrKeyType as String: kSecAttrKeyTypeRSA,
49
+ kSecAttrKeySizeInBits as String: keySize,
50
+ kSecPrivateKeyAttrs as String: [
51
+ kSecAttrIsPermanent as String: false
52
+ ]
53
+ ]
54
+
55
+ var error: Unmanaged<CFError>?
56
+ guard let privateSecKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else {
57
+ let errorMessage = error?.takeRetainedValue().localizedDescription ?? "Unknown error"
58
+ throw NSError(domain: "RSAKeyGenerator", code: 1,
59
+ userInfo: [NSLocalizedDescriptionKey: "Failed to generate RSA key: \(errorMessage)"])
60
+ }
61
+
62
+ // SecKeyCopyExternalRepresentation returns PKCS#1 DER for RSA private keys
63
+ guard let privateKeyData = SecKeyCopyExternalRepresentation(privateSecKey, &error) as Data? else {
64
+ let errorMessage = error?.takeRetainedValue().localizedDescription ?? "Unknown error"
65
+ throw NSError(domain: "RSAKeyGenerator", code: 2,
66
+ userInfo: [NSLocalizedDescriptionKey: "Failed to export RSA key: \(errorMessage)"])
67
+ }
68
+
69
+ // Encode private key in the requested format
70
+ let privateKeyPEM: String
71
+ if format == "pkcs8" {
72
+ let pkcs8Data = ASN1Utils.wrapPkcs1InPkcs8(pkcs1Data: privateKeyData)
73
+ privateKeyPEM = KeyUtils.toPEM(data: pkcs8Data, header: "PRIVATE KEY")
74
+ } else {
75
+ privateKeyPEM = KeyUtils.toPEM(data: privateKeyData, header: "RSA PRIVATE KEY")
76
+ }
77
+
78
+ // Extract and export public key
79
+ guard let publicSecKey = SecKeyCopyPublicKey(privateSecKey) else {
80
+ throw NSError(domain: "RSAKeyGenerator", code: 3,
81
+ userInfo: [NSLocalizedDescriptionKey: "Could not extract public key"])
82
+ }
83
+
84
+ guard let publicKeyRawData = SecKeyCopyExternalRepresentation(publicSecKey, &error) as Data? else {
85
+ let errorMessage = error?.takeRetainedValue().localizedDescription ?? "Unknown error"
86
+ throw NSError(domain: "RSAKeyGenerator", code: 4,
87
+ userInfo: [NSLocalizedDescriptionKey: "Failed to export public key: \(errorMessage)"])
88
+ }
89
+
90
+ // Wrap raw PKCS#1 public key in SPKI for standard PEM format
91
+ let spkiData = ASN1Utils.wrapPublicKeyInSPKI(rawKeyData: publicKeyRawData)
92
+ let publicKeyPEM = KeyUtils.toPEM(data: spkiData, header: "PUBLIC KEY")
93
+
94
+ return RSAKeyPairResult(publicKey: publicKeyPEM, privateKey: privateKeyPEM)
95
+ }
96
+
97
+ // MARK: - Public Key Extraction
98
+
99
+ /**
100
+ * Extract the public key from an RSA private key PEM string.
101
+ *
102
+ * Works with both PKCS#1 and PKCS#8 input formats.
103
+ * The returned public key is always in SPKI PEM format ("BEGIN PUBLIC KEY").
104
+ */
105
+ @objc public func getPublicKeyFromPrivate(privateKeyPEM: String) throws -> String {
106
+ // Load private key (handles both PKCS#1 and PKCS#8 automatically)
107
+ let privateSecKey = try KeyUtils.loadPrivateKey(pem: privateKeyPEM)
108
+
109
+ guard let publicSecKey = SecKeyCopyPublicKey(privateSecKey) else {
110
+ throw NSError(domain: "RSAKeyGenerator", code: 8,
111
+ userInfo: [NSLocalizedDescriptionKey: "Could not extract public key"])
112
+ }
113
+
114
+ var error: Unmanaged<CFError>?
115
+ guard let publicKeyRawData = SecKeyCopyExternalRepresentation(publicSecKey, &error) as Data? else {
116
+ let errorMessage = error?.takeRetainedValue().localizedDescription ?? "Unknown error"
117
+ throw NSError(domain: "RSAKeyGenerator", code: 9,
118
+ userInfo: [NSLocalizedDescriptionKey: "Failed to export public key: \(errorMessage)"])
119
+ }
120
+
121
+ let spkiData = ASN1Utils.wrapPublicKeyInSPKI(rawKeyData: publicKeyRawData)
122
+ return KeyUtils.toPEM(data: spkiData, header: "PUBLIC KEY")
123
+ }
124
+
125
+ // MARK: - Key Format Conversion
126
+
127
+ /**
128
+ * Convert a private key PEM between PKCS#1 and PKCS#8 formats.
129
+ *
130
+ * - Parameters:
131
+ * - pem: The private key in PEM format
132
+ * - targetFormat: "pkcs1" or "pkcs8"
133
+ * - Throws: If the PEM format is unrecognized or base64 decoding fails
134
+ * - Returns: The private key re-encoded in the target format
135
+ */
136
+ @objc public func convertPrivateKey(pem: String, targetFormat: String) throws -> String {
137
+ if pem.contains("BEGIN RSA PRIVATE KEY") && targetFormat == "pkcs8" {
138
+ // PKCS#1 → PKCS#8: wrap the raw bytes in a PKCS#8 structure
139
+ let base64 = KeyUtils.extractBase64(from: pem)
140
+ guard let derData = Data(base64Encoded: base64) else {
141
+ throw NSError(domain: "RSAKeyGenerator", code: 10,
142
+ userInfo: [NSLocalizedDescriptionKey: "Invalid base64 encoding"])
143
+ }
144
+ let pkcs8Data = ASN1Utils.wrapPkcs1InPkcs8(pkcs1Data: derData)
145
+ return KeyUtils.toPEM(data: pkcs8Data, header: "PRIVATE KEY")
146
+ } else if pem.contains("BEGIN PRIVATE KEY") && targetFormat == "pkcs1" {
147
+ // PKCS#8 → PKCS#1: extract the inner PKCS#1 bytes
148
+ let base64 = KeyUtils.extractBase64(from: pem)
149
+ guard let derData = Data(base64Encoded: base64) else {
150
+ throw NSError(domain: "RSAKeyGenerator", code: 11,
151
+ userInfo: [NSLocalizedDescriptionKey: "Invalid base64 encoding"])
152
+ }
153
+ let pkcs1Data = ASN1Utils.extractPkcs1FromPkcs8(pkcs8Data: derData)
154
+ return KeyUtils.toPEM(data: pkcs1Data, header: "RSA PRIVATE KEY")
155
+ } else if (pem.contains("BEGIN RSA PRIVATE KEY") && targetFormat == "pkcs1") ||
156
+ (pem.contains("BEGIN PRIVATE KEY") && targetFormat == "pkcs8") {
157
+ // Already in the target format — return unchanged
158
+ return pem
159
+ } else {
160
+ throw NSError(domain: "RSAKeyGenerator", code: 12,
161
+ userInfo: [NSLocalizedDescriptionKey: "Unrecognized PEM format or unsupported target format"])
162
+ }
163
+ }
164
+ }
@@ -0,0 +1,101 @@
1
+ import Foundation
2
+ import Security
3
+
4
+ /**
5
+ * RSA signing and verification operations for iOS.
6
+ *
7
+ * Uses the Security framework's `SecKeyCreateSignature` / `SecKeyVerifySignature`.
8
+ * All data crosses the bridge as base64 strings to avoid binary encoding issues.
9
+ *
10
+ * Supported padding modes:
11
+ * - "pss" — PSS (Probabilistic Signature Scheme) with configurable hash
12
+ * - "pkcs1" — PKCS#1 v1.5 deterministic signatures
13
+ *
14
+ * The "Message" algorithm variants are used (e.g. `rsaSignatureMessagePSSSHA256`),
15
+ * meaning the Security framework hashes the input internally — callers pass the raw message.
16
+ *
17
+ * Exposed to Objective-C via `@objc` for the React Native bridge.
18
+ */
19
+ @objc public class RSASigner: NSObject {
20
+
21
+ /**
22
+ * Sign data with an RSA private key.
23
+ *
24
+ * - Parameters:
25
+ * - dataBase64: The data to sign, encoded as base64
26
+ * - privateKeyPEM: The private key in PEM format (PKCS#1 or PKCS#8)
27
+ * - padding: "pss" or "pkcs1"
28
+ * - hash: "sha256", "sha1", "sha384", or "sha512"
29
+ * - Throws: If the input is invalid, key loading fails, or signing fails
30
+ * - Returns: The signature encoded as base64
31
+ */
32
+ @objc public static func sign(dataBase64: String, privateKeyPEM: String, padding: String, hash: String) throws -> String {
33
+ guard let data = Data(base64Encoded: dataBase64) else {
34
+ throw NSError(domain: "RSASigner", code: 1,
35
+ userInfo: [NSLocalizedDescriptionKey: "Invalid base64 input data"])
36
+ }
37
+
38
+ let privateKey = try KeyUtils.loadPrivateKey(pem: privateKeyPEM)
39
+ let algorithm = try Algorithms.signatureAlgorithm(padding: padding, hash: hash)
40
+
41
+ var error: Unmanaged<CFError>?
42
+ guard let signatureData = SecKeyCreateSignature(privateKey, algorithm, data as CFData, &error) as Data? else {
43
+ let errorMessage = error?.takeRetainedValue().localizedDescription ?? "Unknown error"
44
+ throw NSError(domain: "RSASigner", code: 2,
45
+ userInfo: [NSLocalizedDescriptionKey: "Signing failed: \(errorMessage)"])
46
+ }
47
+
48
+ return signatureData.base64EncodedString()
49
+ }
50
+
51
+ /**
52
+ * Verify a signature against data using an RSA public key.
53
+ *
54
+ * - Parameters:
55
+ * - dataBase64: The original data that was signed, encoded as base64
56
+ * - signatureBase64: The signature to verify, encoded as base64
57
+ * - publicKeyPEM: The public key in SPKI PEM format ("BEGIN PUBLIC KEY")
58
+ * - padding: "pss" or "pkcs1" — must match the padding used during signing
59
+ * - hash: "sha256", "sha1", "sha384", or "sha512" — must match signing hash
60
+ * - Throws: If the input is invalid or key loading fails
61
+ * - Returns: true if the signature is valid, false otherwise
62
+ *
63
+ * Note on Swift→Obj-C bridging: A `throws -> Bool` method maps to Obj-C as
64
+ * `(BOOL)...error:(NSError **)`. When the method returns `false` normally
65
+ * (invalid signature), `*error` is nil. When it throws (actual error), `*error`
66
+ * is set. The bridge checks `error != nil` to distinguish these cases.
67
+ */
68
+ @objc public static func verify(dataBase64: String, signatureBase64: String, publicKeyPEM: String, padding: String, hash: String) throws -> Bool {
69
+ guard let data = Data(base64Encoded: dataBase64) else {
70
+ throw NSError(domain: "RSASigner", code: 3,
71
+ userInfo: [NSLocalizedDescriptionKey: "Invalid base64 input data"])
72
+ }
73
+ guard let signatureData = Data(base64Encoded: signatureBase64) else {
74
+ throw NSError(domain: "RSASigner", code: 4,
75
+ userInfo: [NSLocalizedDescriptionKey: "Invalid base64 signature"])
76
+ }
77
+
78
+ let publicKey = try KeyUtils.loadPublicKey(pem: publicKeyPEM)
79
+ let algorithm = try Algorithms.signatureAlgorithm(padding: padding, hash: hash)
80
+
81
+ // SecKeyVerifySignature returns true for valid signatures, false otherwise.
82
+ // IMPORTANT: On iOS, it also sets *error for invalid signatures (errSecVerifyFailed = -67808).
83
+ // We must distinguish between "invalid signature" (return false) and "actual error"
84
+ // (bad key type, unsupported algorithm, etc.) by checking the error code.
85
+ var error: Unmanaged<CFError>?
86
+ let result = SecKeyVerifySignature(publicKey, algorithm, data as CFData, signatureData as CFData, &error)
87
+
88
+ if !result, let cfError = error?.takeRetainedValue() {
89
+ let nsError = cfError as Error as NSError
90
+ // errSecVerifyFailed (-67808) means "signature doesn't match" — not an actual error.
91
+ // Return false for this case; only throw for unexpected failures.
92
+ if nsError.domain == NSOSStatusErrorDomain && nsError.code == Int(errSecVerifyFailed) {
93
+ return false
94
+ }
95
+ throw NSError(domain: "RSASigner", code: 5,
96
+ userInfo: [NSLocalizedDescriptionKey: "Verification error: \(cfError.localizedDescription)"])
97
+ }
98
+
99
+ return result
100
+ }
101
+ }
package/ios/Rsa.h ADDED
@@ -0,0 +1,61 @@
1
+ #ifdef __cplusplus
2
+ #import <RsaSpec/RsaSpec.h>
3
+ #endif
4
+
5
+ @interface Rsa : NSObject
6
+ #ifdef __cplusplus
7
+ <NativeRsaSpec>
8
+ #endif
9
+
10
+ // --- Key Generation ---
11
+
12
+ - (void)generateKeyPair:(double)keySize
13
+ format:(NSString *)format
14
+ resolve:(RCTPromiseResolveBlock)resolve
15
+ reject:(RCTPromiseRejectBlock)reject;
16
+
17
+ - (void)getPublicKeyFromPrivate:(NSString *)privateKeyPEM
18
+ resolve:(RCTPromiseResolveBlock)resolve
19
+ reject:(RCTPromiseRejectBlock)reject;
20
+
21
+ // --- Encrypt / Decrypt ---
22
+
23
+ - (void)encrypt:(NSString *)dataBase64
24
+ publicKeyPEM:(NSString *)publicKeyPEM
25
+ padding:(NSString *)padding
26
+ hash:(NSString *)hash
27
+ resolve:(RCTPromiseResolveBlock)resolve
28
+ reject:(RCTPromiseRejectBlock)reject;
29
+
30
+ - (void)decrypt:(NSString *)dataBase64
31
+ privateKeyPEM:(NSString *)privateKeyPEM
32
+ padding:(NSString *)padding
33
+ hash:(NSString *)hash
34
+ resolve:(RCTPromiseResolveBlock)resolve
35
+ reject:(RCTPromiseRejectBlock)reject;
36
+
37
+ // --- Sign / Verify ---
38
+
39
+ - (void)sign:(NSString *)dataBase64
40
+ privateKeyPEM:(NSString *)privateKeyPEM
41
+ padding:(NSString *)padding
42
+ hash:(NSString *)hash
43
+ resolve:(RCTPromiseResolveBlock)resolve
44
+ reject:(RCTPromiseRejectBlock)reject;
45
+
46
+ - (void)verify:(NSString *)dataBase64
47
+ signatureBase64:(NSString *)signatureBase64
48
+ publicKeyPEM:(NSString *)publicKeyPEM
49
+ padding:(NSString *)padding
50
+ hash:(NSString *)hash
51
+ resolve:(RCTPromiseResolveBlock)resolve
52
+ reject:(RCTPromiseRejectBlock)reject;
53
+
54
+ // --- Key Format Conversion ---
55
+
56
+ - (void)convertPrivateKey:(NSString *)pem
57
+ targetFormat:(NSString *)targetFormat
58
+ resolve:(RCTPromiseResolveBlock)resolve
59
+ reject:(RCTPromiseRejectBlock)reject;
60
+
61
+ @end
package/ios/Rsa.mm ADDED
@@ -0,0 +1,216 @@
1
+ #import "Rsa.h"
2
+
3
+ // Import the auto-generated Swift bridging header
4
+ #if __has_include("react_native_rsa_turbo/react_native_rsa_turbo-Swift.h")
5
+ #import "react_native_rsa_turbo/react_native_rsa_turbo-Swift.h"
6
+ #elif __has_include("react-native-rsa-turbo/react_native_rsa_turbo-Swift.h")
7
+ #import "react-native-rsa-turbo/react_native_rsa_turbo-Swift.h"
8
+ #elif __has_include("Rsa-Swift.h")
9
+ #import "Rsa-Swift.h"
10
+ #else
11
+ // Fallback: forward declare Swift classes used by this file
12
+ @class RSAKeyGenerator;
13
+ @class RSACipher;
14
+ @class RSASigner;
15
+ #endif
16
+
17
+ /**
18
+ * Objective-C++ bridge between React Native TurboModule and Swift implementations.
19
+ *
20
+ * Each method dispatches to a background queue (QOS_CLASS_USER_INITIATED)
21
+ * and calls the corresponding Swift class method, then resolves/rejects
22
+ * the JS promise based on the result.
23
+ *
24
+ * Dispatches to:
25
+ * - RSAKeyGenerator: key generation, public key extraction, format conversion
26
+ * - RSACipher: encrypt, decrypt
27
+ * - RSASigner: sign, verify
28
+ */
29
+ @implementation Rsa
30
+
31
+ // MARK: - Key Generation
32
+
33
+ - (void)generateKeyPair:(double)keySize
34
+ format:(NSString *)format
35
+ resolve:(RCTPromiseResolveBlock)resolve
36
+ reject:(RCTPromiseRejectBlock)reject
37
+ {
38
+ dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{
39
+ NSError *error = nil;
40
+ RSAKeyGenerator *generator = [RSAKeyGenerator shared];
41
+
42
+ RSAKeyPairResult *result = [generator generateKeyPairWithKeySize:(int)keySize
43
+ format:format
44
+ error:&error];
45
+ if (error != nil) {
46
+ reject(@"RSAKeyGenerationError", error.localizedDescription, error);
47
+ return;
48
+ }
49
+
50
+ if (result == nil) {
51
+ reject(@"RSAKeyGenerationError", @"Unknown error during key generation", nil);
52
+ return;
53
+ }
54
+
55
+ NSDictionary *map = @{
56
+ @"publicKey": result.publicKey,
57
+ @"privateKey": result.privateKey
58
+ };
59
+ resolve(map);
60
+ });
61
+ }
62
+
63
+ - (void)getPublicKeyFromPrivate:(NSString *)privateKeyPEM
64
+ resolve:(RCTPromiseResolveBlock)resolve
65
+ reject:(RCTPromiseRejectBlock)reject
66
+ {
67
+ dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{
68
+ NSError *error = nil;
69
+ RSAKeyGenerator *generator = [RSAKeyGenerator shared];
70
+
71
+ NSString *publicKeyPEM = [generator getPublicKeyFromPrivateWithPrivateKeyPEM:privateKeyPEM
72
+ error:&error];
73
+ if (error != nil) {
74
+ reject(@"RSAKeyExtractionError", error.localizedDescription, error);
75
+ return;
76
+ }
77
+
78
+ resolve(publicKeyPEM);
79
+ });
80
+ }
81
+
82
+ // MARK: - Encrypt / Decrypt
83
+
84
+ - (void)encrypt:(NSString *)dataBase64
85
+ publicKeyPEM:(NSString *)publicKeyPEM
86
+ padding:(NSString *)padding
87
+ hash:(NSString *)hash
88
+ resolve:(RCTPromiseResolveBlock)resolve
89
+ reject:(RCTPromiseRejectBlock)reject
90
+ {
91
+ dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{
92
+ NSError *error = nil;
93
+ // RSACipher.encrypt is a static Swift method → class method in Obj-C
94
+ NSString *result = [RSACipher encryptWithDataBase64:dataBase64
95
+ publicKeyPEM:publicKeyPEM
96
+ padding:padding
97
+ hash:hash
98
+ error:&error];
99
+ if (error != nil) {
100
+ reject(@"RSAEncryptError", error.localizedDescription, error);
101
+ return;
102
+ }
103
+ resolve(result);
104
+ });
105
+ }
106
+
107
+ - (void)decrypt:(NSString *)dataBase64
108
+ privateKeyPEM:(NSString *)privateKeyPEM
109
+ padding:(NSString *)padding
110
+ hash:(NSString *)hash
111
+ resolve:(RCTPromiseResolveBlock)resolve
112
+ reject:(RCTPromiseRejectBlock)reject
113
+ {
114
+ dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{
115
+ NSError *error = nil;
116
+ NSString *result = [RSACipher decryptWithDataBase64:dataBase64
117
+ privateKeyPEM:privateKeyPEM
118
+ padding:padding
119
+ hash:hash
120
+ error:&error];
121
+ if (error != nil) {
122
+ reject(@"RSADecryptError", error.localizedDescription, error);
123
+ return;
124
+ }
125
+ resolve(result);
126
+ });
127
+ }
128
+
129
+ // MARK: - Sign / Verify
130
+
131
+ - (void)sign:(NSString *)dataBase64
132
+ privateKeyPEM:(NSString *)privateKeyPEM
133
+ padding:(NSString *)padding
134
+ hash:(NSString *)hash
135
+ resolve:(RCTPromiseResolveBlock)resolve
136
+ reject:(RCTPromiseRejectBlock)reject
137
+ {
138
+ dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{
139
+ NSError *error = nil;
140
+ NSString *result = [RSASigner signWithDataBase64:dataBase64
141
+ privateKeyPEM:privateKeyPEM
142
+ padding:padding
143
+ hash:hash
144
+ error:&error];
145
+ if (error != nil) {
146
+ reject(@"RSASignError", error.localizedDescription, error);
147
+ return;
148
+ }
149
+ resolve(result);
150
+ });
151
+ }
152
+
153
+ - (void)verify:(NSString *)dataBase64
154
+ signatureBase64:(NSString *)signatureBase64
155
+ publicKeyPEM:(NSString *)publicKeyPEM
156
+ padding:(NSString *)padding
157
+ hash:(NSString *)hash
158
+ resolve:(RCTPromiseResolveBlock)resolve
159
+ reject:(RCTPromiseRejectBlock)reject
160
+ {
161
+ dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{
162
+ NSError *error = nil;
163
+ // Swift `throws -> Bool` maps to Obj-C `(BOOL)...error:(NSError **)`.
164
+ // - YES + nil error = signature valid
165
+ // - NO + nil error = signature invalid (legitimate false)
166
+ // - NO + error set = actual error occurred
167
+ BOOL result = [RSASigner verifyWithDataBase64:dataBase64
168
+ signatureBase64:signatureBase64
169
+ publicKeyPEM:publicKeyPEM
170
+ padding:padding
171
+ hash:hash
172
+ error:&error];
173
+ if (error != nil) {
174
+ reject(@"RSAVerifyError", error.localizedDescription, error);
175
+ return;
176
+ }
177
+ resolve(@(result));
178
+ });
179
+ }
180
+
181
+ // MARK: - Key Format Conversion
182
+
183
+ - (void)convertPrivateKey:(NSString *)pem
184
+ targetFormat:(NSString *)targetFormat
185
+ resolve:(RCTPromiseResolveBlock)resolve
186
+ reject:(RCTPromiseRejectBlock)reject
187
+ {
188
+ dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{
189
+ NSError *error = nil;
190
+ RSAKeyGenerator *generator = [RSAKeyGenerator shared];
191
+
192
+ NSString *result = [generator convertPrivateKeyWithPem:pem
193
+ targetFormat:targetFormat
194
+ error:&error];
195
+ if (error != nil) {
196
+ reject(@"RSAConvertKeyError", error.localizedDescription, error);
197
+ return;
198
+ }
199
+ resolve(result);
200
+ });
201
+ }
202
+
203
+ // MARK: - TurboModule Registration
204
+
205
+ - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
206
+ (const facebook::react::ObjCTurboModule::InitParams &)params
207
+ {
208
+ return std::make_shared<facebook::react::NativeRsaSpecJSI>(params);
209
+ }
210
+
211
+ + (NSString *)moduleName
212
+ {
213
+ return @"Rsa";
214
+ }
215
+
216
+ @end
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+
3
+ import { TurboModuleRegistry } from 'react-native';
4
+
5
+ /**
6
+ * Native bridge specification for RSA operations.
7
+ *
8
+ * All methods use flat string parameters (no objects/arrays) because
9
+ * React Native's codegen works best with simple types across the bridge.
10
+ *
11
+ * Data is passed as base64 strings to avoid binary encoding issues.
12
+ * The JS layer (index.ts) handles defaults resolution and UTF-8→base64 encoding.
13
+ */
14
+
15
+ export default TurboModuleRegistry.getEnforcing('Rsa');
16
+ //# sourceMappingURL=NativeRsa.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeRsa.ts"],"mappings":";;AAAA,SAASA,mBAAmB,QAA0B,cAAc;;AAEpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAgDA,eAAeA,mBAAmB,CAACC,YAAY,CAAO,KAAK,CAAC","ignoreList":[]}
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * Default values for all RSA operation options.
5
+ *
6
+ * These are applied in `index.ts` when the caller omits an option.
7
+ * Keeping them in one place ensures consistency across encrypt, decrypt, sign, verify.
8
+ */
9
+ export const DEFAULTS = {
10
+ /** Default padding for encrypt/decrypt — OAEP is recommended over PKCS#1 */
11
+ ENCRYPTION_PADDING: 'oaep',
12
+ /** Default padding for sign/verify — PSS is recommended over PKCS#1 */
13
+ SIGNATURE_PADDING: 'pss',
14
+ /** Default hash algorithm */
15
+ HASH: 'sha256',
16
+ /** Default input string encoding — UTF-8 text is the common case */
17
+ ENCODING: 'utf8',
18
+ /** Default private key format for key generation */
19
+ KEY_FORMAT: 'pkcs1'
20
+ };
21
+
22
+ /** Supported RSA key sizes in bits */
23
+ export const VALID_KEY_SIZES = [1024, 2048, 4096];
24
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["DEFAULTS","ENCRYPTION_PADDING","SIGNATURE_PADDING","HASH","ENCODING","KEY_FORMAT","VALID_KEY_SIZES"],"sourceRoot":"../../src","sources":["constants.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMA,QAAQ,GAAG;EACtB;EACAC,kBAAkB,EAAE,MAAe;EAEnC;EACAC,iBAAiB,EAAE,KAAc;EAEjC;EACAC,IAAI,EAAE,QAAiB;EAEvB;EACAC,QAAQ,EAAE,MAAe;EAEzB;EACAC,UAAU,EAAE;AACd,CAAC;;AAED;AACA,OAAO,MAAMC,eAAe,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAU","ignoreList":[]}