@functionland/react-native-fula 1.2.2 → 1.2.4

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.
@@ -1,47 +1,60 @@
1
- package land.fx.fula;
2
-
3
- import android.util.Base64;
4
-
5
- import java.io.UnsupportedEncodingException;
6
- import java.security.InvalidAlgorithmParameterException;
7
- import java.security.InvalidKeyException;
8
- import java.security.NoSuchAlgorithmException;
9
- import java.security.spec.InvalidKeySpecException;
10
- import java.security.spec.InvalidParameterSpecException;
11
-
12
- import javax.crypto.BadPaddingException;
13
- import javax.crypto.Cipher;
14
- import javax.crypto.IllegalBlockSizeException;
15
- import javax.crypto.NoSuchPaddingException;
16
- import javax.crypto.SecretKey;
17
- import javax.crypto.SecretKeyFactory;
18
- import javax.crypto.spec.PBEKeySpec;
19
- import javax.crypto.spec.SecretKeySpec;
20
-
21
- public class Cryptography {
22
- public static String encryptMsg(String message, SecretKey secret)
23
- throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidParameterSpecException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
24
- Cipher cipher = null;
25
- cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
26
- cipher.init(Cipher.ENCRYPT_MODE, secret);
27
- byte[] cipherText = cipher.doFinal(message.getBytes("UTF-8"));
28
- return Base64.encodeToString(cipherText, Base64.NO_WRAP);
29
- }
30
-
31
- public static String decryptMsg(String cipherText, SecretKey secret)
32
- throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidParameterSpecException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException {
33
- Cipher cipher = null;
34
- cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
35
- cipher.init(Cipher.DECRYPT_MODE, secret);
36
- byte[] decode = Base64.decode(cipherText, Base64.NO_WRAP);
37
- String decryptString = new String(cipher.doFinal(decode), "UTF-8");
38
- return decryptString;
39
- }
40
-
41
- public static SecretKey generateKey(byte[] key)
42
- throws NoSuchAlgorithmException, InvalidKeySpecException {
43
- PBEKeySpec pbeKeySpec = new PBEKeySpec(StaticHelper.bytesToBase64(key).toCharArray(), key, 1000, 128);
44
- SecretKey pbeKey = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256").generateSecret(pbeKeySpec);
45
- return new SecretKeySpec(pbeKey.getEncoded(), "AES");
46
- }
47
- }
1
+ package land.fx.fula;
2
+
3
+ import android.util.Base64;
4
+
5
+ import java.io.UnsupportedEncodingException;
6
+ import java.nio.charset.StandardCharsets;
7
+ import java.security.InvalidAlgorithmParameterException;
8
+ import java.security.InvalidKeyException;
9
+ import java.security.NoSuchAlgorithmException;
10
+ import java.security.spec.InvalidKeySpecException;
11
+ import java.security.SecureRandom;
12
+ import java.nio.ByteBuffer;
13
+ import java.security.spec.InvalidParameterSpecException;
14
+
15
+ import javax.crypto.BadPaddingException;
16
+ import javax.crypto.Cipher;
17
+ import javax.crypto.IllegalBlockSizeException;
18
+ import javax.crypto.NoSuchPaddingException;
19
+ import javax.crypto.SecretKey;
20
+ import javax.crypto.SecretKeyFactory;
21
+ import javax.crypto.spec.PBEKeySpec;
22
+ import javax.crypto.spec.SecretKeySpec;
23
+ import javax.crypto.spec.GCMParameterSpec;
24
+
25
+ public class Cryptography {
26
+ public static String encryptMsg(String message, SecretKey secret)
27
+ throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException {
28
+ Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
29
+ byte[] iv = new byte[12]; // Ensure this is randomly generated for each encryption.
30
+ new SecureRandom().nextBytes(iv);
31
+ GCMParameterSpec spec = new GCMParameterSpec(128, iv);
32
+ cipher.init(Cipher.ENCRYPT_MODE, secret, spec);
33
+ byte[] cipherText = cipher.doFinal(message.getBytes(StandardCharsets.UTF_8));
34
+ ByteBuffer byteBuffer = ByteBuffer.allocate(iv.length + cipherText.length);
35
+ byteBuffer.put(iv);
36
+ byteBuffer.put(cipherText);
37
+ return Base64.encodeToString(byteBuffer.array(), Base64.NO_WRAP);
38
+ }
39
+
40
+ public static String decryptMsg(String cipherText, SecretKey secret)
41
+ throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
42
+ ByteBuffer byteBuffer = ByteBuffer.wrap(Base64.decode(cipherText, Base64.NO_WRAP));
43
+ byte[] iv = new byte[12];
44
+ byteBuffer.get(iv);
45
+ byte[] cipherBytes = new byte[byteBuffer.remaining()];
46
+ byteBuffer.get(cipherBytes);
47
+ Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
48
+ GCMParameterSpec spec = new GCMParameterSpec(128, iv);
49
+ cipher.init(Cipher.DECRYPT_MODE, secret, spec);
50
+ String decryptString = new String(cipher.doFinal(cipherBytes), StandardCharsets.UTF_8);
51
+ return decryptString;
52
+ }
53
+
54
+ public static SecretKey generateKey(byte[] key)
55
+ throws NoSuchAlgorithmException, InvalidKeySpecException {
56
+ PBEKeySpec pbeKeySpec = new PBEKeySpec(StaticHelper.bytesToBase64(key).toCharArray(), key, 1000, 128);
57
+ SecretKey pbeKey = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256").generateSecret(pbeKeySpec);
58
+ return new SecretKeySpec(pbeKey.getEncoded(), "AES");
59
+ }
60
+ }
@@ -16,9 +16,17 @@ import org.apache.commons.io.FileUtils;
16
16
  import org.jetbrains.annotations.Contract;
17
17
 
18
18
  import java.io.File;
19
+ import java.io.IOException;
19
20
  import java.nio.charset.StandardCharsets;
21
+ import java.security.GeneralSecurityException;
22
+ import java.security.InvalidAlgorithmParameterException;
23
+ import java.security.InvalidKeyException;
24
+ import java.security.NoSuchAlgorithmException;
20
25
  import java.util.Arrays;
21
26
 
27
+ import javax.crypto.BadPaddingException;
28
+ import javax.crypto.IllegalBlockSizeException;
29
+ import javax.crypto.NoSuchPaddingException;
22
30
  import javax.crypto.SecretKey;
23
31
 
24
32
  import java.util.concurrent.Executors;
@@ -414,24 +422,32 @@ public class FulaModule extends ReactContextBaseJavaModule {
414
422
  }
415
423
 
416
424
  @NonNull
417
- private byte[] createPeerIdentity(byte[] privateKey) throws Exception {
425
+ private byte[] createPeerIdentity(byte[] privateKey) throws GeneralSecurityException, IOException {
418
426
  try {
419
427
  // 1: First: create public key from provided private key
420
428
  // 2: Should read the local keychain store (if it is key-value, key is public key above,
421
429
  // 3: if found, decrypt using the private key
422
430
  // 4: If not found or decryption not successful, generate an identity
423
431
  // 5: then encrypt and store in keychain
424
-
425
432
  String encryptedKey = sharedPref.getValue(PRIVATE_KEY_STORE_ID);
426
433
  SecretKey secretKey = Cryptography.generateKey(privateKey);
427
- if (encryptedKey == null) {
428
- byte[] autoGeneratedIdentity = Fulamobile.generateEd25519Key();
429
- encryptedKey = Cryptography.encryptMsg(StaticHelper.bytesToBase64(autoGeneratedIdentity), secretKey);
434
+
435
+ if (encryptedKey == null || !encryptedKey.startsWith("FULA_ENC_V2:")) {
436
+ byte[] autoGeneratedIdentity;
437
+ try {
438
+ autoGeneratedIdentity = Fulamobile.generateEd25519Key();
439
+ } catch (Exception e) {
440
+ Log.d("ReactNative", "Failed to generate key: " + e.getMessage());
441
+ throw new GeneralSecurityException("Failed to generate key", e);
442
+ }
443
+ encryptedKey = "FULA_ENC_V2:" + Cryptography.encryptMsg(StaticHelper.bytesToBase64(autoGeneratedIdentity), secretKey);
430
444
  sharedPref.add(PRIVATE_KEY_STORE_ID, encryptedKey);
431
445
  }
432
- return StaticHelper.base64ToBytes(Cryptography.decryptMsg(encryptedKey, secretKey));
433
446
 
434
- } catch (Exception e) {
447
+ String decryptedKey = Cryptography.decryptMsg(encryptedKey.replace("FULA_ENC_V2:", ""), secretKey);
448
+ return StaticHelper.base64ToBytes(decryptedKey);
449
+
450
+ } catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException | InvalidAlgorithmParameterException e) {
435
451
  Log.d("ReactNative", "createPeerIdentity failed with Error: " + e.getMessage());
436
452
  throw (e);
437
453
  }
@@ -462,8 +478,8 @@ public class FulaModule extends ReactContextBaseJavaModule {
462
478
  String cid_encrypted = Cryptography.encryptMsg(this.rootConfig.getCid(), this.secretKeyGlobal);
463
479
  String private_ref_encrypted = Cryptography.encryptMsg(this.rootConfig.getPrivate_ref(), this.secretKeyGlobal);
464
480
 
465
- sharedPref.add("cid_encrypted_" + this.identityEncryptedGlobal, cid_encrypted);
466
- sharedPref.add("private_ref_encrypted_" + this.identityEncryptedGlobal, private_ref_encrypted);
481
+ sharedPref.add("FULA_ENC_V2:cid_encrypted_" + this.identityEncryptedGlobal, cid_encrypted);
482
+ sharedPref.add("FULA_ENC_V2:private_ref_encrypted_" + this.identityEncryptedGlobal, private_ref_encrypted);
467
483
  return true;
468
484
  } else {
469
485
  return false;
@@ -481,13 +497,13 @@ public class FulaModule extends ReactContextBaseJavaModule {
481
497
  }
482
498
  SecretKey secretKey = Cryptography.generateKey(identity);
483
499
  String identity_encrypted = Cryptography.encryptMsg(Arrays.toString(identity), secretKey);
484
- sharedPref.remove("cid_encrypted_"+ identity_encrypted);
485
- sharedPref.remove("private_ref_encrypted_"+identity_encrypted);
500
+ sharedPref.remove("FULA_ENC_V2:cid_encrypted_"+ identity_encrypted);
501
+ sharedPref.remove("FULA_ENC_V2:private_ref_encrypted_"+identity_encrypted);
486
502
 
487
503
  //TODO: Should also remove peerid @Mahdi
488
504
 
489
- sharedPref.remove("cid_encrypted_"+ identity_encrypted);
490
- sharedPref.remove("private_ref_encrypted_"+ identity_encrypted);
505
+ sharedPref.remove("FULA_ENC_V2:cid_encrypted_"+ identity_encrypted);
506
+ sharedPref.remove("FULA_ENC_V2:private_ref_encrypted_"+ identity_encrypted);
491
507
 
492
508
  this.rootConfig = null;
493
509
  this.secretKeyGlobal = null;
@@ -512,7 +528,8 @@ public class FulaModule extends ReactContextBaseJavaModule {
512
528
  }
513
529
 
514
530
  @NonNull
515
- private byte[] newClientInternal(byte[] identity, String storePath, String bloxAddr, String exchange, boolean autoFlush, boolean useRelay, boolean refresh) throws Exception {
531
+ private byte[] newClientInternal(byte[] identity, String storePath, String bloxAddr, String exchange, boolean autoFlush, boolean useRelay, boolean refresh) throws GeneralSecurityException, IOException {
532
+ byte[] peerIdentity = null;
516
533
  try {
517
534
  fulaConfig = new Config();
518
535
  if (storePath == null || storePath.trim().isEmpty()) {
@@ -522,7 +539,7 @@ public class FulaModule extends ReactContextBaseJavaModule {
522
539
  }
523
540
  Log.d("ReactNative", "newClientInternal storePath is set: " + fulaConfig.getStorePath());
524
541
 
525
- byte[] peerIdentity = this.createPeerIdentity(identity);
542
+ peerIdentity = this.createPeerIdentity(identity);
526
543
  fulaConfig.setIdentity(peerIdentity);
527
544
  Log.d("ReactNative", "peerIdentity is set: " + toString(fulaConfig.getIdentity()));
528
545
  fulaConfig.setBloxAddr(bloxAddr);
@@ -535,19 +552,25 @@ public class FulaModule extends ReactContextBaseJavaModule {
535
552
  }
536
553
  if (this.fula == null || refresh) {
537
554
  Log.d("ReactNative", "Creating a new Fula instance");
538
- shutdownInternal();
539
- this.fula = Fulamobile.newClient(fulaConfig);
540
- }
541
- if (this.fula != null) {
542
- this.fula.flush();
555
+ try {
556
+ shutdownInternal();
557
+ this.fula = Fulamobile.newClient(fulaConfig);
558
+ if (this.fula != null) {
559
+ this.fula.flush();
560
+ }
561
+ } catch (Exception e) {
562
+ Log.d("ReactNative", "Failed to create new Fula instance: " + e.getMessage());
563
+ throw new IOException("Failed to create new Fula instance", e);
564
+ }
543
565
  }
544
- return peerIdentity;
545
- } catch (Exception e) {
566
+ } catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException | InvalidAlgorithmParameterException e) {
546
567
  Log.d("ReactNative", "newclientInternal failed with Error: " + e.getMessage());
547
568
  throw (e);
548
569
  }
570
+ return peerIdentity;
549
571
  }
550
572
 
573
+
551
574
  @NonNull
552
575
  private String[] initInternal(byte[] identity, String storePath, String bloxAddr, String exchange, boolean autoFlush, String rootCid, boolean useRelay, boolean refresh) throws Exception {
553
576
  try {
@@ -568,8 +591,8 @@ public class FulaModule extends ReactContextBaseJavaModule {
568
591
  Log.d("ReactNative", "this.rootCid is empty.");
569
592
  //Load from keystore
570
593
 
571
- String cid_encrypted_fetched = sharedPref.getValue("cid_encrypted_"+ identity_encrypted);
572
- String private_ref_encrypted_fetched = sharedPref.getValue("private_ref_encrypted_"+identity_encrypted);
594
+ String cid_encrypted_fetched = sharedPref.getValue("FULA_ENC_V2:cid_encrypted_"+ identity_encrypted);
595
+ String private_ref_encrypted_fetched = sharedPref.getValue("FULA_ENC_V2:private_ref_encrypted_"+identity_encrypted);
573
596
  Log.d("ReactNative", "Here1");
574
597
  String cid = "";
575
598
  String private_ref = "";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@functionland/react-native-fula",
3
- "version": "1.2.2",
3
+ "version": "1.2.4",
4
4
  "description": "This package is a bridge to use the Fula libp2p protocols in the react-native which is using wnfs",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",