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