generated from PenaSide/GolangTemplate
104 lines
3.0 KiB
Go
104 lines
3.0 KiB
Go
package encrypt
|
|
|
|
import (
|
|
"crypto/ed25519"
|
|
"crypto/x509"
|
|
"encoding/pem"
|
|
"fmt"
|
|
|
|
"penahub.gitlab.yandexcloud.net/pena-services/pena-social-auth/internal/models"
|
|
)
|
|
|
|
//go:generate mockery --name jwtUtil
|
|
type jwtUtil interface {
|
|
Validate(string) (*models.JWTAuthUser, error)
|
|
}
|
|
|
|
type ServiceDeps struct {
|
|
JWT jwtUtil
|
|
|
|
/* Публичный ключ для верификации подписи кривой Эдвардса (Edwards curve) */
|
|
PublicCurveKey string
|
|
|
|
/* Приватный ключ для верификации подписи кривой Эдвардса (Edwards curve) */
|
|
PrivateCurveKey string
|
|
|
|
/*
|
|
Обший секретный знаменатель для шифрования и верификации подписи
|
|
(должен быть одинаковым для всех микросервисов)
|
|
*/
|
|
SignSecret string
|
|
}
|
|
|
|
type Service struct {
|
|
jwt jwtUtil
|
|
publicCurveKey string
|
|
privateCurveKey string
|
|
signSecret string
|
|
}
|
|
|
|
func New(deps *ServiceDeps) *Service {
|
|
return &Service{
|
|
jwt: deps.JWT,
|
|
publicCurveKey: deps.PublicCurveKey,
|
|
privateCurveKey: deps.PrivateCurveKey,
|
|
signSecret: deps.SignSecret,
|
|
}
|
|
}
|
|
|
|
func (receiver *Service) VerifySignature(signature []byte) (isValid bool, err error) {
|
|
defer func() {
|
|
if recovered := recover(); recovered != nil {
|
|
err = fmt.Errorf("recovered sign error on <VerifySignature> of <EncryptService>: %v", recovered)
|
|
}
|
|
}()
|
|
|
|
block, _ := pem.Decode([]byte(receiver.publicCurveKey))
|
|
if block == nil {
|
|
return false, fmt.Errorf("public key block is nil")
|
|
}
|
|
|
|
rawPublicKey, err := x509.ParsePKIXPublicKey(block.Bytes)
|
|
if err != nil {
|
|
return false, fmt.Errorf("failed parse public key on <VerifySignature> of <EncryptService>: %w", err)
|
|
}
|
|
|
|
publicKey, ok := rawPublicKey.(ed25519.PublicKey)
|
|
if !ok {
|
|
return false, fmt.Errorf("failed convert to ed25519.PrivateKey on <VerifySignature> of <EncryptService>: %w", err)
|
|
}
|
|
|
|
return ed25519.Verify(publicKey, []byte(receiver.signSecret), signature), nil
|
|
}
|
|
|
|
func (receiver *Service) SignCommonSecret() (signature []byte, err error) {
|
|
defer func() {
|
|
if recovered := recover(); recovered != nil {
|
|
err = fmt.Errorf("recovered sign error on <SignCommonSecret> of <EncryptService>: %v", recovered)
|
|
}
|
|
}()
|
|
|
|
block, _ := pem.Decode([]byte(receiver.privateCurveKey))
|
|
|
|
rawPrivateKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
|
|
if err != nil {
|
|
return []byte{}, fmt.Errorf("failed parse private key on <SignCommonSecret> of <EncryptService>: %w", err)
|
|
}
|
|
|
|
privateKey, ok := rawPrivateKey.(ed25519.PrivateKey)
|
|
if !ok {
|
|
return []byte{}, fmt.Errorf("failed convert to ed25519.PrivateKey on <SignCommonSecret> of <EncryptService>: %w", err)
|
|
}
|
|
|
|
return ed25519.Sign(privateKey, []byte(receiver.signSecret)), nil
|
|
}
|
|
|
|
func (receiver *Service) VerifyJWT(token string) (string, error) {
|
|
validatedJwtPayload, err := receiver.jwt.Validate(token)
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to verify jwt on <VerifyJWT> of <EncryptService>: %w", err)
|
|
}
|
|
|
|
return validatedJwtPayload.ID, nil
|
|
}
|