|
RIPEMD160MessageDigestEngine |
|
1 /* $RCSfile: RIPEMD160MessageDigestEngine.java,v $
2 * $Revision: 1.6 $
3 * $Date: 2003/10/04 19:18:38 $
4 * $Author: uwe_guenther $
5 * $State: Exp $
6 *
7 * Created on July 4, 2001, 1:01 PM
8 *
9 * Copyright (C) 2001 Uwe Guenther <uwe@cscc.de>
10 *
11 * This file is part of the jhbci JCE-ServiceProvider. The jhbci JCE-
12 * ServiceProvider is a library, written in JavaTM, that should be
13 * used in HBCI banking applications (clients and may be servers),
14 * to do cryptographic operations.
15 *
16 * The jhbci library is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU Lesser General Public
18 * License as published by the Free Software Foundation; either
19 * version 2.1 of the License, or (at your option) any later version.
20 *
21 * The jhbci library is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 * Lesser General Public License for more details.
25 *
26 * You should have received a copy of the GNU Lesser General Public
27 * License along with this library; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 *
30 */
31
32 package de.cscc.crypto.provider;
33
34 import java.security.DigestException;
35 import java.security.MessageDigestSpi;
36
37 /**
38 * RIPEMD160MessageDigestEngine Class.
39 *
40 * This class does the RIPEMD-160 algorithm via delegation to
41 * RIPEMD160MessageDigestImpl and is implemented as JCA (Java Cryptogrphy Architecture)
42 * Service Provider. You can not instance these class
43 * direct, because it is enabled through the JCA API.
44 *
45 *
46 * <p>The sum of all added bytes from {@link #engineUpdate(byte)
47 * engineUpdate(byte)} and {@link #engineUpdate(byte[], int, int)
48 * engineUpdate(byte[], int, int)} are processed by the RIPEMD-160
49 * message digest algorithm with {@link #engineDigest() engineDigest()} or
50 * {@link #engineDigest(byte[] , int, int) engineDigest(byte[], int, int)}.
51 *
52 * <pre>
53 *
54 * How does it work:
55 * =================
56 *
57 * RIPEMD-160 works only with whole 512 bit blocks.
58 *
59 * 512bits == 64 bytes == 16 words
60 * -------------------------------------------------
61 * |00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|
62 * -------------------------------------------------
63 * / \
64 * / \
65 * / \
66 * / \
67 * / \
68 * -------------
69 * |32 bit word| <-- 32 bit word = 4 byte
70 * -------------
71 * |00|01|02|03| <-- 4 bytes = 4 x 8 bit = 32 bit
72 * -------------
73 *
74 * </pre>
75 *
76 * <p>Here is a simple Code Example:
77 *
78 * <pre>
79 *
80 * import java.security.Security;
81 * import java.security.Provider;
82 * import java.security.MessageDigest;
83 * import java.security.NoSuchAlgorithmException;
84 * import de.cscc.crypto.provider.HBCI;
85 * import java.io.IOException;
86 *
87 * public class MyMessageDigest{
88 * public static void main(String args[]){
89 *
90 * // add Provider
91 * int i = Security.addProvider(new de.cscc.crypto.provider.JHBCI());
92 * System.out.println("Provider inserted at position " + i + ".");
93 *
94 * // get provider
95 * Provider p = Security.getProvider("JHBCI");
96 * System.out.println("My Provider Name is " + p.getName());
97 * System.out.println("My Provider Version is " + p.getVersion());
98 * System.out.println("My Provider Info is " + p.getInfo());
99 *
100 * // get MessageDigest Object through the JCA API
101 * MessageDigest myRIPEMD1 = null;
102 * MessageDigest myRIPEMD2 = null,
103 *
104 * try{
105 * myRIPEMD1 = MessageDigest.getInstance("RIPEMD160");
106 * } catch(NoSuchAlgorithmException e){
107 * e.printStackTrace();
108 * }
109 *
110 * // put the messaeg in the MessageDigest object
111 * byte[] myByte = {'a','b','c'};
112 * myRIPEMD1.update(myByte);
113 *
114 * // clone the object
115 * try {
116 * myRIPEMD2 = myRIPEMD1.clone
117 * } catch (CloneNotSupportedException e) {
118 * e.printStackTrace();
119 * }
120 *
121 * // get the Message Digests
122 * byte[] messageDigest1 = myRIPEMD1.digest();
123 * byte[] messageDigest2 = myRIPEMD2.digest();
124 *
125 * // now the byte arrays messageDigest[12] holds a 20 byte long message
126 * // digest of the message "abc" and should be in binary form:
127 * // 0x8eb208f7e05d987a9b044a8e98c6b087f15a0bfc
128 *
129 * // verify the two digests
130 * boolean verify = MessageDigest.isEqual(messageDigest1, messageDigest2);
131 * System.out.println("The two digests are equal: " + verify);
132 * }
133 * }
134 * </pre>
135 *
136 * @author <a href=mailto:uwe@cscc.de>Uwe Günther</a>
137 * @version $Revision: 1.6 $
138 */
139 public final class RIPEMD160MessageDigestEngine
140 extends MessageDigestSpi implements Cloneable {
141
142 /**
143 * Object to which we delegate all working crypto stuff from these method.
144 */
145 private RIPEMD160MessageDigestImpl md =
146 new RIPEMD160MessageDigestImpl();
147
148 /**
149 * Creates new RIPEMD160MessageDigestEngine. This default constructor is
150 * invoked from <code>java.security.MessageDigest.getInstance()</code>.
151 */
152 public RIPEMD160MessageDigestEngine() {
153 if (JHBCI.selfIntegrityChecking() == false) {
154 throw new SecurityException("JHBCI-Provider is tampered.");
155 }
156 }
157
158 /**
159 * Creates and returns a deep of this object.
160 * @return a clone of this instance.
161 * @see java.lang.Cloneable
162 * @exception CloneNotSupportedException if the object's class does not
163 * support the <code>Cloneable</code> interface. Subclasses
164 * that override the <code>clone</code> method can also
165 * throw this exception to indicate that an instance cannot
166 * be cloned.
167 */
168 public Object clone() throws CloneNotSupportedException {
169 RIPEMD160MessageDigestEngine result =
170 (RIPEMD160MessageDigestEngine) super.clone();
171 result.md = (RIPEMD160MessageDigestImpl) this.md.clone();
172 return result;
173 }
174
175 /**
176 * Compares two RIPEMD160MessageDigestEngine objects. If the private members
177 * of obj are equal wtih the private members of this object the method
178 * will return true, otherwise false.
179 * @param obj RIPEMD160MessageDigestEngine object to compare.
180 * @return true if the objects are deeply equal.
181 */
182 public boolean equals(Object obj) {
183 //Only for performance.
184 if (this == obj) {
185 return true;
186 }
187
188 //If obj == null then instanceof returns false, see JLS 15.20.2
189 if (!(obj instanceof RIPEMD160MessageDigestEngine)) {
190 return false;
191 }
192
193 RIPEMD160MessageDigestEngine other = (RIPEMD160MessageDigestEngine)obj;
194 return this.md.equals(other.md);
195 }
196
197 /**
198 * Returns a hash code value for the object. This method is
199 * supported for the benefit of hashtables such as those provided by
200 * <code>java.util.Hashtable</code>.
201 *
202 * @return a hash code value for this object.
203 * @see #equals(java.lang.Object)
204 * @see java.util.Hashtable
205 */
206 public int hashCode() {
207 int result = 17;
208 result = 37*result + this.md.hashCode();
209 return result;
210 }
211
212 /**
213 * Returns a string representation of the object.
214 * @return a string representation of the object.
215 */
216 public String toString() {
217 return this.md.toString();
218 }
219
220 /**
221 * If the whole message added to the message digest object, you should
222 * invoke the digest method at your API object (MessageDigest). The wraper
223 * invokes these method to return the 160 bit RIPEMD-160 digest at a byte
224 * array (20 byte or 160 bit).
225 * @return the message digest in 20 byte long byte array.
226 * This byte array contains the 160 bit digest in binary form.
227 */
228 protected byte[] engineDigest() {
229 return this.md.digest();
230 }
231
232 /**
233 * If the whole message added to the message digest object, you should
234 * invoke the digest method at your API Object (MessageDigest). The Wraper
235 * invokes these method to return the 160 bit RIPEMD-160 digest at a byte
236 * array (20 byte or 160 bit).
237 * @param buf the message digest in 20 byte long byte array.
238 * This byte array contains the 160 bit digest in binary form.
239 * @param offset begin of buffer.
240 * @param len end of buffer.
241 * @throws DigestException If the difference between len-offset less than
242 * 20 bytes a DigestException will be thrown.
243 * @return the length of the digest stored in the output buffer.
244 */
245 protected int engineDigest(byte[] buf, int offset, int len)
246 throws DigestException {
247 return this.md.digest(buf, offset, len);
248 }
249
250 /**
251 * Returns the length of the message digest in byte. In case of RIPEMD-160
252 * it will be 20.
253 * @return digest length (20) in byte.
254 */
255 protected int engineGetDigestLength() {
256 return this.md.getDigestLength();
257 }
258
259 /** Resets the message digest object, for further use. So if you have
260 * calculated your digest, you should invoke reset() through the JCA API
261 * that invokes this engineReset method to reset the object to calculate an
262 * new digest from a new message.
263 */
264 protected void engineReset() {
265 this.md.reset();
266 }
267
268 /**
269 * Updates the internal message buffer with <CODE>byte value</CODE>.
270 * @param value message byte.
271 */
272 protected void engineUpdate(byte value) {
273 this.md.update(value);
274 }
275
276 /**
277 * Updates the internal message buffer with <CODE>byte[] value</CODE>,
278 * starting at offset, ending at len.
279 * @param values message byte array.
280 * @param offset begin of message byte array.
281 * @param len end of message byte array.
282 */
283 protected void engineUpdate(byte[] values, int offset, int len) {
284 this.md.update(values, offset, len);
285 }
286 }
287
|
RIPEMD160MessageDigestEngine |
|