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
21
22 package org.apache.james.impl.user;
23
24 import javax.mail.MessagingException;
25 import javax.mail.internet.MimeUtility;
26
27 import java.io.ByteArrayOutputStream;
28 import java.io.FileInputStream;
29 import java.io.FileOutputStream;
30 import java.io.IOException;
31 import java.io.OutputStream;
32 import java.security.MessageDigest;
33 import java.security.NoSuchAlgorithmException;
34 import java.util.Locale;
35
36
37 /**
38 * Computes and verifies digests of files and strings
39 *
40 *
41 * @version $Revision: 684502 $
42 */
43 public class DigestUtil {
44
45 /**
46 * Command line interface. Use -help for arguments.
47 *
48 * @param args the arguments passed in on the command line
49 */
50 public static void main(String[] args) {
51
52 String alg = "SHA";
53 boolean file = false;
54
55 if (args.length == 0 || args.length > 4) {
56 printUsage();
57 return;
58 }
59
60 for (int i = 0; i < args.length; i++) {
61 String currArg = args[i].toLowerCase(Locale.US);
62 if (currArg.equals("-help")
63 || currArg.equals("-usage")) {
64 printUsage();
65 return;
66 }
67 if (currArg.equals("-alg")) {
68 alg = args[i+1];
69 }
70 if (currArg.equals("-file")) {
71 file = true;
72 }
73 }
74
75 if (file) {
76 digestFile(args[args.length - 1], alg);
77 return ;
78 } else {
79 try {
80 String hash = digestString(args[args.length - 1], alg);
81 System.out.println("Hash is: " + hash);
82 return;
83 } catch (NoSuchAlgorithmException nsae) {
84 System.out.println("No such algorithm available");
85 }
86 }
87 }
88
89 /**
90 * Print the command line usage string.
91 */
92 public static void printUsage() {
93 System.out.println("Usage: "
94 + "java org.apache.james.security.DigestUtil"
95 + " [-alg algorithm]"
96 + " [-file] filename|string");
97 }
98
99 /**
100 * Calculate digest of given file with given algorithm.
101 * Writes digest to file named filename.algorithm .
102 *
103 * @param filename the String name of the file to be hashed
104 * @param algorithm the algorithm to be used to compute the digest
105 */
106 public static void digestFile(String filename, String algorithm) {
107 byte[] b = new byte[65536];
108 int count = 0;
109 int read = 0;
110 FileInputStream fis = null;
111 FileOutputStream fos = null;
112 try {
113 MessageDigest md = MessageDigest.getInstance(algorithm);
114 fis = new FileInputStream(filename);
115 while (fis.available() > 0) {
116 read = fis.read(b);
117 md.update(b, 0, read);
118 count += read;
119 }
120 byte[] digest = md.digest();
121 StringBuffer fileNameBuffer =
122 new StringBuffer(128)
123 .append(filename)
124 .append(".")
125 .append(algorithm);
126 fos = new FileOutputStream(fileNameBuffer.toString());
127 OutputStream encodedStream = MimeUtility.encode(fos, "base64");
128 encodedStream.write(digest);
129 fos.flush();
130 } catch (Exception e) {
131 System.out.println("Error computing Digest: " + e);
132 } finally {
133 try {
134 fis.close();
135 fos.close();
136 } catch (Exception ignored) {}
137 }
138 }
139
140 /**
141 * Calculate digest of given String using given algorithm.
142 * Encode digest in MIME-like base64.
143 *
144 * @param pass the String to be hashed
145 * @param algorithm the algorithm to be used
146 * @return String Base-64 encoding of digest
147 *
148 * @throws NoSuchAlgorithmException if the algorithm passed in cannot be found
149 */
150 public static String digestString(String pass, String algorithm )
151 throws NoSuchAlgorithmException {
152
153 MessageDigest md;
154 ByteArrayOutputStream bos;
155
156 try {
157 md = MessageDigest.getInstance(algorithm);
158 byte[] digest = md.digest(pass.getBytes("iso-8859-1"));
159 bos = new ByteArrayOutputStream();
160 OutputStream encodedStream = MimeUtility.encode(bos, "base64");
161 encodedStream.write(digest);
162 return bos.toString("iso-8859-1");
163 } catch (IOException ioe) {
164 throw new RuntimeException("Fatal error: " + ioe);
165 } catch (MessagingException me) {
166 throw new RuntimeException("Fatal error: " + me);
167 }
168 }
169
170 /**
171 * Private constructor to prevent instantiation of the class
172 */
173 private DigestUtil() {}
174 }