CertificateExtract
Extract fields from a certificate file and return the standard context.
- Type
- python
- Pack
- CommonScripts
Source
from typing import Any, cast
import demistomock as demisto
from CommonServerPython import * # noqa # pylint: disable=unused-wildcard-import
from cryptography import x509
# mypy: ignore-errors
from cryptography.hazmat import backends
from cryptography.hazmat.primitives import asymmetric, hashes, serialization
from cryptography.x509 import certificate_transparency, extensions, general_name, oid
from CommonServerUserPython import * # noqa # pylint: disable=unused-wildcard-import
_INSTANCE_TO_TYPE = {
general_name.OtherName: "otherName",
general_name.RFC822Name: "rfc822Name",
general_name.DNSName: "dNSName",
general_name.DirectoryName: "directoryName",
general_name.UniformResourceIdentifier: "uniformResourceIdentifier",
general_name.IPAddress: "iPAddress",
general_name.RegisteredID: "registeredID",
}
_SCT_LOG_ENTRY_TYPE_NAME = {
certificate_transparency.LogEntryType.PRE_CERTIFICATE: "PreCertificate",
certificate_transparency.LogEntryType.X509_CERTIFICATE: "X509Certificate",
}
""" STANDALONE FUNCTION """
def get_indicator_from_value(indicator_value: str) -> Any:
"""
get_indicator_from_value function
Finds an indicator in XSOAR store given a value
:type value: ``str``
:param value: Indicator value
:return: Indicator
:rtype: ``Any``
"""
try:
res = demisto.executeCommand("findIndicators", {"query": f'value:"{indicator_value}" and type:Certificate'})
indicator = res[0]["Contents"][0]
return indicator
except BaseException:
return None
def oid_name(oid: oid.ObjectIdentifier) -> str:
"""
oid_name function
Translates an oid.ObjectIdentifier into a string representation
:type oid: ``oid.ObjectIdentifier``
:param oid: OID as oid.ObjectIdentifier
:return: OID in dotted string format
:rtype: ``str``
"""
n = oid._name
if n.startswith("Unknown"):
return oid.dotted_string
return n
def repr_or_str(o: Any) -> str:
"""
repr_or_str function
Returns a string representation of the input:
- If input is bytes returns the hex representation
- If input is str returns the string
- If input is None returns empty string
:type o: ``Any``
:param o: Input data (str or bytes)
:return: String representation of the input
:rtype: ``str``
"""
if isinstance(o, str):
return o
elif isinstance(o, bytes):
return o.hex()
elif o is None:
return ""
return repr(o)
def load_certificate(path: str) -> x509.Certificate:
"""
load_certificate function
Loads a certificate from a file
:type path: ``str``
:param path: File path
:return: X509 Certificate parsed by cryptography.x509
:rtype: ``x509.Certificate``
"""
with open(path, "rb") as f:
contents = f.read()
try:
certificate = x509.load_pem_x509_certificate(contents, backends.default_backend())
except Exception as e:
demisto.debug(f"Error loading certificate as PEM, trying with DER. Error was: {e!r}")
certificate = x509.load_der_x509_certificate(contents, backends.default_backend())
return certificate
def int_to_comma_hex(n: int, blength: int | None = None) -> str:
"""
int_to_comma_hex
Translates an integer in its corresponding hex string
:type n: ``int``
:param n: Input integer
:type blength: ``Optional[int]``
:param blength: Add padding to reach length
:return: Translated hex string
:rtype: ``str``
"""
bhex = f"{n:x}"
if len(bhex) % 2 == 1:
bhex = "0" + bhex
if blength is not None:
bhex = "00" * max(blength - len(bhex), 0) + bhex
return ":".join([bhex[i : i + 2] for i in range(0, len(bhex), 2)])
def public_key_context(
pkey: asymmetric.dsa.DSAPublicKey
| asymmetric.rsa.RSAPublicKey
| asymmetric.ec.EllipticCurvePublicKey
| asymmetric.ed25519.Ed25519PublicKey
| asymmetric.ed448.Ed448PublicKey,
) -> Common.CertificatePublicKey:
"""
public_key_context function
Translates an X509 certificate Public Key into a Common.CertificatePublicKey object
:type pkey: ``Union[asymmetric.dsa.DSAPublicKey, asymmetric.rsa.RSAPublicKey, asymmetric.ec.EllipticCurvePublicKey, \
asymmetric.ed25519.Ed25519PublicKey, asymmetric.ed448.Ed448PublicKey]``
:param pkey: Certificate Public Key
:return: Certificate Public Key represented as a Common.CertificatePublicKey object
:rtype: ``Common.CertificatePublicKey``
"""
if isinstance(pkey, asymmetric.dsa.DSAPublicKey):
return Common.CertificatePublicKey(
algorithm=Common.CertificatePublicKey.Algorithm.DSA,
length=pkey.key_size,
publickey=int_to_comma_hex(pkey.public_numbers().y),
p=int_to_comma_hex(pkey.public_numbers().parameter_numbers.p),
q=int_to_comma_hex(pkey.public_numbers().parameter_numbers.q),
g=int_to_comma_hex(pkey.public_numbers().parameter_numbers.g),
)
elif isinstance(pkey, asymmetric.rsa.RSAPublicKey):
return Common.CertificatePublicKey(
algorithm=Common.CertificatePublicKey.Algorithm.RSA,
length=pkey.key_size,
modulus=int_to_comma_hex(pkey.public_numbers().n),
exponent=pkey.public_numbers().e,
)
elif isinstance(pkey, asymmetric.ec.EllipticCurvePublicKey):
return Common.CertificatePublicKey(
algorithm=Common.CertificatePublicKey.Algorithm.EC,
length=pkey.key_size,
x=int_to_comma_hex(pkey.public_numbers().x),
y=int_to_comma_hex(pkey.public_numbers().y),
curve=pkey.curve.name,
)
return Common.CertificatePublicKey(
algorithm=Common.CertificatePublicKey.Algorithm.UNKNOWN,
length=0,
publickey=pkey.public_bytes(encoding=serialization.Encoding.Raw, format=serialization.PublicFormat.Raw).hex(),
)
def map_gn(gn: Any) -> Common.GeneralName:
"""
map_gn function
Check whether the provided General Name is a compatible type and maps it to a Common.GeneralName class
:type gn: ``Any``
:param gn: General name to be checked
:return: General Name mapped to a Common.GeneralName class
:rtype: ``Common.GeneralName``
"""
if gn is None:
raise ValueError("gn cannot be None")
itype = next((t for t in _INSTANCE_TO_TYPE if isinstance(gn, t)), None)
if itype is not None:
return Common.GeneralName(gn_type=_INSTANCE_TO_TYPE[itype], gn_value=str(gn.value))
raise ValueError("general name must be a valid type")
def extension_context(oid: str, extension_name: str, critical: bool, extension_value: Any) -> Common.CertificateExtension:
"""
extension_context function
Translates an X509 certificate extension into a Common.CertificateExtension object
:type oid: ``str``
:param oid: Certificate Extension OID
:type extension_name: ``str``
:param extension_name: Name of the Extension
:type critical: ``bool``
:param critical: Whether the Extension is marked as critical
:type extension_value: ``Any``
:param extension_value: Value of the extension (parsed from cryptograph module)
:return: Extension represented as a Common.CertificateExtension object
:rtype: ``Common.CertificateExtension``
"""
if isinstance(extension_value, extensions.SubjectAlternativeName):
return Common.CertificateExtension(
extension_type=Common.CertificateExtension.ExtensionType.SUBJECTALTERNATIVENAME,
oid=oid,
extension_name=extension_name,
critical=critical,
subject_alternative_names=[
Common.CertificateExtension.SubjectAlternativeName(gn=map_gn(gn))
for gn in extension_value._general_names
if gn is not None
],
)
elif isinstance(extension_value, extensions.AuthorityKeyIdentifier):
authority_key_identifier = Common.CertificateExtension.AuthorityKeyIdentifier(
issuer=[map_gn(n) for n in list(extension_value.authority_cert_issuer)]
if (extension_value.authority_cert_issuer)
else None,
serial_number=extension_value.authority_cert_serial_number, # type: ignore
key_identifier=extension_value.key_identifier.hex(), # type: ignore
)
return Common.CertificateExtension(
extension_type=Common.CertificateExtension.ExtensionType.AUTHORITYKEYIDENTIFIER,
oid=oid,
extension_name=extension_name,
critical=critical,
authority_key_identifier=authority_key_identifier,
)
elif isinstance(extension_value, extensions.SubjectKeyIdentifier):
return Common.CertificateExtension(
extension_type=Common.CertificateExtension.ExtensionType.SUBJECTKEYIDENTIFIER,
oid=oid,
extension_name=extension_name,
critical=critical,
digest=extension_value.digest.hex(),
)
elif isinstance(extension_value, extensions.KeyUsage):
return Common.CertificateExtension(
extension_type=Common.CertificateExtension.ExtensionType.KEYUSAGE,
oid=oid,
extension_name=extension_name,
critical=critical,
digital_signature=extension_value.digital_signature,
content_commitment=extension_value.content_commitment,
key_encipherment=extension_value.key_encipherment,
data_encipherment=extension_value.data_encipherment,
key_agreement=extension_value.key_agreement,
key_cert_sign=extension_value.key_cert_sign,
crl_sign=extension_value.crl_sign,
)
elif isinstance(extension_value, extensions.ExtendedKeyUsage):
return Common.CertificateExtension(
extension_type=Common.CertificateExtension.ExtensionType.EXTENDEDKEYUSAGE,
oid=oid,
extension_name=extension_name,
critical=critical,
usages=[oid_name(o) for o in extension_value],
)
elif isinstance(extension_value, extensions.CRLDistributionPoints):
distribution_points: list[Common.CertificateExtension.DistributionPoint] = []
dp: extensions.DistributionPoint
for dp in extension_value:
distribution_points.append(
Common.CertificateExtension.DistributionPoint(
full_name=None if dp.full_name is None else [map_gn(fn) for fn in list(dp.full_name)],
relative_name=None if dp.relative_name is None else dp.relative_name.rfc4514_string(),
crl_issuer=None if dp.crl_issuer is None else [map_gn(ci) for ci in list(dp.crl_issuer)],
reasons=None if dp.reasons is None else [repr_or_str(r) for r in dp.reasons],
)
)
return Common.CertificateExtension(
extension_type=Common.CertificateExtension.ExtensionType.CRLDISTRIBUTIONPOINTS,
oid=oid,
extension_name=extension_name,
critical=critical,
distribution_points=distribution_points,
)
elif isinstance(extension_value, extensions.CertificatePolicies):
policies: list[Common.CertificateExtension.CertificatePolicy] = []
p: extensions.PolicyInformation
for p in extension_value:
policies.append(
Common.CertificateExtension.CertificatePolicy(
policy_identifier=oid_name(p.policy_identifier),
policy_qualifiers=None if not p.policy_qualifiers else [repr_or_str(pq) for pq in p.policy_qualifiers],
)
)
return Common.CertificateExtension(
extension_type=Common.CertificateExtension.ExtensionType.CERTIFICATEPOLICIES,
oid=oid,
extension_name=extension_name,
critical=critical,
certificate_policies=policies,
)
elif isinstance(extension_value, extensions.AuthorityInformationAccess):
descriptions: list[Common.CertificateExtension.AuthorityInformationAccess] = []
d: extensions.AccessDescription
for d in extension_value:
descriptions.append(
Common.CertificateExtension.AuthorityInformationAccess(
access_method=oid_name(d.access_method), access_location=map_gn(d.access_location)
)
)
return Common.CertificateExtension(
extension_type=Common.CertificateExtension.ExtensionType.AUTHORITYINFORMATIONACCESS,
oid=oid,
extension_name=extension_name,
critical=critical,
authority_information_access=descriptions,
)
elif isinstance(extension_value, extensions.BasicConstraints):
return Common.CertificateExtension(
extension_type=Common.CertificateExtension.ExtensionType.BASICCONSTRAINTS,
oid=oid,
extension_name=extension_name,
critical=critical,
basic_constraints=Common.CertificateExtension.BasicConstraints(
ca=extension_value.ca, path_length=None if extension_value.path_length is None else extension_value.path_length
),
)
elif isinstance(extension_value, extensions.PrecertificateSignedCertificateTimestamps):
presigcerttimestamps: list[Common.CertificateExtension.SignedCertificateTimestamp] = []
presct: extensions.SignedCertificateTimestamp
for presct in extension_value:
presigcerttimestamps.append(
Common.CertificateExtension.SignedCertificateTimestamp(
entry_type=_SCT_LOG_ENTRY_TYPE_NAME.get(presct.entry_type, presct.entry_type.value), # type: ignore
version=presct.version.value,
log_id=presct.log_id.hex(),
timestamp=presct.timestamp.strftime("%Y-%m-%dT%H:%M:%S.000Z"),
)
)
return Common.CertificateExtension(
extension_type=Common.CertificateExtension.ExtensionType.PRESIGNEDCERTIFICATETIMESTAMPS,
oid=oid,
extension_name=extension_name,
critical=critical,
signed_certificate_timestamps=presigcerttimestamps,
)
elif isinstance(extension_value, extensions.SignedCertificateTimestamps):
sigcerttimestamps: list[Common.CertificateExtension.SignedCertificateTimestamp] = []
sct: extensions.SignedCertificateTimestamp
for sct in extension_value:
sigcerttimestamps.append(
Common.CertificateExtension.SignedCertificateTimestamp(
entry_type=_SCT_LOG_ENTRY_TYPE_NAME.get(sct.entry_type, sct.entry_type.value), # type: ignore
version=sct.version.value,
log_id=sct.log_id.hex(),
timestamp=sct.timestamp.strftime("%Y-%m-%dT%H:%M:%S.000Z"),
)
)
return Common.CertificateExtension(
extension_type=Common.CertificateExtension.ExtensionType.SIGNEDCERTIFICATETIMESTAMPS,
oid=oid,
extension_name=extension_name,
critical=critical,
signed_certificate_timestamps=sigcerttimestamps,
)
return Common.CertificateExtension(
extension_type=Common.CertificateExtension.ExtensionType.OTHER,
oid=oid,
extension_name=extension_name,
critical=critical,
value=repr(extension_value),
)
def certificate_to_context(certificate: x509.Certificate) -> Common.Certificate:
"""
certificate_to_context function
Translates an X509 certificate into a Common.Certificate object
:type certificate: ``x509.Certificate``
:param oid: Certificate Extension OID
:return: Certificate represented as a Common.Certificate object
:rtype: ``Common.Certificate``
"""
spkisha256 = hashes.Hash(hashes.SHA256(), backends.default_backend())
spkisha256.update(
certificate.public_key().public_bytes(
encoding=serialization.Encoding.DER, format=serialization.PublicFormat.SubjectPublicKeyInfo
)
)
extensions_contexts: list[Common.CertificateExtension] = []
for extension in certificate.extensions:
extension_oid = cast(oid.ObjectIdentifier, extension.oid)
extensions_contexts.append(
extension_context(
oid=extension_oid.dotted_string,
extension_name=extension_oid._name,
critical=extension.critical,
extension_value=extension.value,
)
)
indicator = certificate.fingerprint(hashes.SHA256()).hex()
cert = Common.Certificate(
subject_dn=certificate.subject.rfc4514_string(),
issuer_dn=certificate.issuer.rfc4514_string(),
serial_number=str(certificate.serial_number),
validity_not_before=certificate.not_valid_before.strftime("%Y-%m-%dT%H:%M:%S.000Z"),
validity_not_after=certificate.not_valid_after.strftime("%Y-%m-%dT%H:%M:%S.000Z"),
sha256=certificate.fingerprint(hashes.SHA256()).hex(),
sha1=certificate.fingerprint(hashes.SHA1()).hex(),
md5=certificate.fingerprint(hashes.MD5()).hex(),
spki_sha256=spkisha256.finalize().hex(),
extensions=extensions_contexts,
signature_algorithm=certificate.signature_hash_algorithm.name, # type: ignore[union-attr]
signature=certificate.signature.hex(),
publickey=public_key_context(certificate.public_key()), # type: ignore
dbot_score=Common.DBotScore(
indicator=indicator,
indicator_type=DBotScoreType.CERTIFICATE,
integration_name="X509Certificate",
score=Common.DBotScore.NONE,
),
pem=certificate.public_bytes(serialization.Encoding.PEM).decode("ascii"),
)
return cert
""" COMMAND FUNCTION """
def certificate_extract_command(args: dict[str, Any]) -> CommandResults:
pem: str | None = args.get("pem")
entry_id: str | None = args.get("entry_id")
if pem is None and entry_id is None:
raise ValueError("You should specify pem or entry_id")
if pem is not None and entry_id is not None:
raise ValueError("Only one of pem and entry_id should be specified")
certificate: x509.Certificate
if entry_id is not None:
res_path = demisto.getFilePath(entry_id)
if not res_path:
raise ValueError("Invalid entry_id - not found")
entry_id_path = res_path["path"]
certificate = load_certificate(entry_id_path)
if pem is not None:
certificate = x509.load_pem_x509_certificate(pem.encode("ascii"), backends.default_backend())
standard_context = certificate_to_context(certificate)
readable_output = "Certificate decoded"
return CommandResults(readable_output=readable_output, outputs=None, indicator=standard_context, ignore_auto_extract=True)
""" MAIN FUNCTION """
def main():
try:
return_results(certificate_extract_command(demisto.args()))
except Exception as ex:
return_error(f"Failed to execute CertificateExtract. Error: {ex!s}")
""" ENTRY POINT """
if __name__ in ("__main__", "__builtin__", "builtins"):
main()
README
Extract fields from a certificate file and return the standard context
Script Data
| Name | Description |
|---|---|
| Script Type | python3 |
| Tags | |
| Cortex XSOAR Version | 6.0.0 |
Inputs
| Argument Name | Description |
|---|---|
| pem | Certificate in PEM format |
| entry_id | Certificate entry ID (in DER or PEM format) |
Outputs
| Path | Description | Type |
|---|---|---|
| Certificate.Name | Name (CN or SAN) appearing in the certificate. | String |
| Certificate.SubjectDN | The Subject Distinguished Name of the certificate. This field includes the Common Name of the certificate. |
String |
| Certificate.PEM | Certificate in PEM format. | String |
| Certificate.IssuerDN | The Issuer Distinguished Name of the certificate. | String |
| Certificate.SerialNumber | The Serial Number of the certificate. | String |
| Certificate.ValidityNotAfter | End of certificate validity period. | Date |
| Certificate.ValidityNotBefore | Start of certificate validity period. | Date |
| Certificate.SubjectAlternativeName.Type | Type of the SAN. | String |
| Certificate.SubjectAlternativeName.Value | Name of the SAN. | String |
| Certificate.SHA512 | SHA512 Fingerprint of the certificate in DER format. | String |
| Certificate.SHA256 | SHA256 Fingerprint of the certificate in DER format. | String |
| Certificate.SHA1 | SHA1 Fingerprint of the certificate in DER format. | String |
| Certificate.MD5 | MD5 Fingerprint of the certificate in DER format. | String |
| Certificate.PublicKey.Algorithm | Algorithm used for public key of the certificate. | String |
| Certificate.PublicKey.Length | Length in bits of the public key of the certificate. | Number |
| Certificate.PublicKey.Modulus | Modulus of the public key for RSA keys. | String |
| Certificate.PublicKey.Exponent | Exponent of the public key for RSA keys. | Number |
| Certificate.PublicKey.PublicKey | The public key for DSA/Unknown keys. | String |
| Certificate.PublicKey.P | The P parameter for DSA keys. | String |
| Certificate.PublicKey.Q | The Q parameter for DSA keys. | String |
| Certificate.PublicKey.G | The G parameter for DSA keys. | String |
| Certificate.PublicKey.X | The X parameter for EC keys. | String |
| Certificate.PublicKey.Y | The Y parameter for EC keys. | String |
| Certificate.PublicKey.Curve | Curve of the Public Key for EC keys. | String |
| Certificate.SPKISHA256 | SHA256 fingerprint of the certificate Subject Public Key Info. | String |
| Certificate.Signature.Algorithm | Algorithm used in the signature of the certificate. | String |
| Certificate.Signature.Signature | Signature of the certificate. | String |
| Certificate.Extension.Critical | Critical flag of the certificate extension. | Bool |
| Certificate.Extension.OID | OID of the certificate extension. | String |
| Certificate.Extension.Name | Name of the certificate extension. | String |
| Certificate.Extension.Value | Value of the certificate extension. | Unknown |
| Certificate.Malicious.Vendor | The vendor that reported the file as malicious. | String |
| Certificate.Malicious.Description | A description explaining why the file was determined to be malicious. | String |
| DBotScore.Indicator | The indicator that was tested. | String |
| DBotScore.Type | The indicator type. | String |
| DBotScore.Vendor | The vendor used to calculate the score. | String |
| DBotScore.Score | The actual score. | Number |
Script Example
!CertificateExtract entry_id="978@5b925e3c-6ab8-4209-86bf-10f4ed6a9dc0"
Context Example
{
"Certificate": {
"Extension": [
{
"Critical": true,
"Name": "basicConstraints",
"OID": "2.5.29.19",
"Value": {
"CA": false
}
},
{
"Critical": false,
"Name": "subjectKeyIdentifier",
"OID": "2.5.29.14",
"Value": {
"Digest": "3fe12ea63b9cf8414f0b001f2efa8ac5bd0fc73c"
}
},
{
"Critical": false,
"Name": "keyUsage",
"OID": "2.5.29.15",
"Value": {
"DataEncipherment": true,
"DigitalSignature": true,
"KeyAgreement": true,
"KeyEncipherment": true
}
},
{
"Critical": false,
"Name": "extendedKeyUsage",
"OID": "2.5.29.37",
"Value": {
"Usages": [
"clientAuth"
]
}
},
{
"Critical": false,
"Name": "subjectAltName",
"OID": "2.5.29.17",
"Value": [
{
"Type": "dNSName",
"Value": "*.example.com"
}
]
}
],
"IssuerDN": "CN=TestCA,OU=CA,O=Example.com,L=Casacca,ST=PR,C=IT",
"MD5": "ac2fead0b8ac25a3633194b38ad91ca9",
"Name": [
"*.example.com",
"IAmADVCertificate"
],
"PEM": "-----BEGIN CERTIFICATE-----\nMIIDzjCCAbagAwIBAgIIXAVHw/CcpwowDQYJKoZIhvcNAQELBQAwYDELMAkGA1UE\nBhMCSVQxCzAJBgNVBAgTAlBSMRAwDgYDVQQHEwdDYXNhY2NhMRQwEgYDVQQKEwtF\neGFtcGxlLmNvbTELMAkGA1UECxMCQ0ExDzANBgNVBAMTBlRlc3RDQTAeFw0yNjEy\nMDIxNDQxMDBaFw0yMTEyMDIxNDQxMDBaMBwxGjAYBgNVBAMTEUlBbUFEVkNlcnRp\nZmljYXRlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEfWq17YxZZuf/jPU/to3HRumn\nv8/LgZQSwkKUNdXs6niQYplCHTGQW1g062EtrhDhrWXYDIR1wxxt139y+z3hs9KP\ngThaIkJNjFx8dVklvIWx16c6t4cujZSVr6/08TLOo34wfDAMBgNVHRMBAf8EAjAA\nMB0GA1UdDgQWBBQ/4S6mO5z4QU8LAB8u+orFvQ/HPDALBgNVHQ8EBAMCA7gwEwYD\nVR0lBAwwCgYIKwYBBQUHAwIwGAYDVR0RBBEwD4INKi5leGFtcGxlLmNvbTARBglg\nhkgBhvhCAQEEBAMCBaAwDQYJKoZIhvcNAQELBQADggIBAAEhwtW+srmNaTs1krrt\nxybcF23jDNzRv/2G91PHf0CxFq7BjHYYzF3CvvwaQfTXMKog6j5arenuKgLEPpO9\navXiAcPt7vy3bxqX8WP4xgjoaRcEglS0cwW7bc+wtQT2NzqCsiXqNeRSiHXanNLY\nBGOayOnulnWP9vuAHNhgTDgxvMphxNDYtY9MA1Qj+Bs0jIuRHdFWBTVXvPYaMr4/\nbtzhrJY7VeS47IXDyp9KZbczy+5LUSh7AdKjXOI/kG8MUlKvfw/Vy23rDIOwb/dM\n/PWnqkbTFZI6cBl5FxWh2i/MaYUvjaynS/6A1fZIsgnq9mcCO/Auzaw8pa4Zx55w\nnf5hHBtp/Ksc+0ayPgYmfYKNGYvu/DQW3gvMAigYYaLAIrykYbkDl7mmQgL9lBIT\nBpBN72+ho1oZWb7F8YrbPa4odu2PBxO8kuleQKMfW73rQVF9BWUoxk8oDdHFkeye\nA+saBni5EZyYyLDMJRB2R9h/6mC02JkCRceHf7STNxiTvHwew8eP7mTNfmyTJDND\nEsGgwQpK6w0ki3/kQ3pD8rFUtpnA3AqjB0BON6j+lSpyPx/2HvGSvSx3aT2B6apC\nnoZV/cVfp9txXt1CkRt3zLpdzbQWTrRUiL+L2EaLeHPd901NZG0voxVUP64TuouB\nSIzBSFl5/q4tqkY4D2Gv4gPX\n-----END CERTIFICATE-----\n",
"PublicKey": {
"Algorithm": "EC",
"Curve": "secp384r1",
"Length": 384,
"X": "7d:6a:b5:ed:8c:59:66:e7:ff:8c:f5:3f:b6:8d:c7:46:e9:a7:bf:cf:cb:81:94:12:c2:42:94:35:d5:ec:ea:78:90:62:99:42:1d:31:90:5b:58:34:eb:61:2d:ae:10:e1",
"Y": "ad:65:d8:0c:84:75:c3:1c:6d:d7:7f:72:fb:3d:e1:b3:d2:8f:81:38:5a:22:42:4d:8c:5c:7c:75:59:25:bc:85:b1:d7:a7:3a:b7:87:2e:8d:94:95:af:af:f4:f1:32:ce"
},
"SHA1": "18ac1daece43f5b769260adbabf763046ebda80e",
"SHA256": "869c151a7174f95a35b58c7aa900da5daed3723b63a31f08b89edd788653e402",
"SPKISHA256": "f2d670d5c0e7e3ba2fb928dc2533c0191a679170acd7dc9387130173492e4b18",
"SerialNumber": "6630784933253916426",
"Signature": {
"Algorithm": "sha256",
"Signature": "0121c2d5beb2b98d693b3592baedc726dc176de30cdcd1bffd86f753c77f40b116aec18c7618cc5dc2befc1a41f4d730aa20ea3e5aade9ee2a02c43e93bd6af5e201c3edeefcb76f1a97f163f8c608e86917048254b47305bb6dcfb0b504f6373a82b225ea35e4528875da9cd2d804639ac8e9ee96758ff6fb801cd8604c3831bcca61c4d0d8b58f4c035423f81b348c8b911dd156053557bcf61a32be3f6edce1ac963b55e4b8ec85c3ca9f4a65b733cbee4b51287b01d2a35ce23f906f0c5252af7f0fd5cb6deb0c83b06ff74cfcf5a7aa46d315923a7019791715a1da2fcc69852f8daca74bfe80d5f648b209eaf667023bf02ecdac3ca5ae19c79e709dfe611c1b69fcab1cfb46b23e06267d828d198beefc3416de0bcc02281861a2c022bca461b90397b9a64202fd94121306904def6fa1a35a1959bec5f18adb3dae2876ed8f0713bc92e95e40a31f5bbdeb41517d056528c64f280dd1c591ec9e03eb1a0678b9119c98c8b0cc25107647d87fea60b4d8990245c7877fb493371893bc7c1ec3c78fee64cd7e6c9324334312c1a0c10a4aeb0d248b7fe4437a43f2b154b699c0dc0aa307404e37a8fe952a723f1ff61ef192bd2c77693d81e9aa429e8655fdc55fa7db715edd42911b77ccba5dcdb4164eb45488bf8bd8468b7873ddf74d4d646d2fa315543fae13ba8b81488cc1485979feae2daa46380f61afe203d7"
},
"SubjectAlternativeName": [
{
"Type": "dNSName",
"Value": "*.example.com"
}
],
"SubjectDN": "CN=IAmADVCertificate",
"ValidityNotAfter": "2021-12-02T14:41:00.000Z",
"ValidityNotBefore": "2026-12-02T14:41:00.000Z"
},
"DBotScore": {
"Indicator": "869c151a7174f95a35b58c7aa900da5daed3723b63a31f08b89edd788653e402",
"Score": 0,
"Type": "certificate",
"Vendor": "X509Certificate"
}
}
Human Readable Output
Certificate decoded