# What Cryptographic Protocols Does Croc Use for Security?

> Discover the cryptographic protocols Croc uses for secure file transfers Learn about key derivation encryption and integrity verification methods like PBKDF2 AES and SHA256

- Repository: [Zack/croc](https://github.com/schollz/croc)
- Tags: security
- Published: 2026-07-26

---

**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`](https://github.com/schollz/croc/blob/main/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`](https://github.com/schollz/croc/blob/main/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`](https://github.com/schollz/croc/blob/main/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`](https://github.com/schollz/croc/blob/main/src/crypt/crypt.go):

```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`](https://github.com/schollz/croc/blob/main/src/crypt/crypt.go), while [`src/croc/croc.go`](https://github.com/schollz/croc/blob/main/src/croc/croc.go) orchestrates the transfer logic and [`src/message/message.go`](https://github.com/schollz/croc/blob/main/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.go`](https://github.com/schollz/croc/blob/main/src/utils/utils.go) provides 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`](https://github.com/schollz/croc/blob/main/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`](https://github.com/schollz/croc/blob/main/src/crypt/crypt.go), and for generating cryptographic salts during the Argon2 process.