public static void main(String args[]) throws Exception { // 参数 String cacert = args[0]; String lfcert = args[1]; // CA "Xu Yingxiao"的证书 CertificateFactory cf = CertificateFactory.getInstance("X.509"); FileInputStream in1 = new FileInputStream(cacert); java.security.cert.Certificate cac = cf.generateCertificate(in1); in1.close(); // 用户"Liu Fang"的签名证书 FileInputStream in2 = new FileInputStream(lfcert); java.security.cert.Certificate lfc = cf.generateCertificate(in2); in2.close(); PublicKey pbk = cac.getPublicKey(); boolean pass = false; try { lfc.verify(pbk); pass = true; } catch (Exception e) { pass = false; System.out.println(e); } if (pass) { System.out.println("The Certificate is signed by the CA Xu Yingxiao"); } else { System.out.println("!!!The Certificate is not signed by the CA Xu Yingxiao"); } }
/** * Callback method from _scanKeychain. If a trusted certificate is found, this method will be * called. */ private void createTrustedCertEntry( String alias, long keychainItemRef, long creationDate, byte[] derStream) { TrustedCertEntry tce = new TrustedCertEntry(); try { CertificateFactory cf = CertificateFactory.getInstance("X.509"); InputStream input = new ByteArrayInputStream(derStream); X509Certificate cert = (X509Certificate) cf.generateCertificate(input); input.close(); tce.cert = cert; tce.certRef = keychainItemRef; // Make a creation date. if (creationDate != 0) tce.date = new Date(creationDate); else tce.date = new Date(); int uniqueVal = 1; String originalAlias = alias; while (entries.containsKey(alias.toLowerCase())) { alias = originalAlias + " " + uniqueVal; uniqueVal++; } entries.put(alias.toLowerCase(), tce); } catch (Exception e) { // The certificate will be skipped. System.err.println("KeychainStore Ignored Exception: " + e); } }
MyX509TrustManager() throws java.security.GeneralSecurityException { TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX"); KeyStore ks = KeyStore.getInstance("JKS"); CertificateFactory cf = CertificateFactory.getInstance("X.509"); try { ks.load(null, null); File cacert = new File(cafile); if (!cacert.exists() || !cacert.canRead()) return; InputStream caStream = new FileInputStream(cafile); X509Certificate ca = (X509Certificate) cf.generateCertificate(caStream); ks.setCertificateEntry("CA", ca); PKIXBuilderParameters params = new PKIXBuilderParameters(ks, new X509CertSelector()); File crlcert = new File(crlfile); if (!crlcert.exists() || !crlcert.canRead()) { params.setRevocationEnabled(false); } else { InputStream crlStream = new FileInputStream(crlfile); Collection<? extends CRL> crls = cf.generateCRLs(crlStream); CertStoreParameters csp = new CollectionCertStoreParameters(crls); CertStore store = CertStore.getInstance("Collection", csp); params.addCertStore(store); params.setRevocationEnabled(true); } tmf.init(new CertPathTrustManagerParameters(params)); } catch (java.io.FileNotFoundException e) { vlog.error(e.toString()); } catch (java.io.IOException e) { vlog.error(e.toString()); } tm = (X509TrustManager) tmf.getTrustManagers()[0]; }
private void initCommon() { if (TRY_VALIDATOR == false) { return; } trustedSubjects = new HashMap<X500Principal, List<PublicKey>>(); for (Iterator t = trustedCerts.iterator(); t.hasNext(); ) { X509Certificate cert = (X509Certificate) t.next(); X500Principal dn = cert.getSubjectX500Principal(); List<PublicKey> keys; if (trustedSubjects.containsKey(dn)) { keys = trustedSubjects.get(dn); } else { keys = new ArrayList<PublicKey>(); trustedSubjects.put(dn, keys); } keys.add(cert.getPublicKey()); } try { factory = CertificateFactory.getInstance("X.509"); } catch (CertificateException e) { throw new RuntimeException("Internal error", e); } plugin = variant.equals(VAR_PLUGIN_CODE_SIGNING); }
private X509Certificate[] doValidate(X509Certificate[] chain, PKIXBuilderParameters params) throws CertificateException { try { setDate(params); // do the validation CertPathValidator validator = CertPathValidator.getInstance("PKIX"); CertPath path = factory.generateCertPath(Arrays.asList(chain)); certPathLength = chain.length; PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult) validator.validate(path, params); return toArray(path, result.getTrustAnchor()); } catch (GeneralSecurityException e) { if (e instanceof CertPathValidatorException) { // check cause Throwable cause = e.getCause(); if (cause != null && cause instanceof OCSPResponse.UnreliableException) { throw new ValidatorException(ValidatorException.T_OCSP_RESPONSE_UNRELIABLE); } } throw new ValidatorException("PKIX path validation failed: " + e.toString(), e); } }
/** * Callback method from _scanKeychain. If an identity is found, this method will be called to * create Java certificate and private key objects from the keychain data. */ private void createKeyEntry( String alias, long creationDate, long secKeyRef, long[] secCertificateRefs, byte[][] rawCertData) throws IOException, NoSuchAlgorithmException, UnrecoverableKeyException { KeyEntry ke = new KeyEntry(); // First, store off the private key information. This is the easy part. ke.protectedPrivKey = null; ke.keyRef = secKeyRef; // Make a creation date. if (creationDate != 0) ke.date = new Date(creationDate); else ke.date = new Date(); // Next, create X.509 Certificate objects from the raw data. This is complicated // because a certificate's public key may be too long for Java's default encryption strength. List<CertKeychainItemPair> createdCerts = new ArrayList<>(); try { CertificateFactory cf = CertificateFactory.getInstance("X.509"); for (int i = 0; i < rawCertData.length; i++) { try { InputStream input = new ByteArrayInputStream(rawCertData[i]); X509Certificate cert = (X509Certificate) cf.generateCertificate(input); input.close(); // We successfully created the certificate, so track it and its corresponding // SecCertificateRef. createdCerts.add(new CertKeychainItemPair(secCertificateRefs[i], cert)); } catch (CertificateException e) { // The certificate will be skipped. System.err.println("KeychainStore Ignored Exception: " + e); } } } catch (CertificateException e) { e.printStackTrace(); } catch (IOException ioe) { ioe.printStackTrace(); // How would this happen? } // We have our certificates in the List, so now extract them into an array of // Certificates and SecCertificateRefs. CertKeychainItemPair[] objArray = createdCerts.toArray(new CertKeychainItemPair[0]); Certificate[] certArray = new Certificate[objArray.length]; long[] certRefArray = new long[objArray.length]; for (int i = 0; i < objArray.length; i++) { CertKeychainItemPair addedItem = objArray[i]; certArray[i] = addedItem.mCert; certRefArray[i] = addedItem.mCertificateRef; } ke.chain = certArray; ke.chainRefs = certRefArray; // If we don't have already have an item with this item's alias // create a new one for it. int uniqueVal = 1; String originalAlias = alias; while (entries.containsKey(alias.toLowerCase())) { alias = originalAlias + " " + uniqueVal; uniqueVal++; } entries.put(alias.toLowerCase(), ke); }
/** * Uses the provided PKI method to find the corresponding public key and verify the provided * signature. * * @param paymentRequest Payment request to verify. * @param trustStore KeyStore of trusted root certificate authorities. * @return verification data, or null if no PKI method was specified in the {@link * Protos.PaymentRequest}. * @throws PaymentProtocolException if payment request could not be verified. */ @Nullable public static PkiVerificationData verifyPaymentRequestPki( Protos.PaymentRequest paymentRequest, KeyStore trustStore) throws PaymentProtocolException { List<X509Certificate> certs = null; try { final String pkiType = paymentRequest.getPkiType(); if ("none".equals(pkiType)) // Nothing to verify. Everything is fine. Move along. return null; String algorithm; if ("x509+sha256".equals(pkiType)) algorithm = "SHA256withRSA"; else if ("x509+sha1".equals(pkiType)) algorithm = "SHA1withRSA"; else throw new PaymentProtocolException.InvalidPkiType("Unsupported PKI type: " + pkiType); Protos.X509Certificates protoCerts = Protos.X509Certificates.parseFrom(paymentRequest.getPkiData()); if (protoCerts.getCertificateCount() == 0) throw new PaymentProtocolException.InvalidPkiData( "No certificates provided in message: server config error"); // Parse the certs and turn into a certificate chain object. Cert factories can parse both DER // and base64. // The ordering of certificates is defined by the payment protocol spec to be the same as what // the Java // crypto API requires - convenient! CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); certs = Lists.newArrayList(); for (ByteString bytes : protoCerts.getCertificateList()) certs.add((X509Certificate) certificateFactory.generateCertificate(bytes.newInput())); CertPath path = certificateFactory.generateCertPath(certs); // Retrieves the most-trusted CAs from keystore. PKIXParameters params = new PKIXParameters(trustStore); // Revocation not supported in the current version. params.setRevocationEnabled(false); // Now verify the certificate chain is correct and trusted. This let's us get an identity // linked pubkey. CertPathValidator validator = CertPathValidator.getInstance("PKIX"); PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult) validator.validate(path, params); PublicKey publicKey = result.getPublicKey(); // OK, we got an identity, now check it was used to sign this message. Signature signature = Signature.getInstance(algorithm); // Note that we don't use signature.initVerify(certs.get(0)) here despite it being the most // obvious // way to set it up, because we don't care about the constraints specified on the // certificates: any // cert that links a key to a domain name or other identity will do for us. signature.initVerify(publicKey); Protos.PaymentRequest.Builder reqToCheck = paymentRequest.toBuilder(); reqToCheck.setSignature(ByteString.EMPTY); signature.update(reqToCheck.build().toByteArray()); if (!signature.verify(paymentRequest.getSignature().toByteArray())) throw new PaymentProtocolException.PkiVerificationException( "Invalid signature, this payment request is not valid."); // Signature verifies, get the names from the identity we just verified for presentation to // the user. final X509Certificate cert = certs.get(0); String displayName = X509Utils.getDisplayNameFromCertificate(cert, true); if (displayName == null) throw new PaymentProtocolException.PkiVerificationException( "Could not extract name from certificate"); // Everything is peachy. Return some useful data to the caller. return new PkiVerificationData(displayName, publicKey, result.getTrustAnchor()); } catch (InvalidProtocolBufferException e) { // Data structures are malformed. throw new PaymentProtocolException.InvalidPkiData(e); } catch (CertificateException e) { // The X.509 certificate data didn't parse correctly. throw new PaymentProtocolException.PkiVerificationException(e); } catch (NoSuchAlgorithmException e) { // Should never happen so don't make users have to think about it. PKIX is always present. throw new RuntimeException(e); } catch (InvalidAlgorithmParameterException e) { throw new RuntimeException(e); } catch (CertPathValidatorException e) { // The certificate chain isn't known or trusted, probably, the server is using an SSL root we // don't // know about and the user needs to upgrade to a new version of the software (or import a root // cert). throw new PaymentProtocolException.PkiVerificationException(e, certs); } catch (InvalidKeyException e) { // Shouldn't happen if the certs verified correctly. throw new PaymentProtocolException.PkiVerificationException(e); } catch (SignatureException e) { // Something went wrong during hashing (yes, despite the name, this does not mean the sig was // invalid). throw new PaymentProtocolException.PkiVerificationException(e); } catch (KeyStoreException e) { throw new RuntimeException(e); } }
/** * Uses the provided PKI method to find the corresponding public key and verify the provided * signature. Returns null if no PKI method was specified in the {@link Protos.PaymentRequest}. */ public @Nullable PkiVerificationData verifyPki() throws PaymentRequestException { try { if (pkiVerificationData != null) return pkiVerificationData; if (paymentRequest.getPkiType().equals("none")) // Nothing to verify. Everything is fine. Move along. return null; String algorithm; if (paymentRequest.getPkiType().equals("x509+sha256")) algorithm = "SHA256withRSA"; else if (paymentRequest.getPkiType().equals("x509+sha1")) algorithm = "SHA1withRSA"; else throw new PaymentRequestException.InvalidPkiType( "Unsupported PKI type: " + paymentRequest.getPkiType()); Protos.X509Certificates protoCerts = Protos.X509Certificates.parseFrom(paymentRequest.getPkiData()); if (protoCerts.getCertificateCount() == 0) throw new PaymentRequestException.InvalidPkiData( "No certificates provided in message: server config error"); // Parse the certs and turn into a certificate chain object. Cert factories can parse both DER // and base64. // The ordering of certificates is defined by the payment protocol spec to be the same as what // the Java // crypto API requires - convenient! CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); List<X509Certificate> certs = Lists.newArrayList(); for (ByteString bytes : protoCerts.getCertificateList()) certs.add((X509Certificate) certificateFactory.generateCertificate(bytes.newInput())); CertPath path = certificateFactory.generateCertPath(certs); // Retrieves the most-trusted CAs from keystore. PKIXParameters params = new PKIXParameters(createKeyStore(trustStorePath)); // Revocation not supported in the current version. params.setRevocationEnabled(false); // Now verify the certificate chain is correct and trusted. This let's us get an identity // linked pubkey. CertPathValidator validator = CertPathValidator.getInstance("PKIX"); PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult) validator.validate(path, params); PublicKey publicKey = result.getPublicKey(); // OK, we got an identity, now check it was used to sign this message. Signature signature = Signature.getInstance(algorithm); // Note that we don't use signature.initVerify(certs.get(0)) here despite it being the most // obvious // way to set it up, because we don't care about the constraints specified on the // certificates: any // cert that links a key to a domain name or other identity will do for us. signature.initVerify(publicKey); Protos.PaymentRequest.Builder reqToCheck = paymentRequest.toBuilder(); reqToCheck.setSignature(ByteString.EMPTY); signature.update(reqToCheck.build().toByteArray()); if (!signature.verify(paymentRequest.getSignature().toByteArray())) throw new PaymentRequestException.PkiVerificationException( "Invalid signature, this payment request is not valid."); // Signature verifies, get the names from the identity we just verified for presentation to // the user. X500Principal principal = certs.get(0).getSubjectX500Principal(); // At this point the Java crypto API falls flat on its face and dies - there's no clean way to // get the // different parts of the certificate name except for parsing the string. That's hard because // of various // custom escaping rules and the usual crap. So, use Bouncy Castle to re-parse the string into // binary form // again and then look for the names we want. Fail! org.spongycastle.asn1.x500.X500Name name = new X500Name(principal.getName()); String entityName = null, orgName = null; for (RDN rdn : name.getRDNs()) { AttributeTypeAndValue pair = rdn.getFirst(); if (pair.getType().equals(RFC4519Style.cn)) entityName = ((ASN1String) pair.getValue()).getString(); else if (pair.getType().equals(RFC4519Style.o)) orgName = ((ASN1String) pair.getValue()).getString(); } if (entityName == null && orgName == null) throw new PaymentRequestException.PkiVerificationException( "Invalid certificate, no CN or O fields"); // Everything is peachy. Return some useful data to the caller. PkiVerificationData data = new PkiVerificationData(entityName, orgName, publicKey, result.getTrustAnchor()); // Cache the result so we don't have to re-verify if this method is called again. pkiVerificationData = data; return data; } catch (InvalidProtocolBufferException e) { // Data structures are malformed. throw new PaymentRequestException.InvalidPkiData(e); } catch (CertificateException e) { // The X.509 certificate data didn't parse correctly. throw new PaymentRequestException.PkiVerificationException(e); } catch (NoSuchAlgorithmException e) { // Should never happen so don't make users have to think about it. PKIX is always present. throw new RuntimeException(e); } catch (InvalidAlgorithmParameterException e) { throw new RuntimeException(e); } catch (CertPathValidatorException e) { // The certificate chain isn't known or trusted, probably, the server is using an SSL root we // don't // know about and the user needs to upgrade to a new version of the software (or import a root // cert). throw new PaymentRequestException.PkiVerificationException(e); } catch (InvalidKeyException e) { // Shouldn't happen if the certs verified correctly. throw new PaymentRequestException.PkiVerificationException(e); } catch (SignatureException e) { // Something went wrong during hashing (yes, despite the name, this does not mean the sig was // invalid). throw new PaymentRequestException.PkiVerificationException(e); } catch (IOException e) { throw new PaymentRequestException.PkiVerificationException(e); } catch (KeyStoreException e) { throw new RuntimeException(e); } }