Index: lib/src/hmac.dart |
diff --git a/lib/src/hmac.dart b/lib/src/hmac.dart |
index 668f40f0669dcd479b60e79418b50a586f00185a..169e1fedfc69234357e6890c78e50fd80dc19b27 100644 |
--- a/lib/src/hmac.dart |
+++ b/lib/src/hmac.dart |
@@ -4,6 +4,10 @@ |
library crypto.hmac; |
+import 'dart:typed_data'; |
+ |
+import 'package:typed_data/typed_data.dart'; |
+ |
import 'hash.dart'; |
/// An implementation of [keyed-hash method authentication codes][rfc]. |
@@ -22,22 +26,35 @@ import 'hash.dart'; |
// TODO(floitsch): make HMAC implement Sink, EventSink or similar. |
class HMAC { |
/// The bytes from the message so far. |
- final List<int> _message; |
+ final _message = new Uint8Buffer(); |
/// The hash function used to compute the authentication digest. |
Hash _hash; |
/// The secret key shared by the sender and the receiver. |
- List<int> _key; |
+ final Uint8List _key; |
- /// Whether this is closed. |
+ /// Whether [close] has been called. |
bool _isClosed = false; |
/// Create an [HMAC] object from a [Hash] and a binary key. |
/// |
/// The key should be a secret shared between the sender and receiver of the |
/// message. |
- HMAC(Hash this._hash, List<int> this._key) : _message = []; |
+ HMAC(Hash hash, List<int> key) |
+ : _hash = hash, |
+ _key = new Uint8List(hash.blockSize) { |
+ // Hash the key if it's longer than the block size of the hash. |
+ if (key.length > _hash.blockSize) { |
+ _hash = _hash.newInstance(); |
+ _hash.add(key); |
+ key = _hash.close(); |
+ } |
+ |
+ // If [key] is shorter than the block size, the rest of [_key] will be |
+ // 0-padded. |
+ _key.setRange(0, key.length, key); |
+ } |
/// Adds a list of bytes to the message. |
/// |
@@ -49,28 +66,9 @@ class HMAC { |
/// Returns the digest of the message so far, as a list of bytes. |
List<int> get digest { |
- var blockSize = _hash.blockSize; |
- |
- // Hash the key if it is longer than the block size of the hash. |
- if (_key.length > blockSize) { |
- _hash = _hash.newInstance(); |
- _hash.add(_key); |
- _key = _hash.close(); |
- } |
- |
- // Zero-pad the key until its size is equal to the block size of the hash. |
- if (_key.length < blockSize) { |
- var newKey = new List(blockSize); |
- newKey.setRange(0, _key.length, _key); |
- for (var i = _key.length; i < blockSize; i++) { |
- newKey[i] = 0; |
- } |
- _key = newKey; |
- } |
- |
// Compute inner padding. |
- var padding = new List(blockSize); |
- for (var i = 0; i < blockSize; i++) { |
+ var padding = new Uint8List(_key.length); |
+ for (var i = 0; i < padding.length; i++) { |
padding[i] = 0x36 ^ _key[i]; |
} |
@@ -78,17 +76,17 @@ class HMAC { |
_hash = _hash.newInstance(); |
_hash.add(padding); |
_hash.add(_message); |
- var innerHash = _hash.close(); |
+ var innerDigest = _hash.close(); |
// Compute outer padding. |
- for (var i = 0; i < blockSize; i++) { |
+ for (var i = 0; i < padding.length; i++) { |
padding[i] = 0x5c ^ _key[i]; |
} |
// Outer hash computation which is the result. |
_hash = _hash.newInstance(); |
_hash.add(padding); |
- _hash.add(innerHash); |
+ _hash.add(innerDigest); |
return _hash.close(); |
} |
@@ -115,7 +113,8 @@ class HMAC { |
'Invalid digest size: ${digest.length} in HMAC.verify. ' |
'Expected: ${_hash.blockSize}.'); |
} |
- int result = 0; |
+ |
+ var result = 0; |
for (var i = 0; i < digest.length; i++) { |
result |= digest[i] ^ computedDigest[i]; |
} |