# GO-CRYPTO-003: Use of DES or 3DES Weak Cipher

> **Severity:** HIGH | **CWE:** CWE-327 | **OWASP:** A02:2021

- **Language:** Go
- **Category:** Security
- **URL:** https://codepathfinder.dev/registry/golang/security/GO-CRYPTO-003
- **Detection:** `pathfinder scan --ruleset golang/GO-CRYPTO-003 --project .`

## Description

**DES (Data Encryption Standard)**: Standardized in 1977 with a 56-bit key (2^56 ≈ 72
quadrillion combinations). The EFF's "Deep Crack" machine broke a DES-encrypted message
in 22 hours and 15 minutes in January 1999, spending approximately $250,000 on hardware.
Modern cloud infrastructure makes DES key exhaustion trivial. DES must never be used.

**3DES (Triple DES / TDEA)**: 3DES applies DES three times with independent keys, providing
112-bit effective security. However, 3DES retains DES's 64-bit block size — and that is
its fatal weakness.

The **SWEET32 attack** (Bhargavan and Leurent, ACM CCS 2016; CVE-2016-2183) exploits the
birthday bound of 64-bit block ciphers. In CBC mode, after approximately 2^32 blocks
(32 GB of data encrypted under the same key), a block collision is expected with ~50%
probability. From a block collision, the attacker can XOR two ciphertext blocks to
recover the XOR of the corresponding plaintexts. In a proof-of-concept, researchers
recovered a 16-byte HTTP BasicAuth session cookie in under 38 hours by sending ~785 GB
of HTTPS requests in the background of a long-lived TLS session.

**NIST retirement**: NIST SP 800-131A Rev 2 (2019) deprecated 3DES for applying
cryptographic protection through December 31, 2023, and **disallowed it after that date**.
As of 2024, 3DES is prohibited for encryption under all NIST guidance. Legacy decryption
(reading old data) remains allowed to preserve interoperability.

**Replacement**: AES-GCM is the correct modern replacement. AES operates on 128-bit blocks
(birthday bound: 2^64 blocks = 256 exabytes — unreachable in practice), and GCM is an
AEAD construction providing authenticated encryption and integrity in a single pass.


## Vulnerable Code

```python
# --- file: vulnerable.go ---
// GO-CRYPTO-003 positive test cases — all SHOULD be detected
package main

import "crypto/des"

func brokenDES() {
	key := []byte("12345678")
	_, _ = des.NewCipher(key)          // SINK: DES 56-bit key, brute-forceable
}

func brokenTripleDES() {
	key := make([]byte, 24)
	_, _ = des.NewTripleDESCipher(key) // SINK: 3DES deprecated
}

# --- file: go.mod ---
module example.com/go-crypto-003/positive

go 1.21

# --- file: go.sum ---

```

## Secure Code

```python
// SECURE: AES-GCM (128-bit block, authenticated encryption, no SWEET32 risk)
import (
    "crypto/aes"
    "crypto/cipher"
    "crypto/rand"
    "io"
)

func encryptAESGCM(key, plaintext []byte) ([]byte, error) {
    // key: 16 bytes (AES-128), 24 (AES-192), or 32 bytes (AES-256)
    block, err := aes.NewCipher(key)
    if err != nil {
        return nil, err
    }
    aesgcm, err := cipher.NewGCM(block)
    if err != nil {
        return nil, err
    }
    // Generate a unique nonce per encryption (never reuse a nonce with the same key)
    nonce := make([]byte, aesgcm.NonceSize()) // 12 bytes for standard GCM
    if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
        return nil, err
    }
    // Seal appends the 16-byte GCM authentication tag
    return aesgcm.Seal(nonce, nonce, plaintext, nil), nil
}

func decryptAESGCM(key, ciphertextWithNonce []byte) ([]byte, error) {
    block, _ := aes.NewCipher(key)
    aesgcm, _ := cipher.NewGCM(block)
    nonceSize := aesgcm.NonceSize()
    nonce, ct := ciphertextWithNonce[:nonceSize], ciphertextWithNonce[nonceSize:]
    return aesgcm.Open(nil, nonce, ct, nil)
}

```

## Detection Rule (Python SDK)

```python
"""GO-CRYPTO-003: Use of DES/3DES cipher (broken algorithm)."""

from codepathfinder.go_rule import QueryType
from codepathfinder import flows
from codepathfinder.go_decorators import go_rule


class GoCryptoDES(QueryType):
    fqns = ["crypto/des"]
    patterns = ["des.*"]
    match_subclasses = False


@go_rule(
    id="GO-CRYPTO-003",
    severity="HIGH",
    cwe="CWE-327",
    owasp="A02:2021",
    tags="go,security,crypto,des,broken-cipher,CWE-327,OWASP-A02",
    message=(
        "Detected use of the DES/3DES cipher (crypto/des). "
        "DES uses a 56-bit key that can be brute-forced in hours with modern hardware. "
        "3DES (Triple DES) is deprecated by NIST (SP 800-131A). "
        "Use AES-GCM (crypto/aes + crypto/cipher) instead."
    ),
)
def detect_des_cipher():
    """Detect use of DES or Triple DES cipher (crypto/des)."""
    return GoCryptoDES.method("NewCipher", "NewTripleDESCipher")
```

## How to Fix

- Replace des.NewCipher and des.NewTripleDESCipher with aes.NewCipher + cipher.NewGCM.
- Use 32-byte (256-bit) keys for AES-256-GCM for strongest security.
- Never reuse a GCM nonce with the same key — use crypto/rand for fresh 12-byte nonces.
- AES-GCM provides both confidentiality and integrity — no separate MAC step needed.
- For TLS configuration, Go's crypto/tls defaults are safe — do not add 3DES cipher suites.

## Security Implications

- **SWEET32 Session Decryption (CVE-2016-2183):** A 3DES-CBC TLS session carrying 32+ GB of data is vulnerable to birthday attack
block collision. The SWEET32 proof-of-concept recovered session cookie credentials
(HTTP BasicAuth username and password) in under 38 hours of sustained traffic.
This affected approximately 1–2% of TLS connections in 2016.

- **DES Brute Force:** DES with its 56-bit key can be exhausted in hours using modern hardware. Any
encrypted data or keys protected only by DES must be considered compromised.

- **Long-Lived Session Vulnerability:** VPN tunnels, database connection pools, and long-running API sessions are
particularly vulnerable to SWEET32 because the same session key encrypts
traffic over extended time periods, making 32 GB accumulation realistic.


## References

- [SWEET32 — Birthday attacks on 64-bit block ciphers (sweet32.info)](https://sweet32.info/)
- [SWEET32 paper: On the Practical (In-)Security of 64-bit Block Ciphers (ACM CCS 2016)](https://sweet32.info/SWEET32_CCS16.pdf)
- [EFF Deep Crack — DES 56-bit key exhaustion (1999)](https://w2.eff.org/Privacy/Crypto/Crypto_misc/DESCracker/)
- [NIST SP 800-131A Revision 2 — Transitioning Cryptographic Algorithms](https://csrc.nist.gov/pubs/sp/800/131/a/r2/final)
- [SWEET32 explained — NCC Group Cryptography Services](https://cryptoservices.github.io/cryptographic/attacks/2016/09/03/Sweet32.html)
- [Go crypto/aes package documentation](https://pkg.go.dev/crypto/aes)
- [Go crypto/cipher package documentation (AES-GCM)](https://pkg.go.dev/crypto/cipher)
- [Go crypto/des package documentation](https://pkg.go.dev/crypto/des)
- [CWE-327: Use of a Broken or Risky Cryptographic Algorithm](https://cwe.mitre.org/data/definitions/327.html)
- [OWASP Cryptographic Storage Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Cryptographic_Storage_Cheat_Sheet.html)

---

Source: https://codepathfinder.dev/registry/golang/security/GO-CRYPTO-003
Code Pathfinder — Open source, type-aware SAST with cross-file dataflow analysis
