@@ -9,8 +9,11 @@ import javax.crypto.spec.IvParameterSpec
99import java.security.*
1010import java.security.spec.PKCS8EncodedKeySpec
1111import java.security.spec.X509EncodedKeySpec
12+ import java.security.spec.RSAPublicKeySpec
13+
1214import android.util.Base64
1315import javax.crypto.Cipher
16+ import java.math.BigInteger
1417
1518import java.security.KeyFactory
1619import kotlinx.coroutines.*
@@ -211,7 +214,7 @@ override fun decryptFile(inputPath: String, key: String, promise: Promise) {
211214}
212215
213216 // -----------------------------------------
214- // 🔑 AES Key Generation
217+ // 🔑 RSA Key Generation
215218 // -----------------------------------------
216219
217220 /* *
@@ -221,33 +224,73 @@ override fun decryptFile(inputPath: String, key: String, promise: Promise) {
221224 * @throws Exception if key generation fails.
222225 */
223226 @Throws(Exception ::class )
224- override fun generateRSAKeyPair (): WritableMap {
225- return try {
226- // Generate RSA Key Pair
227- val keyPairGenerator = KeyPairGenerator .getInstance(" RSA" )
228- keyPairGenerator.initialize(2048 )
229- val keyPair = keyPairGenerator.genKeyPair()
230-
231- // Get keys and encode them as Base64
232- val publicKey = keyPair.public.encoded
233- val privateKey = keyPair.private.encoded
234-
235- val publicKeyBase64 = Base64 .encodeToString(publicKey, Base64 .DEFAULT )
236- val privateKeyBase64 = Base64 .encodeToString(privateKey, Base64 .DEFAULT )
237-
238- // Create WritableMap
239- val result: WritableMap = Arguments .createMap()
240- result.putString(" publicKey" , publicKeyBase64)
241- result.putString(" privateKey" , privateKeyBase64)
227+ override fun generateRSAKeyPair (): WritableMap {
228+ try {
229+ // Generate RSA Key Pair
230+ val keyPairGenerator = KeyPairGenerator .getInstance(" RSA" )
231+ keyPairGenerator.initialize(2048 )
232+ val keyPair: KeyPair = keyPairGenerator.genKeyPair()
233+
234+ // Extract Public and Private Key
235+ val publicKey = keyPair.public
236+ val privateKey = keyPair.private
237+
238+ // Encode Keys to Base64
239+ val publicKeyBytes = publicKey.encoded
240+ val privateKeyBytes = privateKey.encoded
241+
242+ val publicKeyBase64 = Base64 .encodeToString(publicKeyBytes, Base64 .DEFAULT )
243+ val privateKeyBase64 = Base64 .encodeToString(privateKeyBytes, Base64 .DEFAULT )
244+
245+ // Return as WritableMap
246+ val result: WritableMap = Arguments .createMap()
247+ result.putString(" publicKey" , publicKeyBase64)
248+ result.putString(" privateKey" , privateKeyBase64)
249+
250+ return result
251+ } catch (e: Exception ) {
252+ e.printStackTrace()
253+ throw Exception (" Failed to generate RSA key pair: ${e.localizedMessage} " )
254+ }
255+ }
242256
243- result
244- } catch (e: Exception ) {
245- e.printStackTrace()
246- val errorMap: WritableMap = Arguments .createMap()
247- errorMap.putString(" error" , " Failed to generate RSA key pair: ${e.localizedMessage} " )
248- errorMap
249- }
250- }
257+ /* *
258+ * Retrieve the Public Key from a given Private Key (Base64 Encoded)
259+ * @param privateKeyBase64 Base64-encoded RSA private key.
260+ * @return Base64-encoded RSA public key or null on failure.
261+ * @throws IllegalArgumentException if the key is invalid.
262+ * @throws Exception for general key-related errors.
263+ */
264+ @Throws(IllegalArgumentException ::class , Exception ::class )
265+ override fun getPublicRSAkey (privateKeyBase64 : String ): String {
266+ try {
267+ // Decode the Base64-encoded private key
268+ val privateKeyBytes = Base64 .decode(privateKeyBase64, Base64 .DEFAULT )
269+ val keySpec = PKCS8EncodedKeySpec (privateKeyBytes)
270+ val keyFactory = KeyFactory .getInstance(" RSA" )
271+
272+ // Generate PrivateKey object
273+ val privateKey: PrivateKey = keyFactory.generatePrivate(keySpec)
274+ val rsaPrivateKey = privateKey as java.security.interfaces.RSAPrivateKey
275+
276+ // Extract Modulus and Public Exponent
277+ val modulus: BigInteger = rsaPrivateKey.modulus
278+ val publicExponent: BigInteger = BigInteger .valueOf(65537 ) // Common RSA exponent
279+
280+ // Generate PublicKey from Modulus and Public Exponent
281+ val publicKeySpec = RSAPublicKeySpec (modulus, publicExponent)
282+ val publicKey: PublicKey = keyFactory.generatePublic(publicKeySpec)
283+
284+ // Encode PublicKey to Base64
285+ val publicKeyBase64 = Base64 .encodeToString(publicKey.encoded, Base64 .DEFAULT )
286+ return publicKeyBase64
287+
288+ } catch (e: IllegalArgumentException ) {
289+ throw IllegalArgumentException (" Invalid private key format: ${e.localizedMessage} " )
290+ } catch (e: Exception ) {
291+ throw Exception (" Failed to extract public key: ${e.localizedMessage} " )
292+ }
293+ }
251294
252295 // -----------------------------------------
253296 // 🔒 RSA Encryption
@@ -394,9 +437,19 @@ override fun decryptFile(inputPath: String, key: String, promise: Promise) {
394437 }
395438
396439 // -----------------------------------------
397- // 📝 HMAC-SHA256
440+ // 📝 HMAC-SHA256/512
398441 // -----------------------------------------
399442
443+ /* *
444+ * Generate HMAC Key for SHA-256 or SHA-512.
445+ * @param keySize Size of the key in bits (256 or 512).
446+ * @return Base64-encoded HMAC key.
447+ * @throws IllegalArgumentException If the key size is invalid.
448+ */
449+ @Throws(IllegalArgumentException ::class )
450+ override fun generateHMACKey (keySize : Double ): String {
451+ return HashingUtils .generateHMACKey(keySize)
452+ }
400453 /* *
401454 * Hashes data using hmac SHA-256.
402455 *
@@ -410,6 +463,20 @@ override fun decryptFile(inputPath: String, key: String, promise: Promise) {
410463 return HashingUtils .hmacSHA256(data, key)
411464 }
412465
466+ /* *
467+ * Hashes data using hmac SHA-512.
468+ *
469+ * @param data The input string to hash.
470+ * @param key The input key to be used for hash.
471+ * @return A hex-encoded hmac SHA-256 hash.
472+ * @throws Exception if hashing fails.
473+ */
474+ @Throws(Exception ::class )
475+ override fun hmacSHA512 (data : String , key : String ): String {
476+ return HashingUtils .hmacSHA512(data, key)
477+ }
478+
479+
413480 // -----------------------------------------
414481 // 🎲 Random String Generation
415482 // -----------------------------------------
@@ -465,6 +532,12 @@ override fun decryptFile(inputPath: String, key: String, promise: Promise) {
465532 return SignatureUtils .generateECDSAKeyPair()
466533 }
467534
535+ @Throws(Exception ::class )
536+ override fun getPublicECDSAKey (privateKeyBase64 : String ): String {
537+ return SignatureUtils .getPublicECDSAKey(privateKeyBase64)
538+ }
539+
540+
468541 /* *
469542 * Signs a given string using ECDSA (Elliptic Curve Digital Signature Algorithm).
470543 *
0 commit comments