fix: implement proper ALTCHA challenge with HMAC signatures

- Use proper cryptographic challenge generation
- Add HMAC-SHA256 signatures for challenge verification
- Replace test signatures with real cryptographic signatures
- This should fix the verification failures
This commit is contained in:
Patrick Britton 2026-02-16 23:32:02 -06:00
parent 9f33cc1e8a
commit 7944380ada
2 changed files with 38 additions and 12 deletions

View file

@ -3,6 +3,9 @@ package handlers
import ( import (
"bytes" "bytes"
"context" "context"
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io" "io"
@ -4130,12 +4133,23 @@ func (h *AdminHandler) SendTestEmail(c *gin.Context) {
} }
func (h *AdminHandler) GetAltchaChallenge(c *gin.Context) { func (h *AdminHandler) GetAltchaChallenge(c *gin.Context) {
// Simple ALTCHA challenge implementation // Generate a proper ALTCHA challenge
challenge := map[string]interface{}{ salt := fmt.Sprintf("%d", time.Now().UnixNano())
// Create a simple number challenge (find a number that when hashed with salt produces a hash starting with certain digits)
challenge := fmt.Sprintf("%x", sha256.Sum256([]byte(salt)))[:10]
// Create HMAC signature using JWT secret as the key
h := hmac.New(sha256.New, []byte(h.jwtSecret))
h.Write([]byte(challenge + salt))
signature := hex.EncodeToString(h.Sum(nil))
response := map[string]interface{}{
"algorithm": "SHA-256", "algorithm": "SHA-256",
"challenge": fmt.Sprintf("%d", time.Now().UnixNano()), "challenge": challenge,
"salt": fmt.Sprintf("%d", time.Now().Unix()), "salt": salt,
"signature": "test-signature", "signature": signature,
} }
c.JSON(http.StatusOK, challenge)
c.JSON(http.StatusOK, response)
} }

View file

@ -1,6 +1,7 @@
package handlers package handlers
import ( import (
"crypto/hmac"
"crypto/rand" "crypto/rand"
"crypto/sha256" "crypto/sha256"
"encoding/base64" "encoding/base64"
@ -598,12 +599,23 @@ func (h *AuthHandler) ResetPassword(c *gin.Context) {
} }
func (h *AuthHandler) GetAltchaChallenge(c *gin.Context) { func (h *AuthHandler) GetAltchaChallenge(c *gin.Context) {
// Simple ALTCHA challenge implementation // Generate a proper ALTCHA challenge
challenge := map[string]interface{}{ salt := fmt.Sprintf("%d", time.Now().UnixNano())
// Create a simple number challenge (find a number that when hashed with salt produces a hash starting with certain digits)
challenge := fmt.Sprintf("%x", sha256.Sum256([]byte(salt)))[:10]
// Create HMAC signature using JWT secret as the key
h := hmac.New(sha256.New, []byte(h.config.JWTSecret))
h.Write([]byte(challenge + salt))
signature := hex.EncodeToString(h.Sum(nil))
response := map[string]interface{}{
"algorithm": "SHA-256", "algorithm": "SHA-256",
"challenge": fmt.Sprintf("%d", time.Now().UnixNano()), "challenge": challenge,
"salt": fmt.Sprintf("%d", time.Now().Unix()), "salt": salt,
"signature": "test-signature", "signature": signature,
} }
c.JSON(http.StatusOK, challenge)
c.JSON(http.StatusOK, response)
} }