作者:魅力无穷2 | 来源:互联网 | 2023-09-18 12:13
一,思路 对称加密含有一个被称为密钥的东西,在消息发送前使用密钥对消息进行加密,得到密文并发送,接收方收到密文后,使用相同的密钥进行解密,获得原消息。 PS:使用密
一,思路
对称加密含有一个被称为密钥的东西,在消息发送前使用密钥对消息进行加密,得到密文并发送,接收方收到密文后,使用相同的密钥进行解密,获得原消息。
PS:使用密钥对消息进行加密的过程,由加密算法来完成的,加密算法通常也是公开的。
二,对称加密的流程
1,发送方和接收方持有相同的密钥,并严格保密
2,发送方使用密钥对消息进行加密,然后发送消息
3,接收方收到消息后,使用相同的密钥对消息进行解密
PS:在这一过程中,第三方可能截获消息,但得到的知识一堆乱码
三,Demo
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Security.Cryptography; //注意引入此命名空间
using System.IO;
namespace 对称加密与解密
{
class Program
{
static void Main(string[] args)
{
string key = "secret key"; //密钥
string plainText = "hello,world"; //明文
string encryptedText = SymmetricCryPtoHelper.Encrypt(plainText, key); //加密
Console.WriteLine(encryptedText);
string clearText = SymmetricCryPtoHelper.Decrypt(encryptedText, key); //解密
Console.WriteLine(clearText);
Console.ReadKey();
}
}
///
/// 对称加密帮助类
///
/// Editor:v-liuhch CreateTime:2015/5/15 22:05:41
public class SymmetricCryPtoHelper
{
//对称加密算法提供器
private ICryptoTransform encryptor;//加密器对象
private ICryptoTransform decryptor;//解密器对象
private const int BufferSize = 1024;
///
/// Initializes a new instance of the class.
///
/// Name of the algorithm.
/// The key.
/// Editor:v-liuhch
public SymmetricCryPtoHelper(string algorithmName, byte[] key)
{
//SymmetricAlgorithm为对称算法基类
SymmetricAlgorithm provider = SymmetricAlgorithm.Create(algorithmName);
provider.Key = key;//指定密钥,通常为128位或者196位
provider.IV = new byte[] { 0x12,0x34,0x56,0x78,0x90,0xAB,0xCD,0xEF};//Initialization vector ,初始化向量,避免了加密之后文字的相关部分也是重复的问题,通常为64位
encryptor = provider.CreateEncryptor();//创建加密器对象
decryptor = provider.CreateDecryptor();//创建解密器对象
}
public SymmetricCryPtoHelper(byte[] key) : this("TripleDES", key) { }
//加密算法
///
/// Encrypts the specified clear text.
///
/// The clear text.
/// System.String.
/// Editor:v-liuhch CreateTime:2015/5/17 16:56:15
public string Encrypt(string clearText) {
//创建明文流
byte[] clearBuffer = Encoding.UTF8.GetBytes(clearText);
MemoryStream clearStream = new MemoryStream(clearBuffer);
//创建空的密文流
MemoryStream encryptedStream = new MemoryStream();
/* 加密解密涉及到两个流,一个是明文流,一个是密文流
那么必然有一个中介者,将明文流转换成密文流;或者将密文流转换成明文流;
* .net中执行这个操作的中介者是一个流类型,叫做CryptoStream;
*
* 加密时构造函数参数:
* 1,Stream:密文流(此时密文流还没有包含数据,仅仅是一个空流);
* 2,ICryptoTransform:创建的加密器,负责进行加密计算,
* 3,枚举:write,将流经CryptoStream的明文流写入到密文流中,最后从密文流中获得加密后的数据
*/
CryptoStream cryptoStream = new CryptoStream(encryptedStream, encryptor, CryptoStreamMode.Write);
//将明文流写入到buffer中
//将buffer中的数据写入到cryptoStream中
int bytesRead = 0;
byte[] buffer = new byte[BufferSize];
do
{
bytesRead = clearStream.Read(buffer, 0, BufferSize);
cryptoStream.Write(buffer, 0, bytesRead);
} while (bytesRead>0);
cryptoStream.FlushFinalBlock();//清除缓冲区
//获取加密后的文本
buffer = encryptedStream.ToArray();
string encryptedText = Convert.ToBase64String(buffer);
return encryptedText;
}
///
/// 解密算法
///
/// The encrypted text.
/// System.String.
/// Editor:v-liuhch CreateTime:2015/5/17 16:56:22
public string Decrypt(string encryptedText)
{
byte[] encryptedBuffer = Convert.FromBase64String(encryptedText);
Stream encryptedStream = new MemoryStream(encryptedBuffer);
MemoryStream clearStream = new MemoryStream();
/*
解密时构造函数参数:
* 1,Stream:密文流(此时密文流包含数据);
* 2,ICryptoTransform:创建的解密器,负责进行解密计算,
* 3,枚举:write,将密文流中的数据读出到明文流,进而再转换成明文的,原来的格式
*/
CryptoStream cryptoStream = new CryptoStream(encryptedStream, decryptor, CryptoStreamMode.Read);
int bytesRead = 0;
byte[] buffer = new byte[BufferSize];
do
{
bytesRead = cryptoStream.Read(buffer, 0, BufferSize);
clearStream.Write(buffer, 0, bytesRead);
} while (bytesRead>0);
buffer = clearStream.GetBuffer();
string clearText = Encoding.UTF8.GetString(buffer, 0, (int)clearStream.Length);
return clearText;
}
///
/// Encrypts the specified clear text.
///
/// The clear text.
/// The key.
/// System.String.
/// Editor:v-liuhch CreateTime:2015/5/17 16:56:40
public static string Encrypt(string clearText, string key) {
byte[] keyData = new byte[16];
byte[] sourceData = Encoding.Default.GetBytes(key);
int copyBytes = 16;
if (sourceData.Length<16)
{
copyBytes = sourceData.Length;
}
Array.Copy(sourceData, keyData, copyBytes);
SymmetricCryPtoHelper helper = new SymmetricCryPtoHelper(keyData);
return helper.Encrypt(clearText);
}
///
/// Decrypts the specified encrypted text.
///
/// The encrypted text.
/// The key.
/// System.String.
/// Editor:v-liuhch CreateTime:2015/5/17 16:56:44
public static string Decrypt(string encryptedText, string key)
{
byte[] keyData = new byte[16];
byte[] sourceData = Encoding.Default.GetBytes(key);
int copyBytes = 16;
if (sourceData.Length<16)
{
copyBytes = sourceData.Length;
}
Array.Copy(sourceData, keyData, copyBytes);
SymmetricCryPtoHelper helper = new SymmetricCryPtoHelper(keyData);
return helper.Decrypt(encryptedText);
}
}
}
四,隐患问题
1,发送方和接收方都需要持有密钥,并保证密钥不被泄露。
2,如果第三方非法获得了密钥,在对消息进行篡改后,重新加密发给接收方,则接收方无法辨别。既然无法判断消息是否被篡改,也无法确定消息是由谁发送过来的,无法满足完整性和可认证性。
.Net加密与解密——对称加密