HMAC与时间窗口

huangapple go评论91阅读模式
英文:

HMAC with a time-window

问题

我正在使用基于UTC+0同步时间的时间窗口机制对HMAC进行一些测试。服务器有一个特殊的公共API调用http://myserver.com/api/servertime/,它将返回服务器的准确的UTC+0时间。这样,API用户可以同步他们的请求客户端,以便能够匹配我的API允许的安全调用的时间窗口。我设置了一个30分钟的时间段(-15min - +15min)。

我的代码如下:

func GenerateHmac512(message []byte, key []byte) []byte {
    h := hmac.New(sha512.New, key)
    h.Write(message)
    return []byte(base64.StdEncoding.EncodeToString(h.Sum(nil)))
}

func ValidateHmac512(message, messageMAC, key []byte) bool {
    var err error
    decryptedMessageMAC, err := base64.StdEncoding.DecodeString(string(messageMAC))

    if err != nil {
        log.Fatalln(err.Error())
        return false
    }

    mac := hmac.New(sha512.New, key)
    mac.Write(message)
    expectedMAC := mac.Sum(nil)
    return hmac.Equal(decryptedMessageMAC, expectedMAC)
}

func main() {
    timestamp := time.Now().Unix()
    key := []byte("afad9411468602782fb62d904f623d87")
    message := []byte(fmt.Sprintf("SecretHash,Value1,Value2,Value3,TimeStamp:%d", time.Now().Unix()))
    hmacHash := GenerateHmac512(message, key)
    hmacValid := ValidateHmac512(message, hmacHash, key)
    log.Println(timestamp)
    log.Println(string(hmacHash))
    log.Println(hmacValid)

    requestValid := false

    if timestamp > time.Now().Unix()-(60*15) && timestamp < time.Now().Unix()+(60+15) {
        requestValid = true
    }

    log.Println(requestValid)
}

我在HMAC哈希中散列了将在调用中公开提供的时间戳,与密钥哈希组合在一起。我想知道这是否足够可靠,或者是否需要更多工作来使其完全可靠?调用将类似于:

POST http://myserver.com/api/users/
Value1 : Data1
Value2 : Data2
Value3 : Data3
Timestamp : 1420497639

最终,当一切都正常时,我将通过SSL/TLS发送这些数据。我知道SSL已经足够了,不需要HMAC,但我喜欢有这3层安全性。我想对这些安全层的变化进行基准测试,以了解性能影响以及如何调整以在性能和安全性之间取得良好的平衡。

英文:

I'm doing some tests with HMAC by using a time-window mechanism based on UTC+0 synced time. The server has a special public API call http://myserver.com/api/servertime/ that will return the server's exact UTC+0 time. This way the API users can sync their requesting client so it will be able to match the time window my API allows for secure calls. I built in a 30 minute timeslot (-15min - +15min).

My code looks like this:

func GenerateHmac512(message []byte, key []byte) []byte {
	h := hmac.New(sha512.New, key)
	h.Write(message)
	return []byte(base64.StdEncoding.EncodeToString(h.Sum(nil)))
}

func ValidateHmac512(message, messageMAC, key []byte) bool {
	var err error
	decryptedMessageMAC, err := base64.StdEncoding.DecodeString(string(messageMAC))

	if err != nil {
		log.Fatalln(err.Error())
		return false
	}

	mac := hmac.New(sha512.New, key)
	mac.Write(message)
	expectedMAC := mac.Sum(nil)
	return hmac.Equal(decryptedMessageMAC, expectedMAC)
}

func main() {
	timestamp := time.Now().Unix()
	key := []byte(&quot;afad9411468602782fb62d904f623d87&quot;)
	message := []byte(fmt.Sprintf(&quot;SecretHash,Value1,Value2,Value3,TimeStamp:%d&quot;, time.Now().Unix()))
	hmacHash := GenerateHmac512(message, key)
	hmacValid := ValidateHmac512(message, hmacHash, key)
	log.Println(timestamp)
	log.Println(string(hmacHash))
	log.Println(hmacValid)

	requestValid := false

	if timestamp &gt; time.Now().Unix()-(60*15) &amp;&amp; timestamp &lt; time.Now().Unix()+(60+15) {
		requestValid = true
	}

	log.Println(requestValid)
}

I'm hashing the timestamp that will be publicly provided in the call in my HMAC hash, combined with the secret hash. I'm wondering if this is fool-proof enough, or it would need more work to make it totally solid? The call would be something like this:

POST http://myserver.com/api/users/
Value1 : Data1
Value2 : Data2
Value3 : Data3
Timestamp : 1420497639

Eventually when this is all OK I'm gonna send this data over SSL/TLS. I know SSL is more than enough and HMAC wouldn't be needed, but I like to have these 3 layers of security. And I want to benchmark variations of these layers to see what the performance impact is and how I can tweak it to have a good balance between performance and security.

答案1

得分: 1

这里没有太多需要回答的内容,HMAC用于验证消息的真实性和完整性,这似乎是你想要的。此外,如果你要对客户端进行身份验证,TLS只是“足够多”。如果这是一个未经身份验证的调用,那么使用HMAC仍然是合理的,以证明共享密钥的知识。

请注意,SecretHash是多余的。你已经有一个共享密钥。

英文:

There's not much to answer here, an HMAC authenticates a message and verifies integrity, and that seems to be what you want. Also, TLS is only "more than enough" if you're authenticating the client. If this is an unauthenticated call, then HMAC is still reasonable to prove the knowledge of a shared secret.

Note that SecretHash is superfluous. You already have a secret shared key.

huangapple
  • 本文由 发表于 2015年1月6日 06:53:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/27789310.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定