package rsa import ( "crypto/rand" "crypto/rsa" "crypto/sha256" "crypto/x509" "encoding/pem" "fmt" ) // Service provides RSA functionality. type Service struct{} // NewService creates and returns a new Service instance for performing RSA-related operations. func NewService() *Service { return &Service{} } // GenerateKeyPair creates a new RSA key pair. func (s *Service) GenerateKeyPair(bits int) (publicKey, privateKey []byte, err error) { if bits < 2048 { return nil, nil, fmt.Errorf("rsa: key size too small: %d (minimum 2048)", bits) } privKey, err := rsa.GenerateKey(rand.Reader, bits) if err != nil { return nil, nil, fmt.Errorf("failed to generate private key: %w", err) } privKeyBytes := x509.MarshalPKCS1PrivateKey(privKey) privKeyPEM := pem.EncodeToMemory(&pem.Block{ Type: "RSA PRIVATE KEY", Bytes: privKeyBytes, }) pubKeyBytes, err := x509.MarshalPKIXPublicKey(&privKey.PublicKey) if err != nil { return nil, nil, fmt.Errorf("failed to marshal public key: %w", err) } pubKeyPEM := pem.EncodeToMemory(&pem.Block{ Type: "PUBLIC KEY", Bytes: pubKeyBytes, }) return pubKeyPEM, privKeyPEM, nil } // Encrypt encrypts data with a public key. func (s *Service) Encrypt(publicKey, data, label []byte) ([]byte, error) { block, _ := pem.Decode(publicKey) if block == nil { return nil, fmt.Errorf("failed to decode public key") } pub, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { return nil, fmt.Errorf("failed to parse public key: %w", err) } rsaPub, ok := pub.(*rsa.PublicKey) if !ok { return nil, fmt.Errorf("not an RSA public key") } ciphertext, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, rsaPub, data, label) if err != nil { return nil, fmt.Errorf("failed to encrypt data: %w", err) } return ciphertext, nil } // Decrypt decrypts data with a private key. func (s *Service) Decrypt(privateKey, ciphertext, label []byte) ([]byte, error) { block, _ := pem.Decode(privateKey) if block == nil { return nil, fmt.Errorf("failed to decode private key") } priv, err := x509.ParsePKCS1PrivateKey(block.Bytes) if err != nil { return nil, fmt.Errorf("failed to parse private key: %w", err) } plaintext, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, priv, ciphertext, label) if err != nil { return nil, fmt.Errorf("failed to decrypt data: %w", err) } return plaintext, nil }