架构思路
- 密钥生成:使用PKI体系,每台服务器生成自己的公私钥对。公钥用于加密数据和验证签名,私钥用于解密数据和生成签名。
- 密钥管理:建立一个证书颁发机构(CA),服务器向CA注册并获取数字证书,证书包含服务器的公钥及相关身份信息,CA用自己的私钥对证书签名。
- 密钥分发:服务器间通过交换数字证书来共享公钥。
- 数据签名:发送方用自己的私钥对数据的哈希值进行签名,以确保不可抵赖性。
- 签名验证:接收方用发送方的公钥验证签名,确保数据未被篡改且来源可靠。
- 数据加密:发送方用接收方的公钥对数据进行加密。
- 数据解密:接收方用自己的私钥对加密数据进行解密。
关键代码片段
- 生成密钥对
using System.Security.Cryptography;
// 生成RSA密钥对
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048))
{
string publicKey = rsa.ToXmlString(false);
string privateKey = rsa.ToXmlString(true);
// 存储或分发密钥
}
- 数据签名
using System.Security.Cryptography;
using System.Text;
string data = "要签名的数据";
byte[] dataBytes = Encoding.UTF8.GetBytes(data);
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048))
{
// 假设已从存储中加载私钥
rsa.FromXmlString(privateKey);
byte[] hashBytes = SHA256.Create().ComputeHash(dataBytes);
byte[] signature = rsa.SignHash(hashBytes, CryptoConfig.MapNameToOID("SHA256"));
}
- 签名验证
using System.Security.Cryptography;
using System.Text;
string receivedData = "接收到的数据";
byte[] receivedDataBytes = Encoding.UTF8.GetBytes(receivedData);
byte[] receivedSignature = // 接收到的签名
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048))
{
// 假设已从证书中加载发送方公钥
rsa.FromXmlString(publicKey);
byte[] hashBytes = SHA256.Create().ComputeHash(receivedDataBytes);
bool isValid = rsa.VerifyHash(hashBytes, CryptoConfig.MapNameToOID("SHA256"), receivedSignature);
}
- 数据加密
using System.Security.Cryptography;
using System.Text;
string dataToEncrypt = "要加密的数据";
byte[] dataToEncryptBytes = Encoding.UTF8.GetBytes(dataToEncrypt);
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048))
{
// 假设已从证书中加载接收方公钥
rsa.FromXmlString(publicKey);
byte[] encryptedData = rsa.Encrypt(dataToEncryptBytes, false);
}
- 数据解密
using System.Security.Cryptography;
using System.Text;
byte[] encryptedData = // 接收到的加密数据
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048))
{
// 假设已从存储中加载自己的私钥
rsa.FromXmlString(privateKey);
byte[] decryptedData = rsa.Decrypt(encryptedData, false);
string decryptedText = Encoding.UTF8.GetString(decryptedData);
}