C# 加密总结 一些常见的加密方法
一 散列数据 代码如下:
View Code?
private static string CalculateSHA512Hash(string input) { byte[] inputBytes = Encoding.UTF8.GetBytes(input); SHA512Managed sha512 = new SHA512Managed(); byte[] outputBytes = sha512.ComputeHash(inputBytes); return Convert.ToBase64String(outputBytes); }
原始散列对于彩虹表来说也存在漏洞,在彩虹表中,表内的每一条记录都是一串明文对应一种加密算法生成的一串密文。加盐就是指在密码中加入一个盐,这样可以提高密码散列的安全性。修改后的代码如下:
View Code?
private static string CalculateSHA512Hash(string input,string salt)
{ byte[] saltBytes = Convert.FromBase64String(salt);
byte[] inputBytes = Encoding.UTF8.GetBytes(input);
byte[] inputWithSaltBytes = new byte[saltBytes.Length + inputBytes.Length];
Array.Copy(inputBytes, 0, inputWithSaltBytes, 0, inputBytes.Length);
Array.Copy(saltBytes, 0, inputWithSaltBytes, inputBytes.Length, saltBytes.Length); SHA512Managed sha512 = new SHA512Managed();
byte[] outputBytes = sha512.ComputeHash(inputWithSaltBytes);
return Convert.ToBase64String(outputBytes);
} private static string GetSalt(int minSaltSize, int maxSaltSize)
{ Random random = new Random();
int saltSize = random.Next(minSaltSize, maxSaltSize);
byte[] saltBytes = new byte[saltSize];
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetNonZeroBytes(saltBytes);
return Convert.ToBase64String(saltBytes);
}
二 对称加密
View Code?
private static string Encrypt(string input, byte[] key, byte[] iv)
{ byte[] inputBytes = Encoding.UTF8.GetBytes(input);
RijndaelManaged rijndael = new RijndaelManaged();
ICryptoTransform transform = rijndael.CreateEncryptor(key, iv);
byte[] encrytData = null;
using (MemoryStream outputStream = new MemoryStream())
{ using (CryptoStream inputStream = new CryptoStream(outputStream, transform, CryptoStreamMode.Write))
{ inputStream.Write(inputBytes, 0,
inputBytes.Length);
inputStream.FlushFinalBlock();
encrytData = outputStream.ToArray();
} } return Convert.ToBase64String(encrytData);
} private static string Decrypt(string input, byte[] key, byte[] iv)
{ byte[] inputBytes=Convert.FromBase64String(input);
RijndaelManaged rijndael = new RijndaelManaged();
ICryptoTransform transform = rijndael.CreateDecryptor(key, iv);
byte[] decryptByte;
using (MemoryStream outputStream=new MemoryStream())
{ using (CryptoStream inputStream=new CryptoStream(outputStream,transform,CryptoStreamMode.Write))
{ inputStream.Write(inputBytes, 0, inputBytes.Length);
inputStream.FlushFinalBlock();
decryptByte = outputStream.ToArray();
} } return Encoding.UTF8.GetString(decryptByte);
} private static void GetKeyAndIVFromPasswordAndSalt(string password, byte[] salt,
SymmetricAlgorithm symmetricAlgorithm,
ref byte[] key, ref byte[] iv)
{ Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, salt);
key = rfc2898DeriveBytes.GetBytes(symmetricAlgorithm.KeySize / 8);
iv = rfc2898DeriveBytes.GetBytes(symmetricAlgorithm.BlockSize / 8);
} private static string GetSalt(int minSaltSize, int maxSaltSize)
{ Random random = new Random();
int saltSize = random.Next(minSaltSize, maxSaltSize);
byte[] saltBytes = new byte[saltSize];
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
rng.GetNonZeroBytes(saltBytes);
return Convert.ToBase64String(saltBytes); }
调用方式:
byte[] salt = Convert.FromBase64String(GetSalt(9, 18));
string password = "Password";
byte[] key=new byte[0];
byte[] iv = new byte[0];
GetKeyAndIVFromPasswordAndSalt(password,salt, new RijndaelManaged(), ref key, ref iv);
string input = "Wrox Press";
string encrytText = Encrypt(input, key, iv);
Console.WriteLine(encrytText);
string decryptText=Decrypt(encrytText,key,iv);
Console.WriteLine(decryptText);
只是简单的加密和解密数据是不够的,我们还需要确保数据不被改变,我们可以创建一个消息认证代码来生成一个加密的散列。
?private static string GenerateMac(string input, byte[] key)
{
HMACSHA512 hmac = new HMACSHA512(key);
byte[] data= hmac.ComputeHash(Convert.FromBase64String(input));
return Convert.ToBase64String(data);
}
static bool IsMacValid(string input, byte[] key, string savedMac)
{
string recalculateMac = GenerateMac(input, key);
return recalculateMac.Equals(savedMac);
}
例如我们对数据库中LicenseNumber加密,那么我们就必须修改表结构,修改后如图:
非对称加密:
View Code?
private static string Encrypt(string input, string publickey)
{ RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(1024);
rsa.FromXmlString(publickey);
byte[] encryptData = rsa.Encrypt(Encoding.UTF8.GetBytes(input), true);
return Convert.ToBase64String(encryptData);
} private static string Decrypt(string input, string privatekey)
{ RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(1024);
rsa.FromXmlString(privatekey);
byte[] dencryptData = rsa.Decrypt(Convert.FromBase64String(input), true);
return Encoding.UTF8.GetString(dencryptData);
} private static void GetkeyXml(out string publicKey, out string privateKey)
{ RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(1024);
publicKey = rsa.ToXmlString(false);
privateKey = rsa.ToXmlString(true); }
证书加密:
View Code?
static byte[] SignData(byte[] clearText, X509Certificate2 signingCertificate)
{ ContentInfo contentInfo = new ContentInfo(clearText);
CmsSigner signer = new CmsSigner(signingCertificate);
SignedCms signedCms = new SignedCms(contentInfo);
signedCms.ComputeSignature(signer);
return signedCms.Encode();
} static byte[] ValidateSignatureAndExtractContent(byte[] signedCmsAsBytes, ICollection<string> signingSubjects)
{ SignedCms signedCms = new SignedCms();
signedCms.Decode(signedCmsAsBytes);
signedCms.CheckSignature(true);
foreach (SignerInfo signerInfo in signedCms.SignerInfos)
{ X509Certificate2 signingCertificate = signerInfo.Certificate;
signingSubjects.Add(signingCertificate.Subject);
} return signedCms.ContentInfo.Content;
} static byte[] EncryptWithCertificate(byte[] clearText, X509Certificate2 certificate)
{ ContentInfo contentInfo = new ContentInfo(clearText);
EnvelopedCms envelopedCms = new EnvelopedCms(contentInfo);
CmsRecipient recipient = new CmsRecipient(certificate);
envelopedCms.Encrypt(recipient);
return envelopedCms.Encode();
} static byte[] DecryptWithCertificate(byte[] cipherText)
{ EnvelopedCms envelopedCms = new EnvelopedCms();
envelopedCms.Decode(cipherText);
envelopedCms.Decrypt();
return envelopedCms.ContentInfo.Content;
} static X509Certificate2 LoadCertificateFromFile(string filename)
{ X509Certificate2 certificate = new X509Certificate2();
certificate.Import(ReadBinaryFile(filename));
return certificate;
} static byte[] ReadBinaryFile(string filename)
{ FileStream f = new FileStream(filename, FileMode.Open, FileAccess.Read);
int size = (int)f.Length;
byte[] data = new byte[size];
size = f.Read(data, 0, size);
f.Close();
return data;
} private static X509Certificate2 GetCertificateBySubjectName(string subjectName)
{ X509Store myStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);
myStore.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certificateCollection = myStore.Certificates.Find
(X509FindType.FindBySubjectName, subjectName, true);
X509Certificate2 myCertificate = certificateCollection[0];
if (myStore != null) myStore.Close();
return myCertificate; }
调用方式:
string input = "Wrox Press";
byte[] clearTextAsBytes = Encoding.UTF8.GetBytes(input);
X509Certificate2 serverPublicKeyCertificate = LoadCertificateFromFile("IISExpress.cer");
X509Certificate2 signingCertificate = GetCertificateBySubjectName("test");
byte[] signedClearText = SignData(clearTextAsBytes, signingCertificate);
byte[] encryptedAndSignedData = EncryptWithCertificate(signedClearText, serverPublicKeyCertificate);
byte[] encodedUnencryptedCms = DecryptWithCertificate(encryptedAndSignedData);
List<string> signingSubjects = new List<string>();
byte[] receivedClearText = ValidateSignatureAndExtractContent(encodedUnencryptedCms, signingSubjects);
string unecnryptedString = Encoding.UTF8.GetString(receivedClearText);
Console.ReadLine();
我的计算机是win8,这里并没有用什么企业级证书,作为测试,我是用win8中IIS来创建自签名证书,然后用mmc来管理证书 所以以上的GetCertificateBySubjectName方法需要修改如下:
private static X509Certificate2 GetCertificateBySubjectName(string subjectName)
{
X509Store myStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);
myStore.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certificateCollection = myStore.Certificates.Find(X509FindType.FindBySubjectName, subjectName, true);
X509Certificate2 myCertificate;
if (certificateCollection.Count > 0)
{
myCertificate = certificateCollection[0];
}
else
{
X509Certificate2[] array = new X509Certificate2[myStore.Certificates.Count];
myStore.Certificates.CopyTo(array, 0);
myCertificate = array.FirstOrDefault(x => x.FriendlyName.Equals(subjectName));
}
if (myStore != null)
myStore.Close();
return myCertificate;
}
- 09-26多线程开发中线程数量设计问题
- 09-26Go语言和Java、Python等其他语言的对比分析
- 09-26Java语言为什么经久不衰?且总能霸占编程语言排行榜首?
- 09-26浅谈10个提升应用程序10倍性能的技巧
- 06-10利用Python语言判断狗狗年龄的程序
- 12-09用c写了个后台扫描
- 01-11全球最受赞誉公司揭晓:苹果连续九年第一
- 12-09罗伯特·莫里斯:让黑客真正变黑
- 12-09谁闯入了中国网络?揭秘美国绝密黑客小组TA
- 12-09警示:iOS6 惊现“闪退”BUG
- 11-18LG新能源宣布与Bear Robotics达成合作,成为
- 11-18机构:三季度全球个人智能音频设备市场强势
- 11-18闲鱼:注册用户过6亿 AI技术已应用于闲置交
- 11-18美柚、宝宝树回应“涉黄短信骚扰”:未发现
- 11-01京东七鲜与前置仓完成融合