What Cryptographic Protocols Does Croc Use for Security?
Croc secures file transfers using PBKDF2‑SHA256 or Argon2‑id for key derivation, AES‑256‑GCM or ChaCha20‑Poly1305 for authenticated encryption, and SHA‑256 for integrity verification.
Croc is an open‑source command‑line tool that enables secure peer‑to‑peer file transfers without relying on third‑party infrastructure. Understanding what cryptographic protocols croc uses for security requires examining the implementation in src/crypt/crypt.go, where modern key‑derivation functions and Authenticated Encryption with Associated Data (AEAD) primitives are orchestrated to provide end‑to‑end confidentiality and tamper evidence.
Key Derivation Mechanisms
Croc supports two distinct computational paths for converting human‑readable passphrases into cryptographically strong keys.
PBKDF2 with SHA‑256
The default key‑derivation method employs PBKDF2 (Password‑Based Key Derivation Function 2) with SHA‑256. The New function in src/crypt/crypt.go (lines 16‑34) invokes pbkdf2.Key to stretch the user’s passphrase into a 32‑byte key suitable for AES‑256. This CPU‑hard approach increases the cost of brute‑force attacks by iterating the hash function thousands of times.
Argon2‑id Memory‑Hard KDF
For environments requiring defense against GPU or ASIC‑based cracking, croc exposes NewArgon2 (lines 76‑95). This function implements Argon2‑id, the winner of the Password Hashing Competition, to perform memory‑hard key derivation. It returns a ChaCha20‑Poly1305 AEAD instance initialized with the derived key, providing resistance to hardware‑accelerated attacks through large memory consumption.
Authenticated Encryption Primitives
After key derivation, croc protects payload confidentiality and integrity using industry‑standard AEAD algorithms.
AES‑256‑GCM Implementation
The primary encryption route utilizes AES‑256 in Galois/Counter Mode (GCM). The Encrypt function (lines 36‑55) generates a fresh 12‑byte nonce, initializes aes.NewCipher with the derived 32‑byte key, wraps the cipher with cipher.NewGCM, and seals the plaintext. The Decrypt counterpart (lines 58‑73) verifies the 128‑bit authentication tag before releasing cleartext, ensuring both confidentiality and integrity with roughly 130‑bit security margins.
ChaCha20‑Poly1305 Alternative
Croc also provides EncryptChaCha and DecryptChaCha (lines 98‑125) for platforms lacking AES hardware acceleration. These functions leverage chacha20poly1305.NewX (as instantiated in NewArgon2) to offer a stream‑cipher‑based AEAD with constant‑time execution characteristics. This eliminates timing side‑channels while maintaining equivalent security to AES‑256.
Integrity and Hashing
Beyond encryption, croc ensures data integrity using SHA‑256. The hashing utilities in src/utils/utils.go (lines 8‑10) apply SHA‑256 to file contents for tamper detection and to PBKDF2 salts for key generation. This cryptographic hash function provides collision resistance, ensuring that any modification to transferred data—whether accidental or malicious—is immediately detectable by the recipient.
Practical Cryptographic Workflow
The following Go example demonstrates both the PBKDF2‑AES‑GCM and Argon2‑ChaCha20 paths as implemented in src/crypt/crypt.go:
package main
import (
"fmt"
"github.com/schollz/croc/v10/src/crypt"
)
func main() {
// 1️⃣ Derive a key from a passphrase (PBKDF2‑SHA256)
passphrase := []byte("my‑secret‑phrase")
key, _, err := crypt.New(passphrase, nil)
if err != nil {
panic(err)
}
// 2️⃣ Encrypt a payload with AES‑GCM
plain := []byte("Hello, croc!")
enc, err := crypt.Encrypt(plain, key)
if err != nil {
panic(err)
}
fmt.Printf("AES‑GCM ciphertext: %x\n", enc)
// 3️⃣ Decrypt it back
dec, err := crypt.Decrypt(enc, key)
if err != nil {
panic(err)
}
fmt.Printf("Decrypted: %s\n", dec)
// 4️⃣ Using Argon2 + ChaCha20‑Poly1305 (alternative high‑memory KDF)
aead, salt, err := crypt.NewArgon2(passphrase, nil)
if err != nil {
panic(err)
}
encCha, err := crypt.EncryptChaCha(plain, aead)
if err != nil {
panic(err)
}
fmt.Printf("ChaCha20‑Poly1305 ciphertext: %x\n", encCha)
decCha, err := crypt.DecryptChaCha(encCha, aead)
if err != nil {
panic(err)
}
fmt.Printf("ChaCha decrypted: %s\n", decCha)
}
This example leverages the high‑level API defined in src/crypt/crypt.go, while src/croc/croc.go orchestrates the transfer logic and src/message/message.go handles serialization of encrypted payloads between peers.
Summary
- Dual KDF support: Croc offers both PBKDF2‑SHA256 (CPU‑hard) and Argon2‑id (memory‑hard) for deriving 256‑bit keys from passphrases.
- AEAD encryption: File contents are encrypted with either AES‑256‑GCM (default) or ChaCha20‑Poly1305, ensuring confidentiality and integrity via authenticated encryption.
- SHA‑256 integrity: Cryptographic hashing in
src/utils/utils.goprovides tamper‑evident file verification and secure salt generation. - No deprecated algorithms: Croc relies exclusively on modern, well‑vetted primitives without legacy or custom cryptography.
Frequently Asked Questions
Does croc use end‑to‑end encryption?
Yes. Croc encrypts data on the sender’s device using keys derived locally from the transfer passphrase, and only the recipient possessing the matching code can decrypt the payload. Intermediary relay servers handle only opaque ciphertext and cannot access file contents.
Why does croc support both AES‑GCM and ChaCha20‑Poly1305?
Croc defaults to AES‑256‑GCM for performance on hardware with AES‑NI instructions, while offering ChaCha20‑Poly1305 as an alternative for devices lacking hardware acceleration or where constant‑time execution is necessary to prevent timing attacks. Both provide equivalent 256‑bit security.
How does croc derive encryption keys from a short transfer code?
Croc treats the transfer code as a passphrase fed into either New (PBKDF2‑SHA256) or NewArgon2. These functions apply computational stretching—iterating the hash function or consuming memory—to resist offline brute‑force attempts, ensuring that even short human‑readable codes yield cryptographically strong keys.
Is SHA‑256 used only for file hashing?
No. While SHA‑256 is used in src/utils/utils.go to hash file contents for integrity checks, it also serves as the underlying hash function for PBKDF2 key derivation in src/crypt/crypt.go, and for generating cryptographic salts during the Argon2 process.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →