44 lines
1.2 KiB
Plaintext
44 lines
1.2 KiB
Plaintext
package simcu::otp
|
||
|
||
import stdx.crypto.digest.SHA1
|
||
|
||
/**
|
||
* HMAC-SHA1 实现(RFC 2104 / RFC 4226 第 5 节)。
|
||
* 仓颉标准库 std.crypto.digest 的 HMAC 目前仅支持 SHA512(HashType.SHA512),
|
||
* 而 HOTP/TOTP 标准基于 HMAC-SHA1,故在此基于 stdx 的 SHA1 自实现(blockSize=64)。
|
||
*/
|
||
public class HmacSha1 {
|
||
private let ipad: Array<Byte>
|
||
private let opad: Array<Byte>
|
||
|
||
public init(key: Array<Byte>) {
|
||
let blockSize: Int64 = 64
|
||
var tempKey = key
|
||
if (key.size > blockSize) {
|
||
let sha = SHA1()
|
||
sha.write(key)
|
||
tempKey = sha.finish()
|
||
}
|
||
ipad = Array<Byte>(blockSize, repeat: 0)
|
||
opad = Array<Byte>(blockSize, repeat: 0)
|
||
tempKey.copyTo(ipad, 0, 0, tempKey.size)
|
||
tempKey.copyTo(opad, 0, 0, tempKey.size)
|
||
for (i in 0..blockSize) {
|
||
ipad[i] ^= 0x36
|
||
opad[i] ^= 0x5c
|
||
}
|
||
}
|
||
|
||
/// 计算 HMAC-SHA1(key, data)
|
||
public func compute(data: Array<Byte>): Array<Byte> {
|
||
let inner = SHA1()
|
||
inner.write(ipad)
|
||
inner.write(data)
|
||
let innerHash = inner.finish()
|
||
let outer = SHA1()
|
||
outer.write(opad)
|
||
outer.write(innerHash)
|
||
outer.finish()
|
||
}
|
||
}
|