メインコンテンツまでスキップ

Binaries and Compiled Artefacts

適用対象:
ELF, PE / COFF, Mach-O (including universal binaries).NET assembliesJava classes, JAR / WAR / EAR (nested)Bundled keystores

Overview​

The binary scan finds cryptography inside compiled artefacts. It complements the source code scan, which needs the source, and the container image scan, which on its own sees package names, libraries and configuration files.

Nothing is executed or loaded. Files are read as bytes and parsed with read-only parsers for ELF, PE / COFF and Mach-O, plus a bounded reader for Java class files and .NET metadata.

What is read​

ArtefactEvidenceConfidence
ELF, PE / COFF, Mach-OLinked crypto libraries: ELF DT_NEEDED entries, PE import and delay-import tables, Mach-O dylib load commands. OpenSSL, BoringSSL, LibreSSL, libgcrypt, libsodium, Mbed TLS, wolfSSL, GnuTLS, NSS, CommonCrypto, Security.framework, Windows CNG (bcrypt.dll, ncrypt.dll), crypt32.dll and the advapi32.dll Crypt* functions.import
Imported, dynamic and (when the binary is not stripped) static symbols mapped to algorithms, for example RSA_*, EC_KEY_*, ECDSA_*, DH_*, EVP_md5, mbedtls_*, wc_*, crypto_sign_*, BCryptSecretAgreement, CryptGenKey, CC_MD5, SecKeyCreate*.symbol
Embedded OIDs: RSA and its signature OIDs, EC public key, ECDSA, DSA, DH, MD5, SHA-1, ML-DSA, SLH-DSA and ML-KEM. PQC algorithm names such as ML-KEM-768, ML-DSA-65 or X25519MLKEM768.constant
Windows CNG algorithm identifiers (RSA, ECDH_P256, ML-KEM...), counted only when the image actually uses CNG.constant
Library version strings (OpenSSL 1.1.1w, LibreSSL, BoringSSL, Mbed TLS, wolfSSL). When the library is not dynamically linked, it is reported as statically linked.constant
.NET assembliesCrypto type names from the assembly metadata (RSACryptoServiceProvider, RSACng, ECDsa, ECDiffieHellman, DSA, MD5, SHA1, TripleDES, MLDsa, MLKem, SlhDsa...), only when the assembly references System.Security.Cryptography.symbol
Java class, JAR / WAR / EARArchives are opened recursively, including nested libraries (WEB-INF/lib, BOOT-INF/lib...). Class references to javax.crypto, java.security (KeyPairGenerator, Signature, MessageDigest, KeyFactory, KeyStore...) and Bouncy Castle; the algorithm is taken from the class name (RSAPublicKey, ECGenParameterSpec, MLDSA*...).symbol
String constants passed to the Java crypto API ("RSA", "RSA/ECB/OAEPWith...", "SHA1withRSA", "EC", "DESede", "MD5", "ML-DSA-65", "ML-KEM-768"...), only in classes that use a crypto API. JAR signature blocks (META-INF/*.RSA, *.DSA, *.EC); Bouncy Castle identified from the manifest.constant
KeystoresKeystores bundled in archives (.jks, .jceks, .p12, .pfx, .keystore, .truststore) are reported as keystore findings; PKCS#12 files are parsed.-
Native libraries in archives.so, .dll, .dylib and .jnilib files inside an archive are scanned as native artefacts.as above

The classes of a crypto provider itself (Bouncy Castle) are reported once, as a library, rather than as every algorithm the provider implements.

Confidence levels​

Every finding carries the strongest confidence seen for that artefact and algorithm:

LevelMeaningConfidence score
importThe artefact links a crypto library or uses a crypto API family. Which algorithm it uses is not established.0.5
symbolThe artefact references an algorithm-specific function, class or type.0.7
constantThe artefact embeds a constant naming the algorithm: OID, algorithm identifier, Java transformation string, signature block or library version string.0.9

Findings and CBOM​

  • One finding per artefact and algorithm, and per artefact and library, with up to eight lines of evidence (for example [symbol] imports RSA_new from libcrypto.so.3, or [constant] com/acme/Signer passes "SHA1withRSA").
  • The location is the artefact path; members of an archive are shown with !/, for example app.war!/WEB-INF/lib/legacy.jar.
  • Algorithm, library, confidence and evidence feed the CycloneDX CBOM exactly like source-code findings.
  • Risk: RSA, ECC, DH, DSA, Ed25519 and X25519 are quantum-vulnerable (High at symbol or constant, Medium at import); MD5, SHA-1, DES, 3DES, RC4 and RC2 are reported as classically weak (Medium); ML-KEM, ML-DSA and SLH-DSA as quantum-safe (Info); AES, SHA-2 and ChaCha20 as Low; a library seen without a specific algorithm as Info.

How to run​

WhereHow
Cockpit UIIn PQC Readiness, create a new scan and choose Binaries & Artefacts, then upload one file (up to 24 MiB).
Scanner agentThe binary command scans a file or a whole directory on the machine that holds the files.
Filesystem scanAdd --binaries to the agent's filesystem command to examine compiled artefacts during the certificate and keystore sweep.
Container image scansAutomatic: every Docker, OCI registry and Harbor image scan also runs the binary scan over the image file system. Results appear per container under Crypto in compiled artefacts and in the JSON report.
REST APIPOST /api/pqc/scans with scan_type: "binary", the file in options.artifact_data (base64) and its name in options.artifact_name. Up to 24 MiB.
Scanner agentBASH
# One file or a whole directory
dke-scanner-agent binary ./dist --format summary
dke-scanner-agent binary /opt/app/app.war --output app-binary.json

# Certificate and keystore sweep plus compiled artefacts
dke-scanner-agent filesystem --path /opt/app --binaries
Agent option (binary)DescriptionDefault
<path>File or directory to scan-
--max-depth <N>Maximum directory depth (0 = unlimited)12
--exclude <LIST>Comma-separated path substrings to skip.git,node_modules
--max-file-mb <MiB>Largest file read128
--timeout <SECS>Time budget for the whole scan300
--format <FMT>json or summaryjson
-o, --output <FILE>Write to a file instead of standard output-
Uploads only through the Cockpit

The Cockpit never reads a path on its own host for this scan: over the UI and the API the artefact is always an upload, as for packet captures. Larger artefacts and whole directories go through the scanner agent, which runs on the machine that holds the files.

Safety caps​

Every limit is enforced. A limit that is hit is recorded as a note on the scan, so a partial result shows as partial.

LimitScanner agentCockpit upload
File read from disk128 MiB (--max-file-mb)24 MiB (upload cap)
Decompressed size of one archive entry32 MiB32 MiB
Uncompressed bytes per top-level archive (nested included)512 MiB256 MiB
Entries per top-level archive (nested included)50,00030,000
Archive nesting depth33
Compression ratio per entry100:1 (above: refused as a decompression bomb)same
Files examined per directory walk20,000n/a
Symbols per native object500,000same
Total time300 s (--timeout)120 s

The declared size of an archive entry is checked before reading and the actual read is capped too, so an entry that lies about its size cannot grow past the limit. Directory walks never follow symbolic links.

Limits​

Read the results as evidence, not as a call graph

The scan shows what an artefact links, references or embeds. It does not trace which code paths call which algorithm at run time.

LimitDetails
Stripped, statically linked binariesWithout a symbol table, a statically linked library is found only through its version string and its compiled-in OID table. Both show that the library is present and what it can do, not which algorithms the program calls. A crypto library's own OID table lists every algorithm it supports, so constant-level evidence from a crypto library means capability, not use.
Obfuscated, packed or encrypted codePacked executables (for example UPX), Java string encryption (ProGuard / R8), .NET obfuscators and native packers hide symbols and constants. The scanner reports what is visible and does not unpack.
.NET depthOnly type names from the metadata are read. Method bodies (IL), user strings (such as algorithm names passed as strings) and native imports declared with DllImport are not analysed. Native AOT and ReadyToRun images are treated as native code.
Java depthString constants are attributed to the class that holds them, not to the call site. A value built at run time (concatenation, configuration file) is not seen. Kotlin and Scala are covered, because they compile to the same class format.
Dynamic loadingLibraries loaded at run time (dlopen, LoadLibrary, Java crypto providers chosen by configuration) leave no import entry.
Formats not coveredWebAssembly, Python bytecode, Go and Rust module metadata, static .a / .lib archives and firmware images. Go and Rust binaries are still analysed as ordinary ELF / PE / Mach-O.
Short OIDsEd25519 and X25519 OIDs are too short to match safely; these algorithms are found through symbols and names instead.
Cockpit uploadsOne file of at most 24 MiB per scan. Use the scanner agent for larger artefacts and directories.