一、数据加密概述
数据加密是将明文转换为密文的过程,在数据密集型应用中,加密是保障数据安全的核心技术,包括传输加密和存储加密两个方面。
二、加密算法分类
2.1 加密算法分类
graph TD
A[加密算法] --> B[对称加密]
A --> C[非对称加密]
A --> D[哈希算法]
A --> E[消息认证码]
B --> B1[AES]
B --> B2[DES]
B --> B3[3DES]
C --> C1[RSA]
C --> C2[ECC]
C --> C3[DSA]
D --> D1[SHA-256]
D --> D2[SHA-3]
D --> D3[MD5]
E --> E1[HMAC]
E --> E2[CMAC]
2.2 加密算法对比
| 算法类型 | 代表算法 | 密钥长度 | 性能 | 安全性 | 适用场景 |
|---|---|---|---|---|---|
| 对称加密 | AES-256 | 256位 | 极高 | 高 | 数据加密 |
| 非对称加密 | RSA-2048 | 2048位 | 低 | 高 | 密钥交换 |
| 非对称加密 | ECC-256 | 256位 | 中等 | 高 | 移动端 |
| 哈希算法 | SHA-256 | 256位 | 高 | 高 | 数据校验 |
| 消息认证码 | HMAC-SHA256 | 256位 | 高 | 高 | 身份验证 |
三、对称加密算法
3.1 AES加密实现
public class AesEncryptionService
{
public byte[] Encrypt(byte[] data, byte[] key, byte[] iv)
{
using var aes = Aes.Create();
aes.Key = key;
aes.IV = iv;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
using var encryptor = aes.CreateEncryptor();
using var memoryStream = new MemoryStream();
using var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write);
cryptoStream.Write(data, 0, data.Length);
cryptoStream.FlushFinalBlock();
return memoryStream.ToArray();
}
public byte[] Decrypt(byte[] encryptedData, byte[] key, byte[] iv)
{
using var aes = Aes.Create();
aes.Key = key;
aes.IV = iv;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
using var decryptor = aes.CreateDecryptor();
using var memoryStream = new MemoryStream(encryptedData);
using var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);
using var resultStream = new MemoryStream();
cryptoStream.CopyTo(resultStream);
return resultStream.ToArray();
}
public (byte[] Key, byte[] IV) GenerateKeyAndIV()
{
using var aes = Aes.Create();
aes.GenerateKey();
aes.GenerateIV();
return (aes.Key, aes.IV);
}
public string EncryptToBase64(string plainText, string keyBase64)
{
var key = Convert.FromBase64String(keyBase64);
var (_, iv) = GenerateKeyAndIV();
var plainBytes = Encoding.UTF8.GetBytes(plainText);
var encrypted = Encrypt(plainBytes, key, iv);
return Convert.ToBase64String(iv.Concat(encrypted).ToArray());
}
public string DecryptFromBase64(string cipherTextBase64, string keyBase64)
{
var key = Convert.FromBase64String(keyBase64);
var cipherBytes = Convert.FromBase64String(cipherTextBase64);
var iv = cipherBytes.Take(16).ToArray();
var encrypted = cipherBytes.Skip(16).ToArray();
var decrypted = Decrypt(encrypted, key, iv);
return Encoding.UTF8.GetString(decrypted);
}
}
3.2 AES-GCM加密(带认证)
public class AesGcmEncryptionService
{
public byte[] Encrypt(byte[] data, byte[] key, byte[] nonce, byte[] associatedData)
{
var tag = new byte[16];
var encrypted = new byte[data.Length];
using var aes = Aes.Create();
aes.Key = key;
using var gcm = new GcmAuthenticatedEncryption(aes);
gcm.Encrypt(nonce, data, encrypted, tag, associatedData);
return nonce.Concat(tag).Concat(encrypted).ToArray();
}
public byte[] Decrypt(byte[] encryptedData, byte[] key, byte[] associatedData)
{
var nonce = encryptedData.Take(12).ToArray();
var tag = encryptedData.Skip(12).Take(16).ToArray();
var cipherText = encryptedData.Skip(28).ToArray();
var decrypted = new byte[cipherText.Length];
using var aes = Aes.Create();
aes.Key = key;
using var gcm = new GcmAuthenticatedEncryption(aes);
gcm.Decrypt(nonce, cipherText, tag, decrypted, associatedData);
return decrypted;
}
public byte[] GenerateNonce()
{
var nonce = new byte[12];
RandomNumberGenerator.Fill(nonce);
return nonce;
}
}
四、非对称加密算法
4.1 RSA加密实现
public class RsaEncryptionService
{
public (byte[] PublicKey, byte[] PrivateKey) GenerateKeyPair(int keySize = 2048)
{
using var rsa = RSA.Create(keySize);
return (
rsa.ExportSubjectPublicKeyInfo(),
rsa.ExportPkcs8PrivateKey()
);
}
public byte[] Encrypt(byte[] data, byte[] publicKey)
{
using var rsa = RSA.Create();
rsa.ImportSubjectPublicKeyInfo(publicKey, out _);
return rsa.Encrypt(data, RSAEncryptionPadding.OaepSHA256);
}
public byte[] Decrypt(byte[] encryptedData, byte[] privateKey)
{
using var rsa = RSA.Create();
rsa.ImportPkcs8PrivateKey(privateKey, out _);
return rsa.Decrypt(encryptedData, RSAEncryptionPadding.OaepSHA256);
}
public byte[] Sign(byte[] data, byte[] privateKey)
{
using var rsa = RSA.Create();
rsa.ImportPkcs8PrivateKey(privateKey, out _);
return rsa.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pss);
}
public bool VerifySignature(byte[] data, byte[] signature, byte[] publicKey)
{
using var rsa = RSA.Create();
rsa.ImportSubjectPublicKeyInfo(publicKey, out _);
return rsa.VerifyData(data, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pss);
}
}
4.2 ECC加密实现
public class EccEncryptionService
{
public (byte[] PublicKey, byte[] PrivateKey) GenerateKeyPair()
{
using var ecc = ECDsa.Create(ECCurve.NamedCurves.nistP256);
return (
ecc.ExportSubjectPublicKeyInfo(),
ecc.ExportPkcs8PrivateKey()
);
}
public byte[] Sign(byte[] data, byte[] privateKey)
{
using var ecc = ECDsa.Create();
ecc.ImportPkcs8PrivateKey(privateKey, out _);
return ecc.SignData(data, HashAlgorithmName.SHA256);
}
public bool VerifySignature(byte[] data, byte[] signature, byte[] publicKey)
{
using var ecc = ECDsa.Create();
ecc.ImportSubjectPublicKeyInfo(publicKey, out _);
return ecc.VerifyData(data, signature, HashAlgorithmName.SHA256);
}
public byte[] DeriveSharedSecret(byte[] privateKey, byte[] otherPublicKey)
{
using var ecc = ECDiffieHellman.Create();
ecc.ImportPkcs8PrivateKey(privateKey, out _);
var otherEcc = ECDiffieHellman.Create();
otherEcc.ImportSubjectPublicKeyInfo(otherPublicKey, out _);
return ecc.DeriveKeyMaterial(otherEcc.PublicKey);
}
}
五、哈希算法
5.1 SHA-256哈希实现
public class HashService
{
public byte[] ComputeSha256(byte[] data)
{
using var sha256 = SHA256.Create();
return sha256.ComputeHash(data);
}
public string ComputeSha256Hex(string input)
{
var bytes = Encoding.UTF8.GetBytes(input);
var hash = ComputeSha256(bytes);
return BitConverter.ToString(hash).Replace("-", "").ToLower();
}
public byte[] ComputeSha384(byte[] data)
{
using var sha384 = SHA384.Create();
return sha384.ComputeHash(data);
}
public byte[] ComputeSha512(byte[] data)
{
using var sha512 = SHA512.Create();
return sha512.ComputeHash(data);
}
public byte[] ComputeSha3(byte[] data)
{
using var sha3 = SHA3.Create();
return sha3.ComputeHash(data);
}
public bool VerifyHash(byte[] data, byte[] expectedHash)
{
var computedHash = ComputeSha256(data);
return computedHash.SequenceEqual(expectedHash);
}
}
5.2 HMAC消息认证码
public class HmacService
{
public byte[] ComputeHmacSha256(byte[] data, byte[] key)
{
using var hmac = new HMACSHA256(key);
return hmac.ComputeHash(data);
}
public string ComputeHmacSha256Hex(string input, string key)
{
var dataBytes = Encoding.UTF8.GetBytes(input);
var keyBytes = Encoding.UTF8.GetBytes(key);
var hash = ComputeHmacSha256(dataBytes, keyBytes);
return BitConverter.ToString(hash).Replace("-", "").ToLower();
}
public byte[] ComputeHmacSha512(byte[] data, byte[] key)
{
using var hmac = new HMACSHA512(key);
return hmac.ComputeHash(data);
}
public bool VerifyHmac(byte[] data, byte[] expectedHmac, byte[] key)
{
var computedHmac = ComputeHmacSha256(data, key);
return computedHmac.SequenceEqual(expectedHmac);
}
public string GenerateToken(string userId, string secretKey, TimeSpan expiresIn)
{
var payload = new
{
UserId = userId,
ExpiresAt = DateTime.UtcNow.Add(expiresIn).ToUnixTimeSeconds()
};
var payloadJson = JsonSerializer.Serialize(payload);
var payloadBytes = Encoding.UTF8.GetBytes(payloadJson);
var keyBytes = Encoding.UTF8.GetBytes(secretKey);
var signature = ComputeHmacSha256(payloadBytes, keyBytes);
return $"{Convert.ToBase64String(payloadBytes)}.{Convert.ToBase64String(signature)}";
}
public bool ValidateToken(string token, string secretKey)
{
var parts = token.Split('.');
if (parts.Length != 2)
{
return false;
}
var payloadBytes = Convert.FromBase64String(parts[0]);
var signature = Convert.FromBase64String(parts[1]);
var keyBytes = Encoding.UTF8.GetBytes(secretKey);
var computedSignature = ComputeHmacSha256(payloadBytes, keyBytes);
if (!computedSignature.SequenceEqual(signature))
{
return false;
}
var payloadJson = Encoding.UTF8.GetString(payloadBytes);
var payload = JsonSerializer.Deserialize(payloadJson);
return payload.ExpiresAt > DateTime.UtcNow.ToUnixTimeSeconds();
}
}
六、密钥管理
6.1 密钥管理架构
graph TD
A[密钥管理] --> B[密钥生成]
A --> C[密钥存储]
A --> D[密钥分发]
A --> E[密钥轮换]
A --> F[密钥销毁]
B --> B1[随机数生成]
B --> B2[密钥派生]
C --> C1[密钥库]
C --> C2[HSM]
D --> D1[TLS]
D --> D2[非对称加密]
E --> E1[定期轮换]
E --> E2[事件触发]
F --> F1[安全擦除]
F --> F2[密钥归档]
6.2 密钥管理实现
public class KeyManagementService
{
public async Task GenerateKeyAsync(string keyId, KeyType keyType, int keySize = 256)
{
byte[] key = null;
switch (keyType)
{
case KeyType.Aes:
key = GenerateAesKey(keySize);
break;
case KeyType.Rsa:
var (publicKey, privateKey) = _rsaService.GenerateKeyPair(keySize);
key = privateKey;
break;
}
var keyInfo = new KeyInfo
{
KeyId = keyId,
KeyType = keyType,
KeySize = keySize,
CreatedAt = DateTime.UtcNow,
Status = KeyStatus.Active,
Version = 1
};
await _keyStorage.StoreKeyAsync(keyId, key, keyInfo);
return keyInfo;
}
public async Task GetKeyAsync(string keyId)
{
return await _keyStorage.GetKeyAsync(keyId);
}
public async Task RotateKeyAsync(string keyId)
{
var oldKeyInfo = await _keyStorage.GetKeyInfoAsync(keyId);
var newKey = GenerateAesKey(oldKeyInfo.KeySize);
var newKeyInfo = new KeyInfo
{
KeyId = keyId,
KeyType = oldKeyInfo.KeyType,
KeySize = oldKeyInfo.KeySize,
CreatedAt = DateTime.UtcNow,
Status = KeyStatus.Active,
Version = oldKeyInfo.Version + 1
};
await _keyStorage.ArchiveKeyAsync(keyId, oldKeyInfo.Version);
await _keyStorage.StoreKeyAsync(keyId, newKey, newKeyInfo);
return newKeyInfo;
}
public async Task DeleteKeyAsync(string keyId)
{
await _keyStorage.DeleteKeyAsync(keyId);
}
private byte[] GenerateAesKey(int keySize)
{
var key = new byte[keySize / 8];
RandomNumberGenerator.Fill(key);
return key;
}
}
6.3 密钥存储
public class KeyStorageService
{
public async Task StoreKeyAsync(string keyId, byte[] key, KeyInfo keyInfo)
{
var encryptedKey = _aesService.Encrypt(key, _masterKey, _masterIv);
await _database.SaveKeyAsync(new KeyRecord
{
KeyId = keyId,
EncryptedKey = encryptedKey,
KeyInfo = keyInfo,
CreatedAt = DateTime.UtcNow
});
}
public async Task GetKeyAsync(string keyId)
{
var keyRecord = await _database.GetKeyAsync(keyId);
return _aesService.Decrypt(keyRecord.EncryptedKey, _masterKey, _masterIv);
}
public async Task ArchiveKeyAsync(string keyId, int version)
{
await _database.ArchiveKeyAsync(keyId, version);
}
public async Task DeleteKeyAsync(string keyId)
{
await _database.DeleteKeyAsync(keyId);
}
public async Task GetKeyInfoAsync(string keyId)
{
var keyRecord = await _database.GetKeyAsync(keyId);
return keyRecord.KeyInfo;
}
}
七、传输加密
7.1 TLS配置
public class TlsConfigurationService
{
public SslStream CreateSslStream(Stream innerStream, bool leaveInnerStreamOpen)
{
var sslOptions = new SslServerAuthenticationOptions
{
ServerCertificate = _certificate,
EnabledSslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13,
ClientCertificateRequired = false,
EncryptionPolicy = EncryptionPolicy.RequireEncryption
};
return new SslStream(innerStream, leaveInnerStreamOpen);
}
public HttpClient CreateSecureHttpClient()
{
var handler = new HttpClientHandler
{
SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13,
ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) =>
{
if (sslPolicyErrors == SslPolicyErrors.None)
{
return true;
}
return false;
}
};
return new HttpClient(handler);
}
public void ConfigureHttpsServer(WebHostBuilder builder)
{
builder.UseKestrel(options =>
{
options.ListenAnyIP(443, listenOptions =>
{
listenOptions.UseHttps(_certificatePath, _certificatePassword);
listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
});
});
}
}
八、加密最佳实践
8.1 加密算法选型
| 场景 | 推荐算法 | 密钥长度 |
|---|---|---|
| 数据加密 | AES-GCM | 256位 |
| 密钥交换 | RSA-OAEP | 2048+位 |
| 数字签名 | ECDSA | 256位 |
| 哈希校验 | SHA-256 | 256位 |
| 消息认证 | HMAC-SHA256 | 256位 |
8.2 密钥管理最佳实践
- 使用随机数生成器生成密钥
- 定期轮换密钥
- 使用HSM存储主密钥
- 加密存储密钥
- 限制密钥访问权限
8.3 安全注意事项
public class EncryptionSecurityService
{
public bool ValidateKeySize(KeyType keyType, int keySize)
{
return keyType switch
{
KeyType.Aes => keySize >= 256,
KeyType.Rsa => keySize >= 2048,
KeyType.Ecc => keySize >= 256,
_ => false
};
}
public void ValidateEncryptionMode(CipherMode mode)
{
if (mode != CipherMode.CBC && mode != CipherMode.GCM)
{
throw new InvalidOperationException("Unsupported cipher mode");
}
}
public bool IsAlgorithmSupported(string algorithm)
{
var supportedAlgorithms = new[] { "AES", "RSA", "ECDSA", "SHA-256", "SHA-384", "SHA-512" };
return supportedAlgorithms.Contains(algorithm);
}
public void ValidateNonce(byte[] nonce)
{
if (nonce == null || nonce.Length != 12)
{
throw new InvalidOperationException("Invalid nonce");
}
}
}
九、总结
数据加密是保障数据安全的核心技术。对称加密适合大量数据加密,非对称加密适合密钥交换,哈希算法适合数据校验,HMAC适合消息认证。通过合理选择加密算法、实现密钥管理、配置传输加密,能够构建安全的数据密集型应用。