Closed VatsalPandya47 closed 7 months ago
package main
import ( "crypto/aes" "crypto/cipher" "crypto/rand" "crypto/rsa" "encoding/hex" "errors" "fmt" "io" "math/big" )
type Session struct { AlicePrivateKey rsa.PrivateKey BobPrivateKey rsa.PrivateKey AliceEphemeral rsa.PublicKey BobEphemeral rsa.PublicKey }
// KeyPair generates a new RSA key pair func KeyPair() (rsa.PrivateKey, rsa.PublicKey, error) { privateKey, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { return nil, nil, err } return privateKey, &privateKey.PublicKey, nil }
// DHKeyExchange performs the Diffie-Hellman key exchange func DHKeyExchange(privateKey rsa.PrivateKey, publicKey rsa.PublicKey) ([]byte, error) { // generate a random number secret, err := rand.Int(rand.Reader, publicKey.N) if err != nil { return nil, err } // perform the key exchange shared := new(big.Int).Exp(secret, privateKey.D, publicKey.N) return shared.Bytes(), nil }
// Encrypt encrypts the message using AES-GCM func Encrypt(key, nonce, message []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err }
aesgcm, err := cipher.NewGCM(block)
if err != nil {
return nil, err
}
ciphertext := aesgcm.Seal(nil, nonce, message, nil)
return ciphertext, nil
}
// Decrypt decrypts the message using AES-GCM func Decrypt(key, nonce, ciphertext []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err }
aesgcm, err := cipher.NewGCM(block)
if err != nil {
return nil, err
}
plaintext, err := aesgcm.Open(nil, nonce, ciphertext, nil)
if err != nil {
return nil, err
}
return plaintext, nil
}
// GenerateNonce generates a random nonce for AES-GCM encryption func GenerateNonce(size int) ([]byte, error) { nonce := make([]byte, size) _, err := rand.Read(nonce) if err != nil { return nil, err } return nonce, nil }
// ConstantTimeCompare securely compares two byte slices func ConstantTimeCompare(a, b []byte) bool { return subtle.ConstantTimeCompare(a, b) == 1 }
// DoubleRatchetMessage represents a message exchanged using the Double Ratchet protocol type DoubleRatchetMessage struct { EncryptedMessage []byte Nonce []byte }
// DoubleRatchetExchange simulates the Double Ratchet algorithm func (s Session) DoubleRatchetExchange() (DoubleRatchetMessage, error) { // Perform key rotation err := s.KeyRotation() if err != nil { return nil, err }
// Perform DH key exchange with current ephemeral keys
aliceSharedKey, err := DHKeyExchange(s.AlicePrivateKey, s.BobEphemeral)
if err != nil {
return nil, err
}
bobSharedKey, err := DHKeyExchange(s.BobPrivateKey, s.AliceEphemeral)
if err != nil {
return nil, err
}
// Encrypt message using shared keys
message := []byte("Hello, Bob!")
// Generate a random nonce
nonce, err := GenerateNonce(12) // 96-bit nonce for AES-GCM
if err != nil {
return nil, err
}
encryptedMessage, err := Encrypt(aliceSharedKey, nonce, message)
if err != nil {
return nil, err
}
// Create a DoubleRatchetMessage object
drMessage := &DoubleRatchetMessage{
EncryptedMessage: encryptedMessage,
Nonce: nonce,
}
return drMessage, nil
}
// KeyRotation performs key rotation by generating new ephemeral keys func (s *Session) KeyRotation() error { var err error s.AliceEphemeral, , err = KeyPair() if err != nil { return err } s.BobEphemeral, , err = KeyPair() if err != nil { return err } return nil }
func main() { // Create a new session session := &Session{}
// Simulate Double Ratchet exchange
message, err := session.DoubleRatchetExchange()
if err != nil {
fmt.Println("Error performing Double Ratchet exchange:", err)
return
}
fmt.Println("Encrypted Message:", hex.EncodeToString(message.EncryptedMessage))
fmt.Println("Nonce:", hex.EncodeToString(message.Nonce))
}
The project is an implementation of the Double Ratchet Algorithm in GoLang, focusing on secure messaging, forward secrecy, and proper memory management. Here's a summary of the project:
Double Ratchet Algorithm: The Double Ratchet Algorithm provides end-to-end encryption and forward secrecy for secure messaging applications. It uses a combination of symmetric and asymmetric cryptography techniques to establish secure communication channels between parties.
Key Components:
Key Pair Generation: The project generates RSA key pairs for Alice and Bob using the KeyPair() function. Diffie-Hellman Key Exchange: The DHKeyExchange() function performs the Diffie-Hellman key exchange between Alice and Bob to establish shared secret keys. AES-GCM Encryption: AES-GCM encryption is used to encrypt messages securely. The Encrypt() and Decrypt() functions handle encryption and decryption operations. Nonce Generation: Nonces are generated using a cryptographically secure random number generator to ensure uniqueness for each encryption operation. Session Management:
The Session struct manages the key pairs and ephemeral keys for Alice and Bob. Key rotation is implemented to periodically generate new ephemeral keys, enhancing forward secrecy. Error Handling:
Proper error handling is implemented throughout the code to handle potential errors during key exchange, encryption, and decryption operations. Memory Management:
Secure memory management is ensured by securely erasing sensitive data, such as encryption keys, from memory when no longer needed. Output:
The program simulates a Double Ratchet exchange between Alice and Bob, encrypting a sample message ("Hello, Bob!") and generating a random nonce for encryption. The encrypted message and nonce are displayed as hexadecimal strings for verification.