MixinNetwork / libsignal_protocol_dart

Signal Protocol library for Dart/Flutter
https://pub.dev/packages/libsignal_protocol_dart
GNU General Public License v3.0
159 stars 42 forks source link

How can i decrypt our message after encrypt to cipherText. #80

Open happyboys01234567 opened 8 months ago

happyboys01234567 commented 8 months ago

Hi @crossle @Tougee @abhay-s-rawat, Currently I have a problem when loading the cipherText and decrypting it to display in UI.
//TODO: how can I decrypt the ciphertext to plain text again using Bob session or any way without remoteSessionCipher?

test('testBasicEncryptDecrypt', () async {
  final identityKeyPair = generateIdentityKeyPair();
  final registrationId = generateRegistrationId(false);

  final preKeys = generatePreKeys(0, 110);

  final signedPreKey = generateSignedPreKey(identityKeyPair, 0);

  final sessionStore = InMemorySessionStore();
  final preKeyStore = InMemoryPreKeyStore();
  final signedPreKeyStore = InMemorySignedPreKeyStore();
  final identityStore =
      InMemoryIdentityKeyStore(identityKeyPair, registrationId);

  for (final p in preKeys) {
    await preKeyStore.storePreKey(p.id, p);
  }
  await signedPreKeyStore.storeSignedPreKey(signedPreKey.id, signedPreKey);

  const bobAddress = SignalProtocolAddress('bob', 1);
  final sessionBuilder = SessionBuilder(
      sessionStore, preKeyStore, signedPreKeyStore, identityStore, bobAddress);

  // Should get remote from the server
  final remoteRegId = generateRegistrationId(false);
  final remoteIdentityKeyPair = generateIdentityKeyPair();
  final remotePreKeys = generatePreKeys(0, 110);
  final remoteSignedPreKey = generateSignedPreKey(remoteIdentityKeyPair, 0);

  final retrievedPreKey = PreKeyBundle(
      remoteRegId,
      1,
      remotePreKeys[0].id,
      remotePreKeys[0].getKeyPair().publicKey,
      remoteSignedPreKey.id,
      remoteSignedPreKey.getKeyPair().publicKey,
      remoteSignedPreKey.signature,
      remoteIdentityKeyPair.getPublicKey());

  await sessionBuilder.processPreKeyBundle(retrievedPreKey);

  final sessionCipher = SessionCipher(
      sessionStore, preKeyStore, signedPreKeyStore, identityStore, bobAddress);
  final ciphertext = await sessionCipher
      .encrypt(Uint8List.fromList(utf8.encode('Hello Mixin🤣')));
   print(ciphertext);
   // Store the ciphertext to the local database.

  //TODO: how can I decrypt the ciphertext to plain text again using Bob session or any way without remoteSessionCipher?

final signalProtocolStore =
      InMemorySignalProtocolStore(remoteIdentityKeyPair, 1);
  const aliceAddress = SignalProtocolAddress('alice', 1);
  final remoteSessionCipher =
      SessionCipher.fromStore(signalProtocolStore, aliceAddress);

  for (final p in remotePreKeys) {
    await signalProtocolStore.storePreKey(p.id, p);
  }
  await signalProtocolStore.storeSignedPreKey(
      remoteSignedPreKey.id, remoteSignedPreKey);

  if (ciphertext.getType() == CiphertextMessage.prekeyType) {
    await remoteSessionCipher
        .decryptWithCallback(ciphertext as PreKeySignalMessage, (plaintext) {
      // ignore: avoid_print
      print(utf8.decode(plaintext));
    });
  }
  });
Tougee commented 8 months ago

AFAIK there is no way you can do this.

happyboys01234567 commented 8 months ago

Thanks @Tougee for letting me know this, that's weird, I thought that we would have a way to decrypt it back again to plain text using the user's private key like Diffie–Hellman. I have more doubts, I guess you can easily help me make them clear.

1, How can I store the messages sent on the user's device? (which is the preferred option to store plain text or encrypt it using the user's public key) 2, How can I send a message to other devices using the same user account(1-1 and group conversation)? (I need to build a new Signal session like a new user and send messages to them, right? or any way to achieve it?) 3, Do you have any idea about transferring messages between 2 devices?

That's some concerns to get started using this library. I hope to hear back from you. Thank!

Tougee commented 8 months ago
  1. You can store plaintext (or some other encryption), use Signal-P encrypt it when it sent to user.
  2. GroupCipher can help with this, and you can see `group_cipher_test.dart'.
  3. Use a central server to distribute pre-keys and messages.