Skip to main content

Certificates API

The Certificates API allows you to list and monitor all SSL/TLS certificates discovered across your organization's assets.

info

This API endpoint is available for enterprise accounts only.

List Certificates

Retrieve all certificates discovered across your organization's assets.

HTTP Request

GET https://fullhunt.io/api/v1/enterprise/certificates

Query Parameters

ParameterRequiredTypeDescription
qNostringSearch query to filter certificates by domain name, date, or certificate type
pageNointegerPagination page number (default: 1)
fromNostringGet certificates from date (format: DD/MM/YYYY)
toNostringGet certificates until date (format: DD/MM/YYYY)

Example Request

curl "https://fullhunt.io/api/v1/enterprise/certificates?q=kaspersky" \
-H "X-API-KEY: xxxx-xxxx-xxxx-xxxxxx"

Example Request with Filters

curl "https://fullhunt.io/api/v1/enterprise/certificates?q=kaspersky&from=01/01/2024&to=31/12/2024" \
-H "X-API-KEY: xxxx-xxxx-xxxx-xxxxxx"

Example Response

{
"status": 200,
"total_results": 42,
"page": 1,
"results": {
"items": [
{
"id": "CERT-5231",
"domain_name": "cloud.kaspersky.com",
"date_added": "2024-03-15T14:22:31Z",
"last_seen": "2024-03-15T14:22:31Z",
"type": "Certificate"
}
],
"total": 42,
"page": 1,
"per_page": 10,
"pages": 5
}
}

Response Fields

FieldTypeDescription
statusintegerHTTP status code
total_resultsintegerTotal number of certificates found
pageintegerCurrent page number
results.itemsarrayArray of certificate objects
results.totalintegerTotal items in current response
results.pagesintegerTotal number of pages

Certificate Object Fields

FieldTypeDescription
idstringUnique certificate identifier
domain_namestringPrimary domain name on the certificate
date_addedstringISO timestamp when certificate was first discovered
last_seenstringISO timestamp when certificate was last seen
typestringCertificate type (always "Certificate")

Certificate Details

For detailed certificate information, you can use the Domain APIs or Host APIs to get full certificate objects:

# Get detailed certificate info for a specific host
curl "https://fullhunt.io/api/v1/host/cloud.kaspersky.com" \
-H "X-API-KEY: xxxx-xxxx-xxxx-xxxxxx"

This will return detailed certificate information including:

  • Subject and issuer details
  • Valid date ranges
  • DNS names (SANs)
  • Fingerprints (MD5, SHA1, SHA256)
  • Signature algorithm

Integration Example

import requests
from datetime import datetime, timedelta
import json

class CertificateMonitor:
def __init__(self, api_key):
self.api_key = api_key
self.headers = {"X-API-KEY": api_key}

def get_all_certificates(self, search_query=None, from_date=None, to_date=None):
"""Get all certificates, optionally filtered by search query and date range."""
url = "https://fullhunt.io/api/v1/enterprise/certificates"
params = {}

if search_query:
params["q"] = search_query
if from_date:
params["from"] = from_date
if to_date:
params["to"] = to_date

all_certificates = []
page = 1

while True:
params["page"] = page
response = requests.get(url, headers=self.headers, params=params)

if response.status_code == 200:
data = response.json()
certificates = data.get("results", {}).get("items", [])

if not certificates:
break

all_certificates.extend(certificates)

# Check if there are more pages
current_page = data.get("results", {}).get("page", 1)
total_pages = data.get("results", {}).get("pages", 1)

if current_page >= total_pages:
break

page += 1
else:
print(f"Error: {response.status_code}")
break

return all_certificates

def get_certificate_details(self, domain):
"""Get detailed certificate information for a domain."""
url = f"https://fullhunt.io/api/v1/host/{domain}"
response = requests.get(url, headers=self.headers)

if response.status_code == 200:
data = response.json()
return data.get("cert_object")
else:
print(f"Error getting details for {domain}: {response.status_code}")
return None

def check_expiring_certificates(self, days_ahead=30):
"""Check for certificates expiring within specified days."""
print(f"🔍 Checking for certificates expiring in {days_ahead} days...")

certificates = self.get_all_certificates()
expiring_certs = []

for cert in certificates:
domain = cert["domain_name"]
details = self.get_certificate_details(domain)

if details and details.get("not_after"):
try:
# Parse expiration date
exp_date_str = details["not_after"]
exp_date = datetime.strptime(exp_date_str, "%d-%m-%Y %H:%M:%S")

# Check if expiring soon
days_until_expiry = (exp_date - datetime.now()).days

if 0 <= days_until_expiry <= days_ahead:
expiring_certs.append({
"domain": domain,
"expires": exp_date_str,
"days_remaining": days_until_expiry,
"issuer": details.get("issuer_common_name"),
"subject": details.get("subject_common_name")
})

except ValueError as e:
print(f"Error parsing date for {domain}: {e}")

# Sort by days remaining (most urgent first)
expiring_certs.sort(key=lambda x: x["days_remaining"])

if expiring_certs:
print(f"⚠️ Found {len(expiring_certs)} certificates expiring soon:")

for cert in expiring_certs:
urgency = "🚨" if cert["days_remaining"] <= 7 else "⚠️"
print(f" {urgency} {cert['domain']} - expires in {cert['days_remaining']} days")
print(f" Expires: {cert['expires']}")
print(f" Issuer: {cert['issuer']}")
print()
else:
print("✅ No certificates expiring soon")

return expiring_certs

def certificate_inventory_report(self):
"""Generate a comprehensive certificate inventory report."""
print("📋 Certificate Inventory Report")
print("=" * 50)

certificates = self.get_all_certificates()

# Statistics
total_certs = len(certificates)

# Get detailed info for analysis
issuers = {}
algorithms = {}
upcoming_expirations = {"7_days": 0, "30_days": 0, "90_days": 0}

print(f"Total Certificates: {total_certs}")
print("\nAnalyzing certificate details...")

for i, cert in enumerate(certificates, 1):
print(f"Progress: {i}/{total_certs}", end="\r")

domain = cert["domain_name"]
details = self.get_certificate_details(domain)

if details:
# Count issuers
issuer = details.get("issuer_common_name", "Unknown")
issuers[issuer] = issuers.get(issuer, 0) + 1

# Count signature algorithms
algorithm = details.get("signature_algorithm", "Unknown")
algorithms[algorithm] = algorithms.get(algorithm, 0) + 1

# Check expiration timeframes
if details.get("not_after"):
try:
exp_date = datetime.strptime(details["not_after"], "%d-%m-%Y %H:%M:%S")
days_until_expiry = (exp_date - datetime.now()).days

if days_until_expiry <= 7:
upcoming_expirations["7_days"] += 1
elif days_until_expiry <= 30:
upcoming_expirations["30_days"] += 1
elif days_until_expiry <= 90:
upcoming_expirations["90_days"] += 1
except ValueError:
pass

print("\n\n📊 Certificate Analysis:")

print(f"\nTop Certificate Issuers:")
for issuer, count in sorted(issuers.items(), key=lambda x: x[1], reverse=True)[:5]:
print(f" {issuer}: {count} certificates")

print(f"\nSignature Algorithms:")
for algorithm, count in sorted(algorithms.items(), key=lambda x: x[1], reverse=True):
print(f" {algorithm}: {count} certificates")

print(f"\nExpiration Timeline:")
print(f" Next 7 days: {upcoming_expirations['7_days']} certificates")
print(f" Next 30 days: {upcoming_expirations['30_days']} certificates")
print(f" Next 90 days: {upcoming_expirations['90_days']} certificates")

return {
"total_certificates": total_certs,
"issuers": issuers,
"algorithms": algorithms,
"expiration_timeline": upcoming_expirations
}

# Usage examples
api_key = "your-api-key-here"
cert_monitor = CertificateMonitor(api_key)

# Check for expiring certificates
expiring = cert_monitor.check_expiring_certificates(days_ahead=30)

# Generate comprehensive report
report = cert_monitor.certificate_inventory_report()

# Search for specific certificates
kaspersky_certs = cert_monitor.get_all_certificates("kaspersky")
print(f"Found {len(kaspersky_certs)} certificates containing 'kaspersky'")

# Get certificates discovered in the last 30 days
from datetime import datetime, timedelta
end_date = datetime.now()
start_date = end_date - timedelta(days=30)

from_date = start_date.strftime("%d/%m/%Y")
to_date = end_date.strftime("%d/%m/%Y")

recent_certs = cert_monitor.get_all_certificates(
from_date=from_date,
to_date=to_date
)
print(f"Found {len(recent_certs)} certificates discovered in the last 30 days")

# Get certificates for specific domain with date filtering
filtered_certs = cert_monitor.get_all_certificates(
search_query="kaspersky",
from_date="01/01/2024",
to_date="31/12/2024"
)

Certificate Monitoring Automation

import requests
import json
import smtplib
from email.mime.text import MIMEText
from datetime import datetime, timedelta

def automated_certificate_monitoring(api_key, email_config=None):
"""Automated certificate monitoring with email alerts."""

cert_monitor = CertificateMonitor(api_key)

# Check for certificates expiring in different timeframes
timeframes = [7, 14, 30]
alerts = {}

for days in timeframes:
expiring = cert_monitor.check_expiring_certificates(days_ahead=days)
if expiring:
alerts[f"{days}_days"] = expiring

if alerts and email_config:
send_certificate_alert_email(alerts, email_config)

# Save monitoring results
monitoring_result = {
"timestamp": datetime.now().isoformat(),
"alerts": alerts,
"total_certificates_checked": len(cert_monitor.get_all_certificates())
}

with open("certificate_monitoring_log.json", "a") as f:
f.write(json.dumps(monitoring_result) + "\n")

return monitoring_result

def send_certificate_alert_email(alerts, email_config):
"""Send email alert for expiring certificates."""

subject = "🔒 Certificate Expiration Alert"

body = "The following SSL/TLS certificates are expiring soon:\n\n"

for timeframe, certs in alerts.items():
days = timeframe.replace("_days", "")
body += f"Expiring in {days} days:\n"

for cert in certs:
body += f" • {cert['domain']} - {cert['days_remaining']} days remaining\n"
body += f" Expires: {cert['expires']}\n"
body += f" Issuer: {cert['issuer']}\n\n"

body += "\nPlease take action to renew these certificates before they expire.\n"
body += "Generated by FullHunt Certificate Monitoring"

# Send email
msg = MIMEText(body)
msg["Subject"] = subject
msg["From"] = email_config["from"]
msg["To"] = email_config["to"]

try:
server = smtplib.SMTP(email_config["smtp_server"], email_config["smtp_port"])
server.starttls()
server.login(email_config["username"], email_config["password"])
server.send_message(msg)
server.quit()
print("📧 Certificate alert email sent successfully")
except Exception as e:
print(f"❌ Failed to send email: {e}")

# Email configuration example
email_config = {
"smtp_server": "smtp.gmail.com",
"smtp_port": 587,
"username": "your-email@gmail.com",
"password": "your-app-password",
"from": "your-email@gmail.com",
"to": "security-team@acme.com"
}

# Run automated monitoring
api_key = "your-api-key-here"
result = automated_certificate_monitoring(api_key, email_config)

Use Cases

Certificate Lifecycle Management

  • Monitor certificate expiration dates
  • Track certificate issuers and validate trust chains
  • Identify certificates that need renewal

Security Compliance

  • Ensure all certificates use strong encryption algorithms
  • Verify certificate issuers are from trusted CAs
  • Monitor for weak or deprecated algorithms

Asset Discovery

  • Discover all SSL/TLS enabled services
  • Identify shadow IT through certificate monitoring
  • Map certificate coverage across your infrastructure

Incident Response

  • Quickly identify potentially compromised certificates
  • Track certificate changes over time
  • Monitor for unauthorized certificate installations

Best Practices

Certificate Management

  1. Automated Renewal: Implement automated certificate renewal where possible
  2. Monitoring: Set up alerts for certificates expiring in 30, 14, and 7 days
  3. Documentation: Maintain an inventory of all certificates and their purposes
  4. Testing: Regularly test certificate renewal processes

Security Considerations

  1. Strong Algorithms: Ensure all certificates use strong signature algorithms (SHA-256 or better)
  2. Trusted CAs: Only use certificates from trusted Certificate Authorities
  3. Key Management: Secure private keys and use hardware security modules when possible
  4. Certificate Transparency: Monitor Certificate Transparency logs for unauthorized certificates

Rate Limiting

  • Rate limit: 60 requests per minute
  • Use pagination for large certificate inventories
  • Consider caching results for frequently accessed data