001/**************************************************************** 002 * Licensed to the Apache Software Foundation (ASF) under one * 003 * or more contributor license agreements. See the NOTICE file * 004 * distributed with this work for additional information * 005 * regarding copyright ownership. The ASF licenses this file * 006 * to you under the Apache License, Version 2.0 (the * 007 * "License"); you may not use this file except in compliance * 008 * with the License. You may obtain a copy of the License at * 009 * * 010 * http://www.apache.org/licenses/LICENSE-2.0 * 011 * * 012 * Unless required by applicable law or agreed to in writing, * 013 * software distributed under the License is distributed on an * 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * 015 * KIND, either express or implied. See the License for the * 016 * specific language governing permissions and limitations * 017 * under the License. * 018 ****************************************************************/ 019 020package org.apache.james.user.lib.util; 021 022import javax.mail.MessagingException; 023import javax.mail.internet.MimeUtility; 024 025import java.io.ByteArrayOutputStream; 026import java.io.FileInputStream; 027import java.io.FileOutputStream; 028import java.io.IOException; 029import java.io.OutputStream; 030import java.security.MessageDigest; 031import java.security.NoSuchAlgorithmException; 032import java.util.Locale; 033 034/** 035 * Computes and verifies digests of files and strings 036 */ 037public class DigestUtil { 038 039 /** 040 * Command line interface. Use -help for arguments. 041 * 042 * @param args 043 * the arguments passed in on the command line 044 */ 045 public static void main(String[] args) { 046 047 String alg = "SHA"; 048 boolean file = false; 049 050 if (args.length == 0 || args.length > 4) { 051 printUsage(); 052 return; 053 } 054 055 for (int i = 0; i < args.length; i++) { 056 String currArg = args[i].toLowerCase(Locale.US); 057 if (currArg.equals("-help") || currArg.equals("-usage")) { 058 printUsage(); 059 return; 060 } 061 if (currArg.equals("-alg")) { 062 alg = args[i + 1]; 063 } 064 if (currArg.equals("-file")) { 065 file = true; 066 } 067 } 068 069 if (file) { 070 digestFile(args[args.length - 1], alg); 071 } else { 072 try { 073 String hash = digestString(args[args.length - 1], alg); 074 System.out.println("Hash is: " + hash); 075 } catch (NoSuchAlgorithmException nsae) { 076 System.out.println("No such algorithm available"); 077 } 078 } 079 } 080 081 /** 082 * Print the command line usage string. 083 */ 084 public static void printUsage() { 085 System.out.println("Usage: " + "java org.apache.james.security.DigestUtil" + " [-alg algorithm]" + " [-file] filename|string"); 086 } 087 088 /** 089 * Calculate digest of given file with given algorithm. Writes digest to 090 * file named filename.algorithm . 091 * 092 * @param filename 093 * the String name of the file to be hashed 094 * @param algorithm 095 * the algorithm to be used to compute the digest 096 */ 097 public static void digestFile(String filename, String algorithm) { 098 byte[] b = new byte[65536]; 099 int read; 100 FileInputStream fis = null; 101 FileOutputStream fos = null; 102 try { 103 MessageDigest md = MessageDigest.getInstance(algorithm); 104 fis = new FileInputStream(filename); 105 while (fis.available() > 0) { 106 read = fis.read(b); 107 md.update(b, 0, read); 108 } 109 byte[] digest = md.digest(); 110 String fileNameBuffer = filename + "." + algorithm; 111 fos = new FileOutputStream(fileNameBuffer); 112 OutputStream encodedStream = MimeUtility.encode(fos, "base64"); 113 encodedStream.write(digest); 114 fos.flush(); 115 } catch (Exception e) { 116 System.out.println("Error computing Digest: " + e); 117 } finally { 118 try { 119 fis.close(); 120 fos.close(); 121 } catch (Exception ignored) { 122 } 123 } 124 } 125 126 /** 127 * Calculate digest of given String using given algorithm. Encode digest in 128 * MIME-like base64. 129 * 130 * @param pass 131 * the String to be hashed 132 * @param algorithm 133 * the algorithm to be used 134 * @return String Base-64 encoding of digest 135 * 136 * @throws NoSuchAlgorithmException 137 * if the algorithm passed in cannot be found 138 */ 139 public static String digestString(String pass, String algorithm) throws NoSuchAlgorithmException { 140 141 MessageDigest md; 142 ByteArrayOutputStream bos; 143 144 try { 145 md = MessageDigest.getInstance(algorithm); 146 byte[] digest = md.digest(pass.getBytes("iso-8859-1")); 147 bos = new ByteArrayOutputStream(); 148 OutputStream encodedStream = MimeUtility.encode(bos, "base64"); 149 encodedStream.write(digest); 150 return bos.toString("iso-8859-1"); 151 } catch (IOException ioe) { 152 throw new RuntimeException("Fatal error: " + ioe); 153 } catch (MessagingException me) { 154 throw new RuntimeException("Fatal error: " + me); 155 } 156 } 157 158 /** 159 * Private constructor to prevent instantiation of the class 160 */ 161 private DigestUtil() { 162 } 163}