public class NmSecurity
{
/**************************************************
* FileName: NmSecurity.cs
* Version: 1.00
* Author: Kria
* Date: 2009-3-4
* Last Modified Date: 2009-3-6
* Function:
* CopyRight (c) Netmarch Company 2000-2003
* All rights reserved
**************************************************/
private static string encodingType = ConfigurationManager.AppSettings["EncryptStringEncoding"];
//------------------------------------加密部分开始----------------------------------------------------
/// <summary>
/// 使用MD5加密方法加密数据
/// </summary>
/// <param name="sourceData">用户密码等需要被MD5加密的源数据</param>
/// <returns>MD5加密后的形成字符串</returns>
public static string Md5(string sourceData)
{
return FormsAuthentication.HashPasswordForStoringInConfigFile(sourceData, "MD5");
}
/// <summary>
/// 返回二进制数组的Hash值
/// </summary>
/// <param name="sourceData">二进制数组</param>
/// <returns>产生的Hash值</returns>
public static string Hash(byte[] sourceData)
{
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
return BitConverter.ToString(md5.ComputeHash(sourceData)).Replace("-", "").ToLower();
}
/// <summary>
/// 获取随机对称加密密钥
/// </summary>
/// <returns>密钥字符串</returns>
public static string GenericSymmetricKey()
{
SymmetricAlgorithm sa = Rijndael.Create();
sa.GenerateKey();
return Convert.ToBase64String(sa.Key);
}
/// <summary>
/// 获取随机非对称加密密钥
/// </summary>
/// <returns>密钥字符串</returns>
public static string GenericAsymmetricKey()
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
return Convert.ToBase64String(rsa.ExportCspBlob(true));
}
/// <summary>
/// 从带私钥的密钥中获取只包含公钥的密钥
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static string GetPublicKey(string key)
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.ImportCspBlob(Convert.FromBase64String(key));
return Convert.ToBase64String(rsa.ExportCspBlob(false));
}
/// <summary>
/// 二进制流对二进制流的对称加密
/// </summary>
/// <param name="sourceData">需要加密的源数据</param>
/// <param name="key">16位或24位密钥,或者使用GenericSymmetricKey方法产生随机对称密钥</param>
/// <returns>加密后的二进制流形式的字节数组</returns>
public static byte[] SymmetricEncryptBinaryToBinary(byte[] sourceData, string key)
{
try
{
SymmetricAlgorithm sa = Rijndael.Create();
sa.Mode = CipherMode.ECB;
sa.Padding = PaddingMode.Zeros;
try
{
sa.Key = Convert.FromBase64String(key);
}
catch
{
sa.Key = Encoding.GetEncoding(encodingType).GetBytes(key);
}
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, sa.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(sourceData, 0, sourceData.Length);
cs.Close();
byte[] encryptBinaryData = ms.ToArray();
ms.Close();
return encryptBinaryData;
}
catch
{
throw new Exception("您所使用的密钥无效!");
}
}
/// <summary>
/// 二进制流对字符串的对称加密
/// </summary>
/// <param name="sourceData">需要加密的源数据</param>
/// <param name="key">16位或24位密钥,或者使用GenericSymmetricKey方法产生随机对称密钥</param>
/// <returns>加密后的形成的字符串</returns>
public static string SymmetricEncryptBinaryToString(byte[] sourceData, string key)
{
byte[] encryptBinaryData = SymmetricEncryptBinaryToBinary(sourceData, key);
return Convert.ToBase64String(encryptBinaryData);
}
/// <summary>
/// 字符串对二进制流的对称加密
/// </summary>
/// <param name="sourceData">需要加密的源数据</param>
/// <param name="key">16位或24位密钥,或者使用GenericSymmetricKey方法产生随机对称密钥</param>
/// <returns>加密后的二进制流形式的字节数组</returns>
public static byte[] SymmetricEncryptStringToBinary(string sourceData, string key)
{
byte[] byteData = Encoding.GetEncoding(encodingType).GetBytes(sourceData);
return SymmetricEncryptBinaryToBinary(byteData, key);
}
/// <summary>
/// 字符串对字符串的对称加密
/// </summary>
/// <param name="sourceData">需要加密的字符串</param>
/// <param name="key">16位或24位密钥,或者使用GenericSymmetricKey方法产生随机对称密钥</param>
/// <returns>加密后形成的字符串</returns>
public static string SymmetricEncryptStringToString(string sourceData, string key)
{
try
{
byte[] byteData = Encoding.GetEncoding(encodingType).GetBytes(sourceData);
byte[] encryptBinaryData = SymmetricEncryptBinaryToBinary(byteData, key);
return Convert.ToBase64String(encryptBinaryData);
}
catch
{
throw new Exception("您所使用的密钥无效!");
}
}
/// <summary>
/// 二进制流对二进制流的非对称加密
/// </summary>
/// <param name="sourceData">需要加密的源数据</param>
/// <param name="key">RSA密钥或者使用GenericAsymmetricKey方法产生随机非对称密钥</param>
/// <returns>加密后的二进制流形式的字节数组</returns>
public static byte[] AsymmetricEncryptBinaryToBinary(byte[] sourceData, string key)
{
try
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.ImportCspBlob(Convert.FromBase64String(key));
byte[] byteEncrypt = rsa.Encrypt(sourceData, false);
return byteEncrypt;
}
catch
{
throw new Exception("您所使用的密钥无效!");
}
}
/// <summary>
/// 二进制流对字符串的非对称加密
/// </summary>
/// <param name="sourceData">需要加密的源数据</param>
/// <param name="key">RSA密钥或者使用GenericAsymmetricKey方法产生随机非对称密钥</param>
/// <returns>加密后的形成的字符串</returns>
public static string AsymmetricEncryptBinaryToString(byte[] sourceData, string key)
{
byte[] byteEncrypt = AsymmetricEncryptBinaryToBinary(sourceData, key);
return Convert.ToBase64String(byteEncrypt);
}
/// <summary>
/// 字符串对二进制流的非对称加密
/// </summary>
/// <param name="sourceData">需要加密的字符串</param>
/// <param name="key">RSA密钥或者使用GenericAsymmetricKey方法产生随机非对称密钥</param>
/// <returns>加密后的二进制流形式的字节数组</returns>
public static byte[] AsymmetricEncryptStringToBinary(string sourceData, string key)
{
byte[] byteData = Encoding.GetEncoding(encodingType).GetBytes(sourceData);
byte[] byteEncrypt = AsymmetricEncryptBinaryToBinary(byteData, key);
return byteEncrypt;
}
/// <summary>
/// 字符串对字符串的非对称加密
/// </summary>
/// <param name="sourceData">需要加密的字符串</param>
/// <param name="key">RSA密钥或者使用GenericAsymmetricKey方法产生随机非对称密钥</param>
/// <returns>加密后的二进制流形式的字节数组</returns>
public static string AsymmetricEncryptStringToString(string sourceData, string key)
{
byte[] byteData = Encoding.GetEncoding(encodingType).GetBytes(sourceData);
byte[] byteEncrypt = AsymmetricEncryptBinaryToBinary(byteData, key);
return Convert.ToBase64String(byteEncrypt);
}
//--------------------------------------加密部分结束-----------------------------------------------------------
//--------------------------------------解密部分开始-----------------------------------------------------------
/// <summary>
/// 二进制流对二进制流的对称解密
/// </summary>
/// <param name="sourceData">加密后的二进制流</param>
/// <param name="key">对应加密的密钥</param>
/// <returns>解密后的二进制流</returns>
public static byte[] SymmetricDecryptBinaryToBinary(byte[] sourceData, string key)
{
try
{
SymmetricAlgorithm sa = Rijndael.Create();
sa.Mode = CipherMode.ECB;
sa.Padding = PaddingMode.Zeros;
try
{
sa.Key = Convert.FromBase64String(key);
}
catch
{
sa.Key = Encoding.GetEncoding(encodingType).GetBytes(key);
}
MemoryStream ms = new MemoryStream(sourceData);
CryptoStream cs = new CryptoStream(ms, sa.CreateDecryptor(), CryptoStreamMode.Read);
byte[] decryptBinaryData = new byte[sourceData.Length];
cs.Read(decryptBinaryData, 0, sourceData.Length);
int lastIndex = decryptBinaryData.Length;
while (lastIndex > 0 && decryptBinaryData[lastIndex - 1] == (byte)0)
{
lastIndex--;
}
byte[] subDecryptData = new byte[lastIndex];
System.Array.Copy(decryptBinaryData, subDecryptData, lastIndex);
return subDecryptData;
}
catch
{
throw new Exception("您所使用的密钥无效!");
}
}
/// <summary>
/// 二进制流对字符串的对称解密
/// </summary>
/// <param name="sourceData">加密后的二进制流</param>
/// <param name="key">对应加密的密钥</param>
/// <returns>经过解密后的字符串</returns>
public static string SymmetricDecryptBinaryToString(byte[] sourceData, string key)
{
byte[] decryptBinaryData=SymmetricDecryptBinaryToBinary(sourceData, key);
string decryptData = Encoding.GetEncoding(encodingType).GetString(decryptBinaryData);
return decryptData;
}
/// <summary>
/// 字符串对二进制流的对称解密
/// </summary>
/// <param name="sourceData">加密后的字符串</param>
/// <param name="key">对应加密的密钥</param>
/// <returns>经过解密后的二进制流</returns>
public static byte[] SymmetricDecryptStringToBinary(string sourceData, string key)
{
byte[] encryptBinaryData = Convert.FromBase64String(sourceData);
byte[] decryptBinaryData = SymmetricDecryptBinaryToBinary(encryptBinaryData, key);
return decryptBinaryData;
}
/// <summary>
/// 字符串对字符串的对称解密
/// </summary>
/// <param name="sourceData">加密后的字符串</param>
/// <param name="key">对应加密的密钥</param>
/// <returns>经过解密后的字符串</returns>
public static string SymmetricDecryptStringToString(string sourceData, string key)
{
byte[] encryptBinaryData = Convert.FromBase64String(sourceData);
byte[] decryptBinaryData = SymmetricDecryptBinaryToBinary(encryptBinaryData, key);
string decryptData = Encoding.GetEncoding(encodingType).GetString(decryptBinaryData);
return decryptData;
}
/// <summary>
/// 二进制流对二进制流的非对称解密
/// </summary>
/// <param name="sourceData">加密后的二进制流</param>
/// <param name="key">对应加密的密钥</param>
/// <returns>解密后的二进制流</returns>
public static byte[] AsymmetricDecryptBinaryToBinary(byte[] sourceData, string key)
{
try
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.ImportCspBlob(Convert.FromBase64String(key));
byte[] byteDecrypt = rsa.Decrypt(sourceData, false);
return byteDecrypt;
}
catch
{
throw new Exception("您所使用的密钥无效!");
}
}
/// <summary>
/// 二进制流对字符串的非对称解密
/// </summary>
/// <param name="sourceData">加密后的二进制流</param>
/// <param name="key">对应加密的密钥</param>
/// <returns>经过解密后的字符串</returns>
public static string AsymmetricDecryptBinaryToString(byte[] sourceData, string key)
{
byte[] byteDecrypt = AsymmetricDecryptBinaryToBinary(sourceData, key);
return Encoding.GetEncoding(encodingType).GetString(byteDecrypt);
}
/// <summary>
/// 字符串对而二进制流的非对称解密
/// </summary>
/// <param name="sourceData">加密后的字符串</param>
/// <param name="key">对应加密的密钥</param>
/// <returns>解密后的二进制流</returns>
public static byte[] AsymmetricDecryptStringToBinary(string sourceData, string key)
{
byte[] byteData = Convert.FromBase64String(sourceData);
byte[] byteDecrypt = AsymmetricDecryptBinaryToBinary(byteData, key);
return byteDecrypt;
}
/// <summary>
/// 字符串对字符串的非对称解密
/// </summary>
/// <param name="sourceData">加密后的字符串</param>
/// <param name="key">对应加密的密钥</param>
/// <returns>经过解密后的字符串</returns>
public static string AsymmetricDecryptStringToString(string sourceData, string key)
{
byte[] byteData = Convert.FromBase64String(sourceData);
byte[] byteDecrypt = AsymmetricDecryptBinaryToBinary(byteData, key);
return Encoding.GetEncoding(encodingType).GetString(byteDecrypt);
}
//----------------------------------------------带签名验证的加密解密---------------------------------------------
/// <summary>
/// 二进制流对字符串的带签名的验证加密
/// </summary>
/// <param name="sourceData">需要加密的二进制流源数据</param>
/// <param name="localKey">本地密钥</param>
/// <param name="remoteKey">远程密钥</param>
/// <returns>加密后的数据字符串</returns>
public static string SignatureEncryptBinaryToString(byte[] sourceData, string localKey, string remoteKey)
{
try
{
RSACryptoServiceProvider rsaLocal = new RSACryptoServiceProvider();
RSACryptoServiceProvider rsaRemote = new RSACryptoServiceProvider();
rsaLocal.ImportCspBlob(Convert.FromBase64String(localKey));
rsaRemote.ImportCspBlob(Convert.FromBase64String(remoteKey));
SymmetricAlgorithm sa = Rijndael.Create();
sa.GenerateIV();
//将对称密钥使用非对称加密算法加密并转换成base64
string saKey = Convert.ToBase64String(rsaRemote.Encrypt(sa.Key, false));
//用默认密钥进行对称加密
sa.Mode = CipherMode.ECB;
sa.Padding = PaddingMode.Zeros;
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, sa.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(sourceData, 0, sourceData.Length);
cs.Close();
byte[] encryptBinaryData = ms.ToArray();
ms.Close();
string encryptData = Convert.ToBase64String(encryptBinaryData);
//签名
string sinagture = Convert.ToBase64String(rsaLocal.SignData(encryptBinaryData, new SHA1CryptoServiceProvider()));
//返回结果:密文+密钥+签名
return encryptData + "," + saKey + "," + sinagture;
}
catch
{
throw new Exception("您所使用的密钥无效!");
}
}
/// <summary>
/// 二进制流对二进制流的带签名的验证加密
/// </summary>
/// <param name="sourceData">需要加密的二进制流源数据</param>
/// <param name="localKey">本地密钥</param>
/// <param name="remoteKey">远程密钥</param>
/// <returns>加密后的二进制流数据</returns>
public static byte[] SignatureEncryptBinaryToBinary(byte[] sourceData, string localKey, string remoteKey)
{
string encryptResult = SignatureEncryptBinaryToString(sourceData, localKey, remoteKey);
return Encoding.GetEncoding(encodingType).GetBytes(encryptResult);
}
/// <summary>
/// 字符串对二进制流的带签名的验证加密
/// </summary>
/// <param name="sourceData">需要加密的字符串源数据</param>
/// <param name="localKey">本地密钥</param>
/// <param name="remoteKey">远程密钥</param>
/// <returns>加密后的二进制流数据</returns>
public static byte[] SignatureEncryptStringToBinary(string sourceData, string localKey, string remoteKey)
{
//将要加密的数据转换成二进制数据
byte[] binaryData = Encoding.GetEncoding(encodingType).GetBytes(sourceData);
string encryptResult = SignatureEncryptBinaryToString(binaryData, localKey, remoteKey);
return Encoding.GetEncoding(encodingType).GetBytes(encryptResult);
}
/// <summary>
/// 二进制流对字符串的带签名的验证加密
/// </summary>
/// <param name="sourceData">需要加密的字符串源数据</param>
/// <param name="localKey">本地密钥</param>
/// <param name="remoteKey">远程密钥</param>
/// <returns>加密后的字符串数据</returns>
public static string SignatureEncryptStringToString(string sourceData, string localKey, string remoteKey)
{
//将要加密的数据转换成二进制数据
byte[] binaryData = Encoding.GetEncoding(encodingType).GetBytes(sourceData);
return SignatureEncryptBinaryToString(binaryData, localKey, remoteKey);
}
/// <summary>
/// 字符串对二进制流的带签名的验证解密
/// </summary>
/// <param name="sourceData">需要解密的字符串源数据</param>
/// <param name="localKey">本地密钥</param>
/// <param name="remoteKey">远程密钥</param>
/// <returns>解密后的二进制流数据</returns>
public static byte[] SignatureDecryptStringToBinary(string sourceData, string localKey, string remoteKey)
{
try
{
if (string.IsNullOrEmpty(sourceData))
{
return null;
}
string[] dataParts = sourceData.Split(',');
if (dataParts.Length != 3)
{
return null;
}
string encryptData = dataParts[0];
string saKey = dataParts[1];
string sinature = dataParts[2];
byte[] encryptBinaryData = Convert.FromBase64String(encryptData);
RSACryptoServiceProvider rsaLocal = new RSACryptoServiceProvider();
RSACryptoServiceProvider rsaRemote = new RSACryptoServiceProvider();
rsaLocal.ImportCspBlob(Convert.FromBase64String(localKey));
rsaRemote.ImportCspBlob(Convert.FromBase64String(remoteKey));
SymmetricAlgorithm sa = Rijndael.Create();
//验证签名
if (!rsaRemote.VerifyData(encryptBinaryData, new SHA1CryptoServiceProvider(), Convert.FromBase64String(sinature)))
{
throw new Exception("验证签名失败!");
}
//还原对称加密Key
sa.Key = rsaLocal.Decrypt(Convert.FromBase64String(saKey), false);
//用默认密钥进行对称解密
sa.Mode = CipherMode.ECB; //块处理模式
sa.Padding = PaddingMode.Zeros; //末尾数据块的填充模式
MemoryStream ms = new MemoryStream(encryptBinaryData);
CryptoStream cs = new CryptoStream(ms, sa.CreateDecryptor(), CryptoStreamMode.Read);
byte[] decryptBinaryData = new byte[encryptBinaryData.Length];
cs.Read(decryptBinaryData, 0, encryptBinaryData.Length);
int lastIndex = decryptBinaryData.Length;
while (lastIndex > 0 && decryptBinaryData[lastIndex - 1] == (byte)0)
{
lastIndex--;
}
byte[] subDecryptData = new byte[lastIndex];
System.Array.Copy(decryptBinaryData, subDecryptData, lastIndex);
return subDecryptData;
}
catch
{
throw new Exception("您所使用的密钥无效!");
}
}
/// <summary>
/// 二进制流对二进制流的带签名的验证解密
/// </summary>
/// <param name="sourceData">需要解密的二进制流源数据</param>
/// <param name="localKey">本地密钥</param>
/// <param name="remoteKey">远程密钥</param>
/// <returns>解密后的二进制流数据</returns>
public static byte[] SignatureDecryptBinaryToBinary(byte[] sourceData, string localKey, string remoteKey)
{
string encryptData = Encoding.GetEncoding(encodingType).GetString(sourceData);
byte[] decryptBinaryData = SignatureDecryptStringToBinary(encryptData, localKey, remoteKey);
return decryptBinaryData;
}
/// <summary>
/// 二进制流对字符串的带签名的验证解密
/// </summary>
/// <param name="sourceData">需要解密的二进制流源数据</param>
/// <param name="localKey">本地密钥</param>
/// <param name="remoteKey">远程密钥</param>
/// <returns>解密后的字符串数据</returns>
public static string SignatureDecryptBinaryToString(byte[] sourceData, string localKey, string remoteKey)
{
string encryptData = Encoding.GetEncoding(encodingType).GetString(sourceData);
byte[] decryptBinaryData = SignatureDecryptStringToBinary(encryptData, localKey, remoteKey);
string decryptData = Encoding.GetEncoding(encodingType).GetString(decryptBinaryData);
return decryptData;
}
/// <summary>
/// 字符串对字符串的带签名的验证解密
/// </summary>
/// <param name="sourceData">需要解密的字符串源数据</param>
/// <param name="localKey">本地密钥</param>
/// <param name="remoteKey">远程密钥</param>
/// <returns>解密后的字符串数据</returns>
public static string SignatureDecryptStringToString(string sourceData, string localKey, string remoteKey)
{
byte[] decryptBinaryData = SignatureDecryptStringToBinary(sourceData, localKey, remoteKey);
string decryptData = Encoding.GetEncoding(encodingType).GetString(decryptBinaryData);
return decryptData;
}
public static string RsaEncrypt(string data, string localKey, string remoteKey)
{
RSACryptoServiceProvider rsaLocal = new RSACryptoServiceProvider();
RSACryptoServiceProvider rsaRemote = new RSACryptoServiceProvider();
rsaLocal.ImportCspBlob(Convert.FromBase64String(localKey));
rsaRemote.ImportCspBlob(Convert.FromBase64String(remoteKey));
SymmetricAlgorithm sa = Rijndael.Create();
sa.GenerateIV();
//将对称密钥使用非对称加密算法加密并转换成base64
string saKey = Convert.ToBase64String(rsaRemote.Encrypt(sa.Key, false));
//将要加密的数据转换成二进制数据
byte[] binaryData = Encoding.UTF8.GetBytes(data);
byte[] encryptBinaryData = null;
string encryptData = null;
string sinagture = null;
//对称加密开始
sa.Mode = CipherMode.ECB; //块处理模式
sa.Padding = PaddingMode.Zeros; //末尾数据块的填充模式
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, sa.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(binaryData, 0, binaryData.Length);
cs.Close();
encryptBinaryData = ms.ToArray();
ms.Close();
encryptData = Convert.ToBase64String(encryptBinaryData);
//对称加密结束
//签名
sinagture = Convert.ToBase64String(rsaLocal.SignData(encryptBinaryData, new SHA1CryptoServiceProvider()));
//返回结果:密文+密钥+签名
return encryptData + "," + saKey + "," + sinagture;
}
public static string RsaDecrypt(string data, string localKey, string remoteKey)
{
if (string.IsNullOrEmpty(data))
{
return null;
}
string[] dataParts = data.Split(',');
if (dataParts.Length != 3)
{
return null;
}
string encryptData = dataParts[0];
string saKey = dataParts[1];
string sinature = dataParts[2];
byte[] encryptBinaryData = Convert.FromBase64String(encryptData);
RSACryptoServiceProvider rsaLocal = new RSACryptoServiceProvider();
RSACryptoServiceProvider rsaRemote = new RSACryptoServiceProvider();
rsaLocal.ImportCspBlob(Convert.FromBase64String(localKey));
rsaRemote.ImportCspBlob(Convert.FromBase64String(remoteKey));
SymmetricAlgorithm sa = Rijndael.Create();
//验证签名
if (!rsaRemote.VerifyData(encryptBinaryData, new SHA1CryptoServiceProvider(), Convert.FromBase64String(sinature)))
{
return null;
}
//还原对称加密Key
sa.Key = rsaLocal.Decrypt(Convert.FromBase64String(saKey), false);
//对称解密开始
sa.Mode = CipherMode.ECB; //块处理模式
sa.Padding = PaddingMode.Zeros; //末尾数据块的填充模式
MemoryStream ms = new MemoryStream(encryptBinaryData);
CryptoStream cs = new CryptoStream(ms, sa.CreateDecryptor(), CryptoStreamMode.Read);
byte[] decryptBinaryData = new byte[encryptBinaryData.Length];
cs.Read(decryptBinaryData, 0, encryptBinaryData.Length);
int lastIndex = decryptBinaryData.Length;
while (lastIndex > 0 && decryptBinaryData[lastIndex - 1] == (byte)0)
{
lastIndex--;
}
string decryptData = Encoding.UTF8.GetString(decryptBinaryData, 0, lastIndex);
//对称解密结束
return decryptData;
}
}