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: ****************************************************************/package org.apache.james.security;
019:
020: import javax.mail.MessagingException;
021: import javax.mail.internet.MimeUtility;
022:
023: import java.io.ByteArrayOutputStream;
024: import java.io.FileInputStream;
025: import java.io.FileOutputStream;
026: import java.io.IOException;
027: import java.io.OutputStream;
028: import java.security.MessageDigest;
029: import java.security.NoSuchAlgorithmException;
030: import java.util.Locale;
031:
032: /**
033: * Computes and verifies digests of files and strings
034: *
035: *
036: * @version $Revision: 494012 $
037: */
038: public class DigestUtil {
039:
040: /**
041: * Command line interface. Use -help for arguments.
042: *
043: * @param args 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: return;
072: } else {
073: try {
074: String hash = digestString(args[args.length - 1], alg);
075: System.out.println("Hash is: " + hash);
076: return;
077: } catch (NoSuchAlgorithmException nsae) {
078: System.out.println("No such algorithm available");
079: }
080: }
081: }
082:
083: /**
084: * Print the command line usage string.
085: */
086: public static void printUsage() {
087: System.out.println("Usage: "
088: + "java org.apache.james.security.DigestUtil"
089: + " [-alg algorithm]" + " [-file] filename|string");
090: }
091:
092: /**
093: * Calculate digest of given file with given algorithm.
094: * Writes digest to file named filename.algorithm .
095: *
096: * @param filename the String name of the file to be hashed
097: * @param algorithm the algorithm to be used to compute the digest
098: */
099: public static void digestFile(String filename, String algorithm) {
100: byte[] b = new byte[65536];
101: int count = 0;
102: int read = 0;
103: FileInputStream fis = null;
104: FileOutputStream fos = null;
105: try {
106: MessageDigest md = MessageDigest.getInstance(algorithm);
107: fis = new FileInputStream(filename);
108: while (fis.available() > 0) {
109: read = fis.read(b);
110: md.update(b, 0, read);
111: count += read;
112: }
113: byte[] digest = md.digest();
114: StringBuffer fileNameBuffer = new StringBuffer(128).append(
115: filename).append(".").append(algorithm);
116: fos = new FileOutputStream(fileNameBuffer.toString());
117: OutputStream encodedStream = MimeUtility.encode(fos,
118: "base64");
119: encodedStream.write(digest);
120: fos.flush();
121: } catch (Exception e) {
122: System.out.println("Error computing Digest: " + e);
123: } finally {
124: try {
125: fis.close();
126: fos.close();
127: } catch (Exception ignored) {
128: }
129: }
130: }
131:
132: /**
133: * Calculate digest of given String using given algorithm.
134: * Encode digest in MIME-like base64.
135: *
136: * @param pass the String to be hashed
137: * @param algorithm the algorithm to be used
138: * @return String Base-64 encoding of digest
139: *
140: * @throws NoSuchAlgorithmException if the algorithm passed in cannot be found
141: */
142: public static String digestString(String pass, String algorithm)
143: throws NoSuchAlgorithmException {
144:
145: MessageDigest md;
146: ByteArrayOutputStream bos;
147:
148: try {
149: md = MessageDigest.getInstance(algorithm);
150: byte[] digest = md.digest(pass.getBytes("iso-8859-1"));
151: bos = new ByteArrayOutputStream();
152: OutputStream encodedStream = MimeUtility.encode(bos,
153: "base64");
154: encodedStream.write(digest);
155: return bos.toString("iso-8859-1");
156: } catch (IOException ioe) {
157: throw new RuntimeException("Fatal error: " + ioe);
158: } catch (MessagingException me) {
159: throw new RuntimeException("Fatal error: " + me);
160: }
161: }
162:
163: /**
164: * Private constructor to prevent instantiation of the class
165: */
166: private DigestUtil() {
167: }
168: }
|