tailly_messages/crypto/server_crypto.go
madipo2611 00b6b32cf3
All checks were successful
continuous-integration/drone/push Build is passing
v.0.0.4 Добавлено шифрование сообщения
2025-08-20 23:29:04 +03:00

102 lines
2.2 KiB
Go

package crypto
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"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
}
// Шифрование сообщения
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(nonce, 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
}