2222
2323import javax .crypto .Mac ;
2424import javax .crypto .ShortBufferException ;
25+ import java .nio .ByteBuffer ;
2526import java .security .InvalidKeyException ;
2627import java .security .Key ;
2728import java .security .NoSuchAlgorithmException ;
@@ -39,7 +40,7 @@ public class HmacOneTimePasswordGenerator {
3940 private final Mac mac ;
4041 private final int passwordLength ;
4142
42- private final byte [] buffer ;
43+ private final ByteBuffer buffer ;
4344 private final int modDivisor ;
4445
4546 private final String formatString ;
@@ -121,7 +122,7 @@ protected HmacOneTimePasswordGenerator(final int passwordLength, final String al
121122 }
122123
123124 this .passwordLength = passwordLength ;
124- this .buffer = new byte [ this .mac .getMacLength ()] ;
125+ this .buffer = ByteBuffer . allocate ( this .mac .getMacLength ()) ;
125126 }
126127
127128 /**
@@ -136,34 +137,23 @@ protected HmacOneTimePasswordGenerator(final int passwordLength, final String al
136137 * @throws InvalidKeyException if the given key is inappropriate for initializing the {@link Mac} for this generator
137138 */
138139 public synchronized int generateOneTimePassword (final Key key , final long counter ) throws InvalidKeyException {
139- this .mac .init (key );
140-
141- this .buffer [0 ] = (byte ) ((counter & 0xff00000000000000L ) >>> 56 );
142- this .buffer [1 ] = (byte ) ((counter & 0x00ff000000000000L ) >>> 48 );
143- this .buffer [2 ] = (byte ) ((counter & 0x0000ff0000000000L ) >>> 40 );
144- this .buffer [3 ] = (byte ) ((counter & 0x000000ff00000000L ) >>> 32 );
145- this .buffer [4 ] = (byte ) ((counter & 0x00000000ff000000L ) >>> 24 );
146- this .buffer [5 ] = (byte ) ((counter & 0x0000000000ff0000L ) >>> 16 );
147- this .buffer [6 ] = (byte ) ((counter & 0x000000000000ff00L ) >>> 8 );
148- this .buffer [7 ] = (byte ) (counter & 0x00000000000000ffL );
149-
150- this .mac .update (this .buffer , 0 , 8 );
140+ this .buffer .clear ();
141+ this .buffer .putLong (0 , counter );
151142
152143 try {
153- this .mac .doFinal (this .buffer , 0 );
144+ final byte [] array = this .buffer .array ();
145+
146+ this .mac .init (key );
147+ this .mac .update (array , 0 , 8 );
148+ this .mac .doFinal (array , 0 );
154149 } catch (final ShortBufferException e ) {
155150 // We allocated the buffer to (at least) match the size of the MAC length at construction time, so this
156151 // should never happen.
157152 throw new RuntimeException (e );
158153 }
159154
160- final int offset = this .buffer [this .buffer .length - 1 ] & 0x0f ;
161-
162- return ((this .buffer [offset ] & 0x7f ) << 24 |
163- (this .buffer [offset + 1 ] & 0xff ) << 16 |
164- (this .buffer [offset + 2 ] & 0xff ) << 8 |
165- (this .buffer [offset + 3 ] & 0xff )) %
166- this .modDivisor ;
155+ final int offset = this .buffer .get (this .buffer .capacity () - 1 ) & 0x0f ;
156+ return (this .buffer .getInt (offset ) & 0x7fffffff ) % this .modDivisor ;
167157 }
168158
169159 /**
0 commit comments