|
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 |
|