mirror of
https://github.com/mukul975/Anthropic-Cybersecurity-Skills.git
synced 2026-06-16 07:53:18 +03:00
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
This commit is contained in:
@@ -0,0 +1,172 @@
|
||||
#!/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()
|
||||
Reference in New Issue
Block a user