1:MD5 不可逆加密
/// <summary>
/// MD5加密,和动网上的16/32位MD5加密结果相同,
/// 使用的UTF8编码
/// </summary>
/// <param name="source">待加密字串</param>
/// <param name="length">16或32值之一,其它则采用.net默认MD5加密算法</param>
/// <returns>加密后的字串</returns>
public static string Encrypt(string source, int length = 32)//默认参数
{
if (string.IsNullOrEmpty(source)) return string.Empty;
HashAlgorithm provider = CryptoConfig.CreateFromName("MD5") as HashAlgorithm;
byte[] bytes = Encoding.UTF8.GetBytes(source);//这里需要区别编码的
byte[] hashValue = provider.ComputeHash(bytes);
StringBuilder sb = new StringBuilder();
switch (length)
{
case 16://16位密文是32位密文的9到24位字符
for (int i = 4; i < 12; i++)
{
sb.Append(hashValue[i].ToString("x2"));
}
break;
case 32:
for (int i = 0; i < 16; i++)
{
sb.Append(hashValue[i].ToString("x2"));
}
break;
default:
for (int i = 0; i < hashValue.Length; i++)
{
sb.Append(hashValue[i].ToString("x2"));
}
break;
}
return sb.ToString();
}
用途:
/// 1 防止被篡改
/// 2 防止明文存储
/// 3 防止抵赖,数字签名
//1 防止看到明文
//密码–md5一下–保存–登陆的时候–输入的密码也md5一下–比对
//md5不能解密?不能解密 网上的解密都是基于样本比对
//密码复杂点 加盐(密码+ruanmou 再MD5)(双MD5)
//文件摘要,只有相同文件才能相同的md5
// 防篡改:下载VS安装文件(MD5)--官网--软件站下载(MD5)
//急速秒传:百度云--一瞬间就传完了--第一次上传,传完保存md5--先计算md5--比对--匹配了就不需要上传
// git/svn:md5比对
//任何数据MD5后结果都不一样,到目前为止还没碰到 2的128次方
//防抵赖:文章--md5(权威机构)
文件的MD5
/// <summary>
/// 获取文件的MD5摘要
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public static string AbstractFile(string fileName)
{
using (FileStream file = new FileStream(fileName, FileMode.Open))
{
return AbstractFile(file);
}
}
/// <summary>
/// 根据stream获取文件摘要
/// </summary>
/// <param name="stream"></param>
/// <returns></returns>
public static string AbstractFile(Stream stream)
{
MD5 md5 = new MD5CryptoServiceProvider();
byte[] retVal = md5.ComputeHash(stream);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < retVal.Length; i++)
{
sb.Append(retVal[i].ToString("x2"));
}
return sb.ToString();
}
Des可逆对称加密
对称:加密解密的密钥是一样的,,关键点就是保存藏好密钥,,但因为需要把密码传给解密的一方,所以安全是一个问题
public class DesEncrypt
{
private static byte[] _rgbKey = ASCIIEncoding.ASCII.GetBytes(Constant.DesKey.Substring(0, 8));
private static byte[] _rgbIV = ASCIIEncoding.ASCII.GetBytes(Constant.DesKey.Insert(0, "w").Substring(0, 8));
/// <summary>
/// DES 加密
/// </summary>
/// <param name="text">需要加密的值</param>
/// <returns>加密后的结果</returns>
public static string Encrypt(string text)
{
DESCryptoServiceProvider dsp = new DESCryptoServiceProvider();
using (MemoryStream memStream = new MemoryStream())
{
CryptoStream crypStream = new CryptoStream(memStream, dsp.CreateEncryptor(_rgbKey, _rgbIV), CryptoStreamMode.Write);
StreamWriter sWriter = new StreamWriter(crypStream);
sWriter.Write(text);
sWriter.Flush();
crypStream.FlushFinalBlock();
memStream.Flush();
return Convert.ToBase64String(memStream.GetBuffer(), 0, (int)memStream.Length);
}
}
/// <summary>
/// DES解密
/// </summary>
/// <param name="encryptText"></param>
/// <returns>解密后的结果</returns>
public static string Decrypt(string encryptText)
{
DESCryptoServiceProvider dsp = new DESCryptoServiceProvider();
byte[] buffer = Convert.FromBase64String(encryptText);
using (MemoryStream memStream = new MemoryStream())
{
CryptoStream crypStream = new CryptoStream(memStream, dsp.CreateDecryptor(_rgbKey, _rgbIV), CryptoStreamMode.Write);
crypStream.Write(buffer, 0, buffer.Length);
crypStream.FlushFinalBlock();
return ASCIIEncoding.UTF8.GetString(memStream.ToArray());
}
}
}
Rsa可逆非对称加密
/// <summary>
/// 获取加密/解密对
/// 给你一个,是无法推算出另外一个的
///
/// Encrypt Decrypt
/// </summary>
/// <returns>Encrypt Decrypt</returns>
public static KeyValuePair<string, string> GetKeyPair()
{
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
string publicKey = RSA.ToXmlString(false);
string privateKey = RSA.ToXmlString(true);
return new KeyValuePair<string, string>(publicKey, privateKey);
}
/// <summary>
/// 加密:内容+加密key
/// </summary>
/// <param name="content"></param>
/// <param name="encryptKey">加密key</param>
/// <returns></returns>
public static string Encrypt(string content, string encryptKey)
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(encryptKey);
UnicodeEncoding ByteConverter = new UnicodeEncoding();
byte[] DataToEncrypt = ByteConverter.GetBytes(content);
byte[] resultBytes = rsa.Encrypt(DataToEncrypt, false);
return Convert.ToBase64String(resultBytes);
}
/// <summary>
/// 解密 内容+解密key
/// </summary>
/// <param name="content"></param>
/// <param name="decryptKey">解密key</param>
/// <returns></returns>
public static string Decrypt(string content, string decryptKey)
{
byte[] dataToDecrypt = Convert.FromBase64String(content);
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
RSA.FromXmlString(decryptKey);
byte[] resultBytes = RSA.Decrypt(dataToDecrypt, false);
UnicodeEncoding ByteConverter = new UnicodeEncoding();
return ByteConverter.GetString(resultBytes);
}
/// <summary>
/// 可以合并在一起的,,每次产生一组新的密钥
/// </summary>
/// <param name="content"></param>
/// <param name="encryptKey">加密key</param>
/// <param name="decryptKey">解密key</param>
/// <returns>加密后结果</returns>
private static string Encrypt(string content, out string publicKey, out string privateKey)
{
RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider();
publicKey = rsaProvider.ToXmlString(false);
privateKey = rsaProvider.ToXmlString(true);
UnicodeEncoding ByteConverter = new UnicodeEncoding();
byte[] DataToEncrypt = ByteConverter.GetBytes(content);
byte[] resultBytes = rsaProvider.Encrypt(DataToEncrypt, false);
return Convert.ToBase64String(resultBytes);
}
//加密钥 解密钥 钥匙的功能划分
//公钥 私钥 公开程度划分
//根据需求 可以交错的,两组公钥密钥一块用就可以实现信息传输的完全加密,
数字签名实际上就是上面非对称加密时的认证模式,只不过做了一点点的改进,加入了散列算法。大家比较熟悉的散列算法可能就是MD5了,很多开源论坛都采用了这个算法。散列算法有三个特点:一是不可逆的,由结果无法推算出原数据;二是原数据哪怕是一丁点儿的变化,都会使散列值产生巨大的变化;三是不论多么大或者多么少的数据,总会产生固定长度的散列值(常见的为32位64位)。产生的散列值通常称为消息的摘要(digest)。
发送方
1.将消息进行散列运算,得到消息摘要。
2.使用自己的私钥对消息摘要加密(认证模式:确保了接收方能够确认自己)。
3.使用接收方的公钥对消息进行加密(加密模式:确保了消息只能由期望的接收方解密)。
4.发送消息和消息摘要。
接下来我们看一下接收方所执行的步骤:
1.使用发送方的公钥对消息摘要进行解密(确认了消息是由谁发送的)。
2.使用自己的私钥对消息进行解密(安全地获得了实际应获得的信息)。
3.将消息进行散列运算,获得消息摘要。
4.将上一步获得的消息摘要 和 第一步解密的消息摘要进行对比(确认了消息是否被篡改)。
证书机制
与数字签名相关的一个概念就是证书机制了,证书是用来做什么呢?在上面的各种模式中,我们一直使用了这样一个假设,就是接收方或者发送方所持有的、对方的公钥总是正确的(确实是对方公布的)。而实际上除非对方手把手将公钥交给我们,否则如果不采取措施,双方在网络中传递公钥时,一样有可能被篡改。那么怎样解决这个问题呢?这时就需要证书机制了:可以引入一个公正的第三方,当某一方想要发布公钥时,它将自身的身份信息及公钥提交给这个第三方,第三方对其身份进行证实,如果没有问题,则将其信息和公钥打包成为证书(Certificate)。而这个公正的第三方,就是常说的证书颁发机构(Certificate
Authority)。当我们需要获取公钥时,只需要获得其证书,然后从中提取出公钥就可以了。
SSL的验证过程如下图所示(单边验证) ssl加http就变成了https