首页 > 技术知识 > 正文

如果用户 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);

}

}

审核编辑:刘清

猜你喜欢