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 }