Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/sentryco/e2ee

Encrypt communication with E2EE
https://github.com/sentryco/e2ee

Last synced: about 1 month ago
JSON representation

Encrypt communication with E2EE

Awesome Lists containing this project

README

        

[![Tests](https://github.com/sentryco/E2EE/actions/workflows/Tests.yml/badge.svg)](https://github.com/sentryco/E2EE/actions/workflows/Tests.yml)
[![codebeat badge](https://codebeat.co/badges/ed625f6f-4a9d-41fd-9062-0125b74daf67)](https://codebeat.co/projects/github-com-sentryco-e2ee-main)

# E2EE

> Encrypt communication with E2EE

## Description
E2EE is a system that ensures only the communicating users can read the messages. In principle, it prevents potential eavesdroppers – including telecom providers, Internet providers, and even the provider of the communication service – from being able to access the cryptographic keys needed to decrypt the conversation.

## Problem:

1. **Secure Message Encryption**: Ensuring only intended recipients can read messages.

2. **Secure Key Management**: Safely generating and storing cryptographic keys.

3. **Secure Confirmation Code Exchange**: Securely exchanging confirmation codes to verify identities.

## Solution:

1. **End-to-End Encryption**: Encrypts messages using the recipient's public key and sender's private key, ensuring only the intended recipient can decrypt them.

2. **Secure Key Storage**: Stores private keys locally in the device's secure enclave and keychain to protect against unauthorized access.

3. **Encrypted Confirmation Codes**: Generates and encrypts ephemeral confirmation codes with unique salts for secure identity verification and enhanced attack resistance.

## Features
- 🔐 **Local Keychain in Secure Enclave**: The private key is stored in the local keychain, which is a secure enclave that provides cryptographic operations and secure storage.
- 🧂 **Different Salts**: E2EE uses different salts for different communication types, including "share", "sync", and "confirm".
- 🔑 **Priv/Public Key Shared Key**: The system uses a shared key that is derived from the private and public keys.
- ⏳ **Ephemeral Share-Code**: E2EE creates a temporary share-code that is used in the setup of the E2EE handshake.

## Example:

The following Swift code demonstrates how to use the E2EE (End-to-End Encryption) system to securely encrypt and decrypt a message. This example shows how to generate or retrieve a key pair, encrypt a message using a public key, and decrypt the message using the corresponding private key.

> **Important**: Both parties must use the same salt value for encryption and decryption to succeed.

```swift
do {
// Generate or retrieve the key pair
let keyPair = try E2EE.keyPair(key: "myKey", service: "myService")

// The message to encrypt
let message = "Hello, world!"

// Assume you have a public key string from a remote peer
let remotePubKeyStr = try Cipher.exportPubKey(pubKey: keyPair.pub)

// Encrypt the message using the remote public key and your private key
let encryptedMessage = try E2EE.getEncryptedCode(
code: message,
pubKey: remotePubKeyStr,
privKey: keyPair.priv,
confirmCodeSalt: Cipher.defaultSalt
)

// Decrypt the message using your private key and the remote public key
let decryptedMessage = try E2EE.getDecryptedCode(
code: encryptedMessage,
pubKey: remotePubKeyStr,
privKey: keyPair.priv,
confirmCodeSalt: Cipher.defaultSalt
)

print("Decrypted message: \(decryptedMessage)")
} catch {
print("An error occurred: \(error)")
}
```

### Example: Encrypting and Decrypting Between Two Users

In this example, we'll simulate secure communication between two users, Alice and Bob. Each user will generate their own key pair. Alice will encrypt a message using Bob's public key and her private key. Bob will then decrypt the message using Alice's public key and his private key.

```swift
do {
// Alice generates her key pair
let aliceKeyPair = try Cipher.getKeyPair()
let alicePubKeyStr = try Cipher.exportPubKey(pubKey: aliceKeyPair.pub)

// Bob generates his key pair
let bobKeyPair = try Cipher.getKeyPair()
let bobPubKeyStr = try Cipher.exportPubKey(pubKey: bobKeyPair.pub)

// Alice's message to Bob
let messageFromAlice = "Hello Bob, this is a secret message!"

// Alice encrypts the message using Bob's public key and her private key
let encryptedMessage = try E2EE.getEncryptedCode(
code: messageFromAlice,
pubKey: bobPubKeyStr, // Bob's public key
privKey: aliceKeyPair.priv, // Alice's private key
confirmCodeSalt: Cipher.defaultSalt
)

// Alice sends `encryptedMessage` and `alicePubKeyStr` to Bob

// Bob receives the message and decrypts it using Alice's public key and his private key
let decryptedMessage = try E2EE.getDecryptedCode(
code: encryptedMessage,
pubKey: alicePubKeyStr, // Alice's public key
privKey: bobKeyPair.priv, // Bob's private key
confirmCodeSalt: Cipher.defaultSalt
)

print("Bob received message: \(decryptedMessage)")
// Output: Bob received message: Hello Bob, this is a secret message!
} catch {
print("An error occurred: \(error)")
}
```

### Explanation

- **Key Generation**: Both Alice and Bob generate their own key pairs using `Cipher.getKeyPair()`.
- **Public Key Exchange**: Alice and Bob exchange public keys. In this example, they share `alicePubKeyStr` and `bobPubKeyStr`.
- **Encryption**:
- **Alice** encrypts the message using Bob's public key (`bobPubKeyStr`) and her private key (`aliceKeyPair.priv`).
- The `E2EE.getEncryptedCode` function combines these keys and the message to produce `encryptedMessage`.
- **Decryption**:
- **Bob** decrypts the message using Alice's public key (`alicePubKeyStr`) and his private key (`bobKeyPair.priv`).
- The `E2EE.getDecryptedCode` function uses these keys to decrypt and retrieve the original message.

### Notes

- **Secure Communication**: This method ensures that only Bob can decrypt the message sent by Alice, as it requires Bob's private key and Alice's public key.
- **Key Pairs**: Each user must keep their private key secure and share their public key with the communicating party.
- **Salt Usage**: The `confirmCodeSalt` is used in the encryption and decryption process to add an extra layer of security.

### Example: Generating and Encrypting a Confirmation Code

In scenarios where you need to generate a confirmation code and send it securely, you can use the `E2EE` methods to encrypt and decrypt the code.

```swift
do {
// Generate a key pair for your application
let keyPair = try E2EE.getKeyPair(keyName: "myKey", service: "myService")
let pubKeyStr = try Cipher.exportPubKey(pubKey: keyPair.pub)

// Assume you have received the remote peer's public key as `remotePubKeyStr`

// Generate a random 4-digit confirmation code
let confirmCode = try RandPSW.makeRandomWord(
recipe: .init(
charCount: 0, // No letters
numCount: 4, // Four numbers
symCount: 0 // No symbols
)
)
print("Original Confirmation Code: \(confirmCode)")
// Output: Original Confirmation Code: 1234 (example)

// Encrypt the confirmation code using the remote peer's public key and your private key
let encryptedConfirmCode = try E2EE.getEncryptedCode(
code: confirmCode,
pubKey: remotePubKeyStr, // Remote peer's public key
privKey: keyPair.priv, // Your private key
confirmCodeSalt: Cipher.defaultSalt
)

// Send `encryptedConfirmCode` to the remote peer

// The remote peer can decrypt the confirmation code using your public key and their private key
// They would use `E2EE.getDecryptedCode` with `pubKey` being your `pubKeyStr` and their own private key

print("Encrypted Confirmation Code: \(encryptedConfirmCode)")
// Output: Encrypted Confirmation Code: (encrypted string)
} catch {
print("An error occurred: \(error)")
}
```

### Explanation

- **Confirmation Code Generation**: A random 4-digit code is generated using `RandPSW.makeRandomWord`.
- **Encryption**:
- You encrypt the confirmation code using the remote peer's public key and your private key.
- **Decryption**:
- The remote peer decrypts the code using your public key and their private key.
- **Usage**: This is useful in scenarios where you need to confirm the identity of the remote peer securely.

### Notes

- **Random Password Generator**: `RandPSW` is used to generate a secure random code.
- **Secure Exchange**: Always ensure that public keys are exchanged securely to prevent man-in-the-middle attacks.
- **Error Handling**: Proper error handling is essential to catch and handle exceptions that may occur during key generation, encryption, or decryption.

## Todo:
- Add a more detailed introduction about E2EE and its importance.
- Explain the terms used in the description section for better understanding.
- Include a section about how to install or use the E2EE in a project.
- Add error handling and what each error might mean.
- Error Handling with Result Type