Java tutorial
/* * Copyright 1999-2009 University of Chicago * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy * of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ package org.nimbustools.auto_common.ezpz_ca; import org.bouncycastle.asn1.DEREncodable; import org.bouncycastle.asn1.DEROutputStream; import org.bouncycastle.asn1.x509.X509Name; import org.bouncycastle.openssl.PEMReader; import org.bouncycastle.jce.provider.BouncyCastleProvider; import javax.security.auth.x500.X500Principal; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Principal; import java.security.Security; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; public class CertFilenameHash { private MessageDigest md5 = null; public CertFilenameHash() throws NoSuchAlgorithmException { this.md5 = MessageDigest.getInstance("MD5"); Security.addProvider(new BouncyCastleProvider()); } /** * Returns equivalent of: * openssl x509 -in "cert-file" -hash -noout * * @param subjectDN dn object * @return hash for certificate names * @throws java.io.IOException issue */ public String nameHash(Principal subjectDN) throws IOException { return hash(encodePrincipal(subjectDN)); } public static byte[] encodePrincipal(Principal subject) throws IOException { if (subject instanceof X500Principal) { return ((X500Principal) subject).getEncoded(); } else if (subject instanceof X509Name) { final ByteArrayOutputStream bout = new ByteArrayOutputStream(); final DEROutputStream der = new DEROutputStream(bout); final DEREncodable nm = (DEREncodable) subject; der.writeObject(nm.getDERObject()); return bout.toByteArray(); } else { throw new ClassCastException("unsupported input class: " + subject.getClass().toString()); } } private String hash(byte[] data) { this.md5.reset(); this.md5.update(data); final byte[] md = this.md5.digest(); final long ret = (fixByte(md[0]) | (fixByte(md[1]) << 8L) | fixByte(md[2]) << 16L | fixByte(md[3]) << 24L) & 0xffffffffL; return Long.toHexString(ret); } private static long fixByte(byte b) { return (b < 0) ? (long) (b + 256) : (long) b; } public String hashFromPath(String existingFile) throws IOException, CertificateException, NoSuchProviderException { final File certFile = new File(existingFile); if (!certFile.canRead()) { final String msg = "File '" + existingFile + "' can not be read."; throw new IOException(msg); } final FileReader fr = new FileReader(certFile); try { final PEMReader reader = new PEMReader(fr, null, BouncyCastleProvider.PROVIDER_NAME); try { final X509Certificate cert = (X509Certificate) reader.readObject(); return this.nameHash(cert.getSubjectDN()); } finally { reader.close(); } } finally { fr.close(); } } // ------------------------------------------------------------------------- // MAIN // ------------------------------------------------------------------------- public static void main(String[] args) { if (args == null || args.length != 1) { System.err.println("Needs these arguments:\n" + "1 - the cert file you want hashed name of"); System.exit(1); } try { final String newhex = new CertFilenameHash().hashFromPath(args[0]); System.out.println(newhex); } catch (Exception e) { System.err.println("Problem: " + e.getMessage()); e.printStackTrace(); System.exit(1); } } }