mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-06-10 21:24:56 +03:00
27c6414ca5
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
173 lines
5.3 KiB
Python
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()
|