如果用户 A 要和 B 进行数据交换,A 要通过网络发送一段文字给 B,那如何保证数据在传输的过程中是安全的呢?并且即使被别人截获,也无法知道数据的内容,这就用到加密技术。
对称密码体制
发送方用一个密钥对数据进行加密,接收方使用相同的密钥进行解密。
• 加密和解密 的密钥相同
• 如何获取或交换密钥,保证密钥的私密性非常重要
• 密钥量级是参与者的平方级数,数量比较多
• 适合对大量数据进行加密,加密解密速度快
• 加解密易于通过硬件实现
非对称密码体制
每个网络参与者都有一对密钥 - 私钥和公钥。用户 A 的公钥是公开的,任何与 A 通信的人都可以获取,用来加密数据后发送给 A。A 的私钥只有自己知道,用来解密数据。
• 公钥用来加密,私钥用来解密。公私钥不相同也不相关
• 公钥的交换无需保密
• 密钥的量级为参与者的数目
• 加解密速度慢,不适合大量数据加密,常用于 对称密码 协商共享密钥
• 加解密操作难以通过硬件实现
数字签名
用户 A 发送给 B,B 如何确定数据是用户 A 发送的,而不是别人伪造的数据呢?数字签名可以鉴别消息的发送者
• 用户 A 先将要发送的数据进行 MD5 计算生成唯一的 消息摘要 a
• A 用私钥签名消息摘要 a
• A 把数据和消息摘要 a 组合起来发送给 B
• B 收到后用 A 的公钥对消息摘要验签得到 a
• B 用 MD5 算法对数据部分进行计算得到消息摘要 b
• B 对 a 和 b 进行比较。如果相同则证明是 A 发送过来的
A 计算数据的消息摘要,并用私钥进行加密的过程称为 签名算法。B 用 A 的公钥解密消息摘要,并与自己计算的消息摘要进行对比的过程称为 验证算法。
如果直接对数据本身直接计算数字签名,会比较耗时。所以一般做法是先将原数据进行 Hash 运算,得到的 Hash 值就叫做“摘要”。
数字证书
用户 A 要给用户 B 发送数据,如何保证用户 A 拿到的一定是用户 B 的公钥呢?
数字证书是标志通讯各方身份信息的一串数字,不是数字身份证而是身份认证机构盖在数字身份证上的一个章或印。由权威机构-CA(Certificate Authority)发行的,用来识别对方的身份。
X.509是一种通用的证书规范。
常见的数字证书格式:
• .cer .crt - 用于存放证书,它是二进制形式存放的,不含私钥。
• .pfx .p12 - 存放个人证书/私钥,通常包含保护密码,2 进制方式
从证书文件获得证书对象:
X509Certificate2 cert = new X509Certificate2 (@"c:/myCert.crt" );
// 保护密码
String password = GetCertPassword();
X509Certificate2 cert = new X509Certificate2 (@"c:/myCert.pfx", password);
从本地证书容器获得证书对象:
private static X509Certificate2 GetCertificateFromStore(string certName)
{
// Get the certificate store for the current user.
X509Store store = new X509Store(StoreLocation.CurrentUser);
try
{
store.Open(OpenFlags.ReadOnly);
// Place all certificates in an X509Certificate2Collection object.
X509Certificate2Collection certCollection = store.Certificates;
// If using a certificate with a trusted root you do not need to FindByTimeValid, instead:
// currentCerts.Find(X509FindType.FindBySubjectDistinguishedName, certName, true);
X509Certificate2Collection currentCerts = certCollection.Find(X509FindType.FindByTimeValid, DateTime.Now, false);
X509Certificate2Collection signingCert = currentCerts.Find(X509FindType.FindBySubjectDistinguishedName, certName, false);
if (signingCert.Count == 0)
return null;
// Return the first certificate in the collection, has the right name and is current.
return signingCert[0];
}
finally
{
store.Close();
}
}
// 验证证书有效期
if (cert.NotAfter <= DateTime .Now)
{
throw new ApplicationException (" 用户证书已经过期!" );
}
// 获取公钥
RSA publickKey = (RSA)cert.PublicKey.Key;
RSA privateKey = cert.GetRSAPrivateKey();
public class RSAHelper
{
/// RSA加密
///
///公钥
///
///
public static string RSAEncrypt(string xmlPublicKey, string m_strEncryptString)
{
RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
provider.FromXmlString(xmlPublicKey);
byte[] bytes = new UnicodeEncoding().GetBytes(m_strEncryptString);
return Convert.ToBase64String(provider.Encrypt(bytes, false));
}
///
/// RSA解密
///
///私钥
///
///
public static string RSADecrypt(string xmlPrivateKey, string m_strDecryptString)
{
RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
provider.FromXmlString(xmlPrivateKey);
byte[] rgb = Convert.FromBase64String(m_strDecryptString);
byte[] bytes = provider.Decrypt(rgb, false);
return new UnicodeEncoding().GetString(bytes);
}
}
审核编辑:刘清
全部0条评论
快来发表一下你的评论吧 !