1 /************************************************************************ 2 * Copyright (c) 2000-2006 The Apache Software Foundation. * 3 * All rights reserved. * 4 * ------------------------------------------------------------------- * 5 * Licensed under the Apache License, Version 2.0 (the "License"); you * 6 * may not use this file except in compliance with the License. You * 7 * may obtain a copy of the License at: * 8 * * 9 * http://www.apache.org/licenses/LICENSE-2.0 * 10 * * 11 * Unless required by applicable law or agreed to in writing, software * 12 * distributed under the License is distributed on an "AS IS" BASIS, * 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * 14 * implied. See the License for the specific language governing * 15 * permissions and limitations under the License. * 16 ***********************************************************************/ 17 18 package org.apache.james.security; 19 20 import javax.mail.MessagingException; 21 import javax.mail.internet.MimeUtility; 22 23 import java.io.ByteArrayOutputStream; 24 import java.io.FileInputStream; 25 import java.io.FileOutputStream; 26 import java.io.IOException; 27 import java.io.OutputStream; 28 import java.security.MessageDigest; 29 import java.security.NoSuchAlgorithmException; 30 import java.util.Locale; 31 32 33 /*** 34 * Computes and verifies digests of files and strings 35 * 36 * 37 * @version $Revision: 365582 $ 38 */ 39 public class DigestUtil { 40 41 /*** 42 * Command line interface. Use -help for arguments. 43 * 44 * @param args the arguments passed in on the command line 45 */ 46 public static void main(String[] args) { 47 48 String alg = "SHA"; 49 boolean file = false; 50 51 if (args.length == 0 || args.length > 4) { 52 printUsage(); 53 return; 54 } 55 56 for (int i = 0; i < args.length; i++) { 57 String currArg = args[i].toLowerCase(Locale.US); 58 if (currArg.equals("-help") 59 || currArg.equals("-usage")) { 60 printUsage(); 61 return; 62 } 63 if (currArg.equals("-alg")) { 64 alg = args[i+1]; 65 } 66 if (currArg.equals("-file")) { 67 file = true; 68 } 69 } 70 71 if (file) { 72 digestFile(args[args.length - 1], alg); 73 return ; 74 } else { 75 try { 76 String hash = digestString(args[args.length - 1], alg); 77 System.out.println("Hash is: " + hash); 78 return; 79 } catch (NoSuchAlgorithmException nsae) { 80 System.out.println("No such algorithm available"); 81 } 82 } 83 } 84 85 /*** 86 * Print the command line usage string. 87 */ 88 public static void printUsage() { 89 System.out.println("Usage: " 90 + "java org.apache.james.security.DigestUtil" 91 + " [-alg algorithm]" 92 + " [-file] filename|string"); 93 } 94 95 /*** 96 * Calculate digest of given file with given algorithm. 97 * Writes digest to file named filename.algorithm . 98 * 99 * @param filename the String name of the file to be hashed 100 * @param algorithm the algorithm to be used to compute the digest 101 */ 102 public static void digestFile(String filename, String algorithm) { 103 byte[] b = new byte[65536]; 104 int count = 0; 105 int read = 0; 106 FileInputStream fis = null; 107 FileOutputStream fos = null; 108 try { 109 MessageDigest md = MessageDigest.getInstance(algorithm); 110 fis = new FileInputStream(filename); 111 while (fis.available() > 0) { 112 read = fis.read(b); 113 md.update(b, 0, read); 114 count += read; 115 } 116 byte[] digest = md.digest(); 117 StringBuffer fileNameBuffer = 118 new StringBuffer(128) 119 .append(filename) 120 .append(".") 121 .append(algorithm); 122 fos = new FileOutputStream(fileNameBuffer.toString()); 123 OutputStream encodedStream = MimeUtility.encode(fos, "base64"); 124 encodedStream.write(digest); 125 fos.flush(); 126 } catch (Exception e) { 127 System.out.println("Error computing Digest: " + e); 128 } finally { 129 try { 130 fis.close(); 131 fos.close(); 132 } catch (Exception ignored) {} 133 } 134 } 135 136 /*** 137 * Calculate digest of given String using given algorithm. 138 * Encode digest in MIME-like base64. 139 * 140 * @param pass the String to be hashed 141 * @param algorithm the algorithm to be used 142 * @return String Base-64 encoding of digest 143 * 144 * @throws NoSuchAlgorithmException if the algorithm passed in cannot be found 145 */ 146 public static String digestString(String pass, String algorithm ) 147 throws NoSuchAlgorithmException { 148 149 MessageDigest md; 150 ByteArrayOutputStream bos; 151 152 try { 153 md = MessageDigest.getInstance(algorithm); 154 byte[] digest = md.digest(pass.getBytes("iso-8859-1")); 155 bos = new ByteArrayOutputStream(); 156 OutputStream encodedStream = MimeUtility.encode(bos, "base64"); 157 encodedStream.write(digest); 158 return bos.toString("iso-8859-1"); 159 } catch (IOException ioe) { 160 throw new RuntimeException("Fatal error: " + ioe); 161 } catch (MessagingException me) { 162 throw new RuntimeException("Fatal error: " + me); 163 } 164 } 165 166 /*** 167 * Private constructor to prevent instantiation of the class 168 */ 169 private DigestUtil() {} 170 }