纸质时代,当写信,或者使用支票的时候,签上自己的名字,就表示这是自己写的,当别人拿到信的时候,如果认识笔迹,或者银行拿到支票后,进行一系列验证,验证这个支票的真伪,前面的操作就是签名,说明是自己写的,后面的检验,就是验签,确认书写者身份。
信息时代,也有这方面的需要。
要确保信息是某人发送的,不让别个知道里面的内容,而且中间没有被修改,同时信息要完整。(信息安全三要素,有效性(Availability):信息的使用者是合法的,保密性(Confidentiality):信息在传输时不被泄露,有效性(Availability):信息的使用者是合法的)
这个时候,首先想到的就是加密了。
加密有对称加密,和非对称加密 这两种算法
对称加密,使用一个密码来进行加密和解密,比如我约定规则,用明文(3)乘以4,在加1,这样得到(3*4+1)密文13,另外一个人得到13后,用我们相同的约定,在反向推(13-1)/4=3,就得到我的明文,电视里面密码本就是这样的。大家都知道怎么解密的约定
非对称加密,明文,用A加密,用B解密,加密和解密分别使用不同的规则。
目前大部分都是采用非对称加密算法
其中,公匙密码就是非对称加密的算法的一个具体事列,公匙密码又称为非对称密码。拥有公匙密码的人分别拥有加密密匙和解密密匙,通过加密密匙不能得到解密密匙,同时加密密匙是公开的。
李四拥有公匙密码,他想获得张三的银行卡密码66666,就把公匙给了张三,张三用公密加密后,通过网络传给李四,其他人获取到了这个密文后,没有私密解不开,只有李四知道私密,可以解开,这样,就保证了信息的安全性,好像不能保证信息发送人就是张三,这个特性,其他人要是获得了这个公匙,也能给李四发信息。
这个时候,我们进行逆运算,我用私匙加密,用公匙解密,因为只有私匙加密的东西,我才能用对应的公匙进行解开。同时我解密的时候,我就能确认发送人了。(为什么了?)
数字签名(名词):某种密码运算生成一系列符号及代码组成电子密码进行签名,这个来表示是自己签名
数字签名(动词):用私匙来加密,用公匙来解密,就是公共密码的逆运算。
一般开发阶段,我们都是使用到的是其他第三方给我们的东西进行加密和解密,一般会给我们这2个文件
其中后缀为 .cer的通常存放公钥,后缀为.pfx的通常存放私钥(包含公匙和私匙,对方还会给你一个密码,用来解开这个私匙的密码)
NET中提供类 X509Certificate2,命名空间 System.Security.Cryptography中,这个类实列化后就表示一个类
X509Certificate2 c3 = DataCertificate.GetCertificateFromPfxFile("d:\\mycert\\NT999.pfx", "000000");
string keyPublic3 = c3.PublicKey.Key.ToXmlString(false); // 公钥
string keyPrivate3 = c3.PrivateKey.ToXmlString(true); // 私钥
string check_value = HashAndSignString(uJson, keyPrivate3); // 加密,原文,私匙
bool bt = VerifySigned(uJson, check_value, keyPublic3);//验签
///
/// 数字签名
///
/// 原文
/// 私钥
///
public static string HashAndSignString(string plaintext, string privateKey)
{
UnicodeEncoding ByteConverter = new UnicodeEncoding();
byte[] dataToEncrypt = ByteConverter.GetBytes(plaintext);
using (RSACryptoServiceProvider RSAalg = new RSACryptoServiceProvider())
{
RSAalg.FromXmlString(privateKey);
//使用SHA1进行摘要算法,生成签名
byte[] encryptedData = RSAalg.SignData(dataToEncrypt, new SHA1CryptoServiceProvider());
return Convert.ToBase64String(encryptedData);
}
}
///
/// 验证签名
///
/// 原文
/// 签名
/// 公钥
///
public static bool VerifySigned(string plaintext, string SignedData, string publicKey)
{
using (RSACryptoServiceProvider RSAalg = new RSACryptoServiceProvider())
{
RSAalg.FromXmlString(publicKey);
UnicodeEncoding ByteConverter = new UnicodeEncoding();
byte[] dataToVerifyBytes = ByteConverter.GetBytes(plaintext);
byte[] signedDataBytes = Convert.FromBase64String(SignedData);
return RSAalg.VerifyData(dataToVerifyBytes, new SHA1CryptoServiceProvider(), signedDataBytes);
}
}
这就是一套流程。
生成签名
一般来说,不直接对消息进行签名,而是对消息的哈希值进行签名,步骤如下。
1, 对消息进行哈希计算,得到哈希值
2, 利用私钥对哈希值进行加密,生成签名
3, 将签名附加在消息后面,一起发送过去
验证签名
1, 收到消息后,提取消息中的签名
2, 用公钥对签名进行解密,得到哈希值1。
3, 对消息中的正文进行哈希计算,得到哈希值2。
4, 比较哈希值1和哈希值2,如果相同,则验证成功。
这种机构称为认证机构(Certification Authority, CA)。CA就是能够认定”公钥确实属于此人”,并能生成公钥的数字签名的组织或机构。CA有国际性组织和政府设立的组织,也有通过提供认证服务来盈利的组织。
注:私钥B是用于加密公钥A的,私钥B和公钥A并不是配对的。
客户端用公钥验证数字签名,检查消息的完整性和服务器的合法性
后续再慢慢写
转载:https://www.jianshu.com/p/9db57e761255
转载:https://segmentfault.com/a/1190000004461428
新手浅谈证书加解密、签名验签
参考:http://blog.csdn.net/weixin_33602978/article/details/71599672
ASP.net 使用证书认证
参考:http://blog.csdn.net/wsxqaz/article/details/5389883
参考:https://www.cnblogs.com/atongmyuxiaowanzi/p/5329558.html