/** * Verifies the siganture * * @param digest input data digest * @param signature signature value * @param cert certificate to be used on verify * @return true if signature verifies */ public static boolean verify(byte[] digest, byte[] signature, X509Certificate cert) throws SignedDocException { boolean rc = false; try { // VS - for some reason this JDK internal method sometimes failes // System.out.println("Verify digest: " + bin2hex(digest) + // " signature: " + Base64Util.encode(signature, 0)); /* // check keystore... java.security.Signature sig = java.security.Signature.getInstance("SHA1withRSA"); sig.initVerify((java.security.interfaces.RSAPublicKey)cert.getPublicKey()); sig.update(digest); rc = sig.verify(signature); */ Cipher cryptoEngine = Cipher.getInstance( ConfigManager.instance().getProperty("DIGIDOC_VERIFY_ALGORITHM"), "BC"); cryptoEngine.init(Cipher.DECRYPT_MODE, cert); byte[] decryptedDigestValue = cryptoEngine.doFinal(signature); byte[] cdigest = new byte[digest.length]; System.arraycopy( decryptedDigestValue, decryptedDigestValue.length - digest.length, cdigest, 0, digest.length); // System.out.println("Decrypted digest: \'" + bin2hex(cdigest) + "\'"); // now compare the digests rc = compareDigests(digest, cdigest); // System.out.println("Result: " + rc); if (!rc) throw new SignedDocException( SignedDocException.ERR_VERIFY, "Invalid signature value!", null); } catch (SignedDocException ex) { throw ex; // pass it on, but check other exceptions } catch (Exception ex) { // System.out.println("Exception: " + ex); SignedDocException.handleException(ex, SignedDocException.ERR_VERIFY); } return rc; }
/** * Reads the cert from a file, URL or from another location somewhere in the CLASSPATH such as in * the librarys jar file. * * @param certLocation certificates file name, or URL. You can use url in form jar://<location> to * read a certificate from the car file or some other location in the CLASSPATH * @return certificate object */ public static X509Certificate readCertificate(String certLocation) throws SignedDocException { X509Certificate cert = null; try { InputStream isCert = null; URL url = null; if (certLocation.startsWith("http")) { url = new URL(certLocation); isCert = url.openStream(); } else if (certLocation.startsWith("jar://")) { ClassLoader cl = ConfigManager.instance().getClass().getClassLoader(); isCert = cl.getResourceAsStream(certLocation.substring(6)); } else { isCert = new FileInputStream(certLocation); } CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); cert = (X509Certificate) certificateFactory.generateCertificate(isCert); isCert.close(); } catch (Exception ex) { SignedDocException.handleException(ex, SignedDocException.ERR_READ_FILE); } return cert; }
/** * Adds a new Signature object by reading it from input stream. This method can be used for * example during mobile signing process where the web-service returns new signature in XML * * @param is input stream */ public void readSignature(InputStream is) throws SignedDocException { // ROB // DigiDocFactory ddfac = ConfigManager.instance().getDigiDocFactory(); DigiDocFactory ddfac = ConfigManager.instance().getSignedDocFactory(); Signature sig = ddfac.readSignature(this, is); }