KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > maverick > crypto > digests > GeneralHMac


1 /*
2  * SSL-Explorer
3  *
4  * Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */

19             
20 package com.maverick.crypto.digests;
21
22
23
24
25 /**
26  * HMAC implementation based on RFC2104
27  *
28  * H(K XOR opad, H(K XOR ipad, text))
29  */

30 public class GeneralHMac
31         implements HMac {
32   private final static int BLOCK_LENGTH = 64;
33
34   private final static byte IPAD = (byte) 0x36;
35   private final static byte OPAD = (byte) 0x5C;
36
37   private Digest digest;
38   private int digestSize;
39   private int outputSize;
40   private byte[] inputPad = new byte[BLOCK_LENGTH];
41   private byte[] outputPad = new byte[BLOCK_LENGTH];
42
43   public GeneralHMac(
44       Digest digest) {
45     this.digest = digest;
46     digestSize = digest.getDigestSize();
47     outputSize = digestSize;
48   }
49
50   public GeneralHMac(
51       Digest digest, int outputSize) {
52     this.digest = digest;
53     this.digestSize = digest.getDigestSize();
54     this.outputSize = outputSize;
55   }
56   
57   public String JavaDoc getAlgorithmName() {
58     return digest.getAlgorithmName() + "/HMAC";
59   }
60
61   public int getOutputSize() {
62       return outputSize;
63   }
64
65   public Digest getUnderlyingDigest() {
66     return digest;
67   }
68
69   public void init(
70       byte[] key) {
71     digest.reset();
72
73     if (key.length > BLOCK_LENGTH) {
74       digest.update(key, 0, key.length);
75       digest.doFinal(inputPad, 0);
76       for (int i = digestSize; i < inputPad.length; i++) {
77         inputPad[i] = 0;
78       }
79     }
80     else {
81       System.arraycopy(key, 0, inputPad, 0, key.length);
82       for (int i = key.length; i < inputPad.length; i++) {
83         inputPad[i] = 0;
84       }
85     }
86
87     outputPad = new byte[inputPad.length];
88     System.arraycopy(inputPad, 0, outputPad, 0, inputPad.length);
89
90     for (int i = 0; i < inputPad.length; i++) {
91       inputPad[i] ^= IPAD;
92     }
93
94     for (int i = 0; i < outputPad.length; i++) {
95       outputPad[i] ^= OPAD;
96     }
97
98     digest.update(inputPad, 0, inputPad.length);
99   }
100
101   public int getMacSize() {
102     return digestSize;
103   }
104
105   public void update(
106       byte in) {
107     digest.update(in);
108   }
109
110   public void update(
111       byte[] in,
112       int inOff,
113       int len) {
114     digest.update(in, inOff, len);
115   }
116
117   public int doFinal(
118       byte[] out,
119       int outOff) {
120     byte[] tmp = new byte[digestSize];
121     digest.doFinal(tmp, 0);
122
123     digest.update(outputPad, 0, outputPad.length);
124     digest.update(tmp, 0, tmp.length);
125
126     int len = digest.doFinal(out, outOff);
127
128     reset();
129
130     return len;
131   }
132
133   /**
134    * Reset the mac generator.
135    */

136   public void reset() {
137     /*
138      * reset the underlying digest.
139      */

140     digest.reset();
141
142     /*
143      * reinitialize the digest.
144      */

145     digest.update(inputPad, 0, inputPad.length);
146   }
147 }
148
Popular Tags