SQL Server  

Encrypting Sensitive Data in Angular and SQL Server

Secure Your Full-Stack Applications with Encryption Best Practices

Handling sensitive data is a critical requirement in modern applications. Whether it is user passwords, payment information, personal identification data, or health records, proper encryption ensures data confidentiality and integrity. Combining Angular frontend with ASP.NET Core backend and SQL Server requires careful handling of data both in transit and at rest.

1. Understanding Data Security Layers

Encryption can be implemented at multiple layers:

LayerPurposeExample Techniques
In TransitProtect data while moving between frontend/backendHTTPS (TLS), Secure WebSocket (WSS)
At RestProtect stored data in a database or storageTDE, Column-level encryption, AES encryption
Application LayerProtect sensitive fields before database insertionAES, RSA encryption in .NET

Best practice: Combine in-transit encryption (HTTPS) with application-layer encryption for highly sensitive fields.

2. Encrypting Data in Angular (Frontend)

Angular typically handles data before sending it to the backend. While HTTPS encrypts data in transit, some regulations require end-to-end encryption, where sensitive fields are encrypted in the browser.

Using AES Encryption in Angular

We can use the CryptoJS library for AES encryption.

npm install crypto-js
// encryption.service.tsimport { Injectable } from '@angular/core';
import * as CryptoJS from 'crypto-js';

@Injectable({ providedIn: 'root' })
export class EncryptionService {
  private key = 'YOUR_SECURE_KEY'; // Use environment variable in production

  encrypt(text: string): string {
    return CryptoJS.AES.encrypt(text, this.key).toString();
  }

  decrypt(cipherText: string): string {
    const bytes = CryptoJS.AES.decrypt(cipherText, this.key);
    return bytes.toString(CryptoJS.enc.Utf8);
  }
}

Example Usage in Component

import { Component } from '@angular/core';
import { EncryptionService } from '../services/encryption.service';

@Component({
  selector: 'app-secure-form',
  templateUrl: './secure-form.component.html'
})
export class SecureFormComponent {
  password: string = '';

  constructor(private encryptionService: EncryptionService) {}

  submitForm() {
    const encryptedPassword = this.encryptionService.encrypt(this.password);
    // send encryptedPassword to backend via API
  }
}

Frontend Best Practices:

  1. Never store encryption keys in code, use environment variables or a secure key exchange mechanism.

  2. Use AES-256 or higher.

  3. Combine with HTTPS to prevent MITM attacks.

3. ASP.NET Core Backend Encryption

Backend encryption is critical for storing sensitive fields in the database.

Encrypting Fields Using AES

using System.Security.Cryptography;
using System.Text;

public class CryptoService
{
    private readonly byte[] _key;
    private readonly byte[] _iv;

    public CryptoService(IConfiguration config)
    {
        _key = Encoding.UTF8.GetBytes(config["Encryption:Key"]);
        _iv = Encoding.UTF8.GetBytes(config["Encryption:IV"]);
    }

    public string Encrypt(string plainText)
    {
        using var aes = Aes.Create();
        aes.Key = _key;
        aes.IV = _iv;

        var encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
        var plainBytes = Encoding.UTF8.GetBytes(plainText);

        var encryptedBytes = encryptor.TransformFinalBlock(plainBytes, 0, plainBytes.Length);
        return Convert.ToBase64String(encryptedBytes);
    }

    public string Decrypt(string cipherText)
    {
        using var aes = Aes.Create();
        aes.Key = _key;
        aes.IV = _iv;

        var decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
        var cipherBytes = Convert.FromBase64String(cipherText);

        var decryptedBytes = decryptor.TransformFinalBlock(cipherBytes, 0, cipherBytes.Length);
        return Encoding.UTF8.GetString(decryptedBytes);
    }
}

Key Best Practices:

  • Store keys securely (Azure Key Vault, AWS KMS, environment variables).

  • Never log plain text sensitive fields.

  • Use AES-256 with random IV for maximum security.

Storing Encrypted Data in SQL Server

Suppose we have a Users table:

CREATE TABLE Users
(
    Id INT PRIMARY KEY IDENTITY,
    Email NVARCHAR(256) NOT NULL,
    EncryptedPassword NVARCHAR(MAX) NOT NULL
);

Inserting encrypted password from ASP.NET Core:

var encryptedPassword = cryptoService.Encrypt(user.Password);
await dbContext.Users.AddAsync(new User
{
    Email = user.Email,
    EncryptedPassword = encryptedPassword
});
await dbContext.SaveChangesAsync();

Retrieving and decrypting:

var user = await dbContext.Users.FirstOrDefaultAsync(u => u.Email == email);
if (user != null)
{
    var password = cryptoService.Decrypt(user.EncryptedPassword);
}

4. SQL Server Encryption Features

SQL Server provides built-in encryption mechanisms:

Transparent Data Encryption (TDE)

  • Encrypts entire database at rest automatically.

  • Minimal changes to application.

  • Useful for compliance (PCI, HIPAA).

Column-Level Encryption

  • Use ENCRYPTBYPASSPHRASE for specific sensitive columns.

  • Allows application-level control but requires key management.

INSERT INTO Users (Email, EncryptedPassword)
VALUES ('[email protected]', ENCRYPTBYPASSPHRASE('MyPassphrase', 'MySecretPassword'));

Decryption:

SELECT Email, CONVERT(NVARCHAR, DECRYPTBYPASSPHRASE('MyPassphrase', EncryptedPassword))
FROM Users;

Always Encrypted

  • Client driver encrypts/decrypts data automatically.

  • Backend never sees plain text.

  • Ideal for highly sensitive fields like SSNs, credit cards.

5. Angular + Backend Integration Best Practices

  1. End-to-End Encryption: Encrypt in Angular if required by regulations.

  2. Secure Transport: Always use HTTPS for API calls.

  3. Backend Validation: Validate decrypted data before processing.

  4. Key Rotation: Regularly rotate encryption keys and manage old keys safely.

  5. Audit Logs: Track access to sensitive data without logging plaintext.

6. Hashing vs Encryption

Use CaseMethodNotes
PasswordsHashing (bcrypt)Never decrypt passwords. Store only hash.
Credit Card / PIIAES / Always EncryptedCan be decrypted for authorized use.
Token / Session DataAES / HMACCan verify integrity and decrypt securely.

Always hash passwords instead of encrypting. Use PBKDF2, bcrypt, or Argon2 for secure storage.

7. Security Considerations

  1. Never hard-code keys in Angular or backend code.

  2. Limit sensitive data exposure in logs or error messages.

  3. Use strong key derivation (PBKDF2, HKDF) if deriving encryption keys.

  4. Access Control: Only authorized services should decrypt sensitive data.

  5. Regular Penetration Testing: Validate implementation against common attacks.

8. Performance Considerations

  • AES encryption is fast, but avoid encrypting/decrypting large blobs frequently.

  • For database-heavy workloads, consider TDE + application-level encryption for critical fields only.

  • Cache decrypted results in memory if needed, but never persist in plain text.

  • Always profile encryption overhead in production.

9. Optional Enhancements

  1. Secure Key Management: Azure Key Vault, AWS KMS, HashiCorp Vault.

  2. Field-Level Access Control: Only specific roles can request decryption.

  3. Client-Side Masking: Mask data in UI while still encrypted in storage.

  4. Tokenization: Replace sensitive fields with secure tokens if full decryption is not required.

10. Summary

Encrypting sensitive data in Angular + ASP.NET Core + SQL Server requires a layered approach:

  1. HTTPS for data in transit.

  2. Application-layer encryption for sensitive fields (AES-256 recommended).

  3. Database encryption using Always Encrypted or TDE.

  4. Secure key management and rotation.

  5. Hash passwords using strong algorithms, never encrypt for storage.

With this strategy, you ensure:

  • Regulatory compliance (GDPR, PCI DSS, HIPAA).

  • Protection against data breaches.

  • Secure and maintainable architecture for enterprise applications.