tailly_messages/crypto/server_crypto.go
madipo2611 f983a2f9d9
All checks were successful
continuous-integration/drone/push Build is passing
v.0.0.4.6 Добавлено шифрование сообщения
2025-08-21 00:50:27 +03:00

113 lines
2.7 KiB
Go

package crypto
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/base64"
"io"
)
type CryptoService struct {
privateKey *rsa.PrivateKey
Vault *VaultManager
}
func NewCryptoService() (*CryptoService, error) {
vault, err := NewVaultManager()
if err != nil {
return nil, err
}
// Загрузка приватного ключа из Vault
keyBytes, err := vault.GetMasterPrivateKey()
if err != nil {
return nil, err
}
privateKey, err := x509.ParsePKCS1PrivateKey(keyBytes)
if err != nil {
return nil, err
}
return &CryptoService{
privateKey: privateKey,
Vault: vault,
}, nil
}
// Шифрование сообщения - возвращает зашифрованный контент, ключ и nonce
func (cs *CryptoService) EncryptMessage(content string) ([]byte, []byte, []byte, error) {
// Генерация сессионного AES ключа
aesKey := make([]byte, 32)
if _, err := rand.Read(aesKey); err != nil {
return nil, nil, nil, err
}
// Шифрование сообщения AES-GCM
block, err := aes.NewCipher(aesKey)
if err != nil {
return nil, nil, nil, err
}
gcm, err := cipher.NewGCM(block)
if err != nil {
return nil, nil, nil, err
}
nonce := make([]byte, gcm.NonceSize())
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
return nil, nil, nil, err
}
encryptedContent := gcm.Seal(nil, nonce, []byte(content), nil)
// Шифрование AES ключа RSA-OAEP
encryptedKey, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, &cs.privateKey.PublicKey, aesKey, nil)
if err != nil {
return nil, nil, nil, err
}
return encryptedContent, encryptedKey, nonce, nil
}
// Расшифровка сообщения
func (cs *CryptoService) DecryptMessage(encryptedContent, encryptedKey, nonce []byte) (string, error) {
// Расшифровка AES ключа
aesKey, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, cs.privateKey, encryptedKey, nil)
if err != nil {
return "", err
}
// Расшифровка сообщения
block, err := aes.NewCipher(aesKey)
if err != nil {
return "", err
}
gcm, err := cipher.NewGCM(block)
if err != nil {
return "", err
}
plaintext, err := gcm.Open(nil, nonce, encryptedContent, nil)
if err != nil {
return "", err
}
return string(plaintext), nil
}
// Утилитарная функция для base64 кодирования (для хранения в Vault)
func (cs *CryptoService) EncodeBase64(data []byte) string {
return base64.StdEncoding.EncodeToString(data)
}
// Утилитарная функция для base64 декодирования
func (cs *CryptoService) DecodeBase64(data string) ([]byte, error) {
return base64.StdEncoding.DecodeString(data)
}