Oracle Forms应用因JAR签名证书不一致被Java拦截,如何排查差异JAR?
Got it, let's figure out how to spot that mismatched JAR without relying on jarsigner. Here are a few practical, straightforward approaches you can try right away:
keytool with a simple script keytool comes pre-installed with every JDK, and it's totally separate from jarsigner. You can whip up a quick script to scan all your JARs, pull their certificate fingerprints, and flag any that don't match the rest.
For Windows (batch script):
Create a file named check_signatures.bat in your JAR directory, paste this in, and run it:
@echo off setlocal enabledelayedexpansion set "first_fingerprint=" for %%f in (*.jar) do ( echo Checking %%f... :: Grab the SHA-256 fingerprint and strip out spaces/colons for /f "tokens=2 delims=:" %%g in ('keytool -printcert -jarfile "%%f" ^| findstr /i "SHA-256"') do ( set "current_fingerprint=%%g" set "current_fingerprint=!current_fingerprint: =!" set "current_fingerprint=!current_fingerprint::=!" if not defined first_fingerprint ( set "first_fingerprint=!current_fingerprint!" echo Reference fingerprint: !first_fingerprint! ) else ( if not "!current_fingerprint!"=="!first_fingerprint!" ( echo ⚠️ WARNING: %%f has a mismatched signature! ) ) ) ) endlocal
For Linux/macOS (shell script):
Save this as check_signatures.sh, run chmod +x check_signatures.sh, then execute it:
#!/bin/bash # Get the fingerprint from the first JAR as our reference first_jar=$(ls *.jar | head -n1) first_fingerprint=$(keytool -printcert -jarfile "$first_jar" | grep -i SHA-256 | awk '{print $3}' | tr -d ':') echo "Reference fingerprint (from $first_jar): $first_fingerprint" for jar in *.jar; do echo "Checking $jar..." current_fingerprint=$(keytool -printcert -jarfile "$jar" | grep -i SHA-256 | awk '{print $3}' | tr -d ':') if [ "$current_fingerprint" != "$first_fingerprint" ]; then echo "⚠️ MISMATCH FOUND: $jar has a different signature!" fi done
Every signed JAR has signature-related files in its META-INF folder — usually a .SF file and a .RSA/.DSA file. You can use any compression tool (WinRAR, 7-Zip, even macOS's built-in Archive Utility) to check these:
- Open the JAR file with your compression tool
- Navigate to the
META-INFdirectory - Double-click the
.RSA/.DSAfile (7-Zip will show you the certificate details directly; other tools might let you view the certificate info via a right-click menu) - Compare the issuer name, serial number, and SHA fingerprint across all JARs. The one that doesn't match is your culprit.
This is perfect if you only have a handful of JARs to check — no scripting required, just visual comparison.
If you're comfortable with Java, a tiny program can scan all JARs in a directory and flag mismatches automatically:
import java.io.File; import java.security.MessageDigest; import java.security.cert.Certificate; import java.util.jar.JarFile; public class JarSignatureChecker { public static void main(String[] args) { File jarDir = new File("."); File[] jarFiles = jarDir.listFiles((dir, name) -> name.toLowerCase().endsWith(".jar")); if (jarFiles == null || jarFiles.length == 0) { System.out.println("No JAR files found in the current directory."); return; } // Get reference fingerprint from first JAR String referenceHash = getCertificateHash(jarFiles[0]); System.out.printf("Reference signature hash (from %s): %s%n", jarFiles[0].getName(), referenceHash); // Check all other JARs for (File jar : jarFiles) { String currentHash = getCertificateHash(jar); if (!currentHash.equals(referenceHash)) { System.out.printf("❌ Mismatch detected: %s has a different signature%n", jar.getName()); } } } private static String getCertificateHash(File jarFile) { try (JarFile jar = new JarFile(jarFile)) { // Grab the first certificate from the JAR (signed JARs have at least one) Certificate[] certs = jar.getEntryCertificates(jar.entries().nextElement()); if (certs != null && certs.length > 0) { MessageDigest md = MessageDigest.getInstance("SHA-256"); byte[] digest = md.digest(certs[0].getEncoded()); // Convert digest to hex string StringBuilder hexString = new StringBuilder(); for (byte b : digest) { String hex = Integer.toHexString(0xff & b); if (hex.length() == 1) hexString.append('0'); hexString.append(hex); } return hexString.toString(); } } catch (Exception e) { System.out.printf("Error checking %s: %s%n", jarFile.getName(), e.getMessage()); } return ""; } }
Compile and run this in your JAR directory — it'll instantly point out any JAR with a mismatched signature.
All these methods avoid jarsigner entirely, so you should be able to track down that problematic JAR in no time.
内容的提问来源于stack exchange,提问作者m.weiloa

