Files
mukul975 27c6414ca5 Add folder anatomy (scripts/agent.py + references/api-reference.md) for 648 cybersecurity skills
Complete skill folder anatomy across all cybersecurity skills:
- scripts/agent.py: 80-150 line Python agents using real libraries (impacket,
  boto3, azure-mgmt-*, kubernetes, pefile, yara, scapy, shodan, stix2, etc.)
- references/api-reference.md: real API documentation with method signatures
- LICENSE: MIT license for all skill folders
2026-03-10 21:02:12 +01:00

173 lines
5.3 KiB
Python

#!/usr/bin/env python3
"""Agent for implementing AES-256-GCM encryption for data at rest."""
import os
import json
import argparse
from datetime import datetime
from pathlib import Path
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives import hashes
SALT_SIZE = 16
NONCE_SIZE = 12
KEY_SIZE = 32 # 256 bits
TAG_SIZE = 16
PBKDF2_ITERATIONS = 600_000
def derive_key(password, salt=None):
"""Derive AES-256 key from password using PBKDF2-HMAC-SHA256."""
if salt is None:
salt = os.urandom(SALT_SIZE)
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=KEY_SIZE,
salt=salt,
iterations=PBKDF2_ITERATIONS,
)
key = kdf.derive(password.encode("utf-8"))
return key, salt
def encrypt_file(input_path, output_path, password):
"""Encrypt a file using AES-256-GCM with PBKDF2 key derivation."""
key, salt = derive_key(password)
nonce = os.urandom(NONCE_SIZE)
aesgcm = AESGCM(key)
with open(input_path, "rb") as f:
plaintext = f.read()
ciphertext = aesgcm.encrypt(nonce, plaintext, None)
with open(output_path, "wb") as f:
f.write(salt)
f.write(nonce)
f.write(ciphertext)
return {
"input": str(input_path),
"output": str(output_path),
"original_size": len(plaintext),
"encrypted_size": SALT_SIZE + NONCE_SIZE + len(ciphertext),
"algorithm": "AES-256-GCM",
"kdf": f"PBKDF2-HMAC-SHA256 ({PBKDF2_ITERATIONS} iterations)",
}
def decrypt_file(input_path, output_path, password):
"""Decrypt an AES-256-GCM encrypted file."""
with open(input_path, "rb") as f:
salt = f.read(SALT_SIZE)
nonce = f.read(NONCE_SIZE)
ciphertext = f.read()
key, _ = derive_key(password, salt)
aesgcm = AESGCM(key)
plaintext = aesgcm.decrypt(nonce, ciphertext, None)
with open(output_path, "wb") as f:
f.write(plaintext)
return {
"input": str(input_path),
"output": str(output_path),
"decrypted_size": len(plaintext),
}
def encrypt_directory(dir_path, output_dir, password):
"""Encrypt all files in a directory tree."""
src = Path(dir_path)
dst = Path(output_dir)
dst.mkdir(parents=True, exist_ok=True)
results = []
for filepath in src.rglob("*"):
if filepath.is_file():
rel = filepath.relative_to(src)
out = dst / (str(rel) + ".enc")
out.parent.mkdir(parents=True, exist_ok=True)
result = encrypt_file(str(filepath), str(out), password)
results.append(result)
return results
def generate_random_key():
"""Generate a random AES-256 key."""
key = os.urandom(KEY_SIZE)
return {
"key_hex": key.hex(),
"key_size_bits": KEY_SIZE * 8,
"algorithm": "AES-256",
}
def verify_encryption(original_path, encrypted_path, password):
"""Verify encryption by decrypting and comparing."""
with open(original_path, "rb") as f:
original = f.read()
with open(encrypted_path, "rb") as f:
salt = f.read(SALT_SIZE)
nonce = f.read(NONCE_SIZE)
ciphertext = f.read()
key, _ = derive_key(password, salt)
aesgcm = AESGCM(key)
try:
decrypted = aesgcm.decrypt(nonce, ciphertext, None)
match = original == decrypted
return {"status": "PASS" if match else "FAIL", "content_match": match}
except Exception as e:
return {"status": "FAIL", "error": str(e)}
def main():
parser = argparse.ArgumentParser(description="AES-256-GCM Encryption Agent")
parser.add_argument("--action", required=True,
choices=["encrypt", "decrypt", "encrypt_dir", "genkey", "verify"])
parser.add_argument("--input", help="Input file or directory")
parser.add_argument("--output", help="Output file or directory")
parser.add_argument("--password", help="Encryption password")
parser.add_argument("--report", default="aes_encryption_report.json")
args = parser.parse_args()
report = {"generated_at": datetime.utcnow().isoformat(), "action": args.action}
if args.action == "encrypt":
result = encrypt_file(args.input, args.output, args.password)
report["result"] = result
print(f"[+] Encrypted: {args.input} -> {args.output}")
elif args.action == "decrypt":
result = decrypt_file(args.input, args.output, args.password)
report["result"] = result
print(f"[+] Decrypted: {args.input} -> {args.output}")
elif args.action == "encrypt_dir":
results = encrypt_directory(args.input, args.output, args.password)
report["results"] = results
print(f"[+] Encrypted {len(results)} files")
elif args.action == "genkey":
result = generate_random_key()
report["result"] = result
print(f"[+] Key: {result['key_hex']}")
elif args.action == "verify":
result = verify_encryption(args.input, args.output, args.password)
report["result"] = result
print(f"[+] Verification: {result['status']}")
with open(args.report, "w") as f:
json.dump(report, f, indent=2, default=str)
print(f"[+] Report saved to {args.report}")
if __name__ == "__main__":
main()