fix: 初验针对修改
This commit is contained in:
64
internal/signing/signature.go
Normal file
64
internal/signing/signature.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package signing
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"crypto/subtle"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.apinb.com/ops/files/internal/storage"
|
||||
)
|
||||
|
||||
func SignUpload(secret string, request storage.UploadRequest) string {
|
||||
canonical := strings.Join([]string{
|
||||
"PUT",
|
||||
request.FileID,
|
||||
strconv.FormatInt(request.ExpiresAt.Unix(), 10),
|
||||
strconv.FormatInt(request.ExpectedSize, 10),
|
||||
request.ContentType,
|
||||
}, "\n")
|
||||
return sign(secret, canonical)
|
||||
}
|
||||
|
||||
func VerifyUpload(secret, signature string, request storage.UploadRequest, now time.Time) bool {
|
||||
return request.ExpiresAt.After(now) && verify(secret, SignUpload(secret, request), signature)
|
||||
}
|
||||
|
||||
func SignAccess(secret, fileID string, expiresAt time.Time, disposition string) string {
|
||||
canonical := strings.Join([]string{"GET", fileID, strconv.FormatInt(expiresAt.Unix(), 10), disposition}, "\n")
|
||||
return sign(secret, canonical)
|
||||
}
|
||||
|
||||
func VerifyAccess(secret, fileID string, expiresAt time.Time, disposition, signature string, now time.Time) bool {
|
||||
return expiresAt.After(now) && verify(secret, SignAccess(secret, fileID, expiresAt, disposition), signature)
|
||||
}
|
||||
|
||||
func sign(secret, canonical string) string {
|
||||
mac := hmac.New(sha256.New, []byte(secret))
|
||||
_, _ = mac.Write([]byte(canonical))
|
||||
return hex.EncodeToString(mac.Sum(nil))
|
||||
}
|
||||
|
||||
func verify(secret, expected, actual string) bool {
|
||||
if strings.TrimSpace(secret) == "" || len(actual) != sha256.Size*2 {
|
||||
return false
|
||||
}
|
||||
expectedBytes, expectedErr := hex.DecodeString(expected)
|
||||
actualBytes, actualErr := hex.DecodeString(actual)
|
||||
if expectedErr != nil || actualErr != nil {
|
||||
return false
|
||||
}
|
||||
return subtle.ConstantTimeCompare(expectedBytes, actualBytes) == 1
|
||||
}
|
||||
|
||||
func UploadNonce(secret string, request storage.UploadRequest) (string, error) {
|
||||
signature := SignUpload(secret, request)
|
||||
if len(signature) < 16 {
|
||||
return "", fmt.Errorf("上传签名长度无效")
|
||||
}
|
||||
return signature[:16], nil
|
||||
}
|
||||
Reference in New Issue
Block a user