RSA生成C#的XML格式的公鑰和私鑰以及Java的Base64位公、私鑰參考文章:C# RAS生成.NET公鑰與私鑰以及.NET公鑰與私鑰轉Java公鑰私鑰類
目錄
簡介
本文主要講解一下C#常用的那些加密算法,包括MD5、Base64、SHA1、SHA256、HmacSHA256、DES、AES、RSA加密等,有需要的朋友可以參考下
需要引用的類
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
還需要安裝 BouncyCastle
在菜單欄找到 工具 —> NuGet 包管理器 —> 管理解決方案的NuGet程序包 —> 瀏覽 —> 搜索 “BouncyCastle” —> 安裝
我自己定義的公共字段;有需要的朋友可以自行定義
private static CspParameters Param;
/// <summary>
/// SK(Secret Access Key):與訪問密鑰ID結合使用的密鑰,對請求進行加密簽名,可標識發送方,並防止請求被修改
/// </summary>
public static string _appSecret = ConfigurationManager.AppSettings["appSecret"].ToString();
/// <summary>
/// AK(Access Key ID):訪問密鑰ID。與私有訪問密鑰關聯的唯一標識符;訪問密鑰ID和私有訪問密鑰一起使用,對請求進行加密簽名
/// </summary>
public static string _appKey = ConfigurationManager.AppSettings["appKey"].ToString();
/// <summary>
/// DES密鑰
/// </summary>
private static byte[] _KEY = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
/// <summary>
/// DES向量
/// </summary>
private static byte[] _IV = new byte[] { 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01 };
/// <summary>
/// RSA加密/解密的默認公鑰
/// </summary>
private static string _publicKey = @"<RSAKeyValue><Modulus>5m9m14XH3oqLJ8bNGw9e4rGpXpcktv9MSkHSVFVMjHbfv+SJ5v0ubqQxa5YjLN4vc49z7SVju8s0X4gZ6AzZTn06jzWOgyPRV54Q4I0DCYadWW4Ze3e+BOtwgVU1Og3qHKn8vygoj40J6U85Z/PTJu3hN1m75Zr195ju7g9v4Hk=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
/// <summary>
/// RSA解密/加密的默認私鑰
/// </summary>
private static string _privateKey = @"<RSAKeyValue><Modulus>5m9m14XH3oqLJ8bNGw9e4rGpXpcktv9MSkHSVFVMjHbfv+SJ5v0ubqQxa5YjLN4vc49z7SVju8s0X4gZ6AzZTn06jzWOgyPRV54Q4I0DCYadWW4Ze3e+BOtwgVU1Og3qHKn8vygoj40J6U85Z/PTJu3hN1m75Zr195ju7g9v4Hk=</Modulus><Exponent>AQAB</Exponent><P>/hf2dnK7rNfl3lbqghWcpFdu778hUpIEBixCDL5WiBtpkZdpSw90aERmHJYaW2RGvGRi6zSftLh00KHsPcNUMw==</P><Q>6Cn/jOLrPapDTEp1Fkq+uz++1Do0eeX7HYqi9rY29CqShzCeI7LEYOoSwYuAJ3xA/DuCdQENPSoJ9KFbO4Wsow==</Q><DP>ga1rHIJro8e/yhxjrKYo/nqc5ICQGhrpMNlPkD9n3CjZVPOISkWF7FzUHEzDANeJfkZhcZa21z24aG3rKo5Qnw==</DP><DQ>MNGsCB8rYlMsRZ2ek2pyQwO7h/sZT8y5ilO9wu08Dwnot/7UMiOEQfDWstY3w5XQQHnvC9WFyCfP4h4QBissyw==</DQ><InverseQ>EG02S7SADhH1EVT9DD0Z62Y0uY7gIYvxX/uq+IzKSCwB8M2G7Qv9xgZQaQlLpCaeKbux3Y59hHM+KpamGL19Kg==</InverseQ><D>vmaYHEbPAgOJvaEXQl+t8DQKFT1fudEysTy31LTyXjGu6XiltXXHUuZaa2IPyHgBz0Nd7znwsW/S44iql0Fen1kzKioEL3svANui63O3o5xdDeExVM6zOf1wUUh/oldovPweChyoAdMtUzgvCbJk1sYDJf++Nr0FeNW1RB1XG30=</D></RSAKeyValue>";
/// <summary>
/// 8位加密密鑰
/// </summary>
private static string keys = "olikjhgb";
/// <summary>
/// 16位的加密秘鑰
/// </summary>
private static string Key = "1123uyrlouhd@_Lq";
/// <summary>
/// 16位以上的默認向量
/// </summary>
private static string vector = "*abcdefghijklmnopqrst@";
一、MD5加密
- MD5加密是最常見的加密方式,因為MD5是不可逆的,所以很多系統的密碼都是用MD5加密保存的。
- 雖說MD5加密不可逆,但是我們可以對明文再次加密,進行兩次加密的密文進行對比
#region MD5加密解密
/// <summary>
/// 16位MD5加密
/// </summary>
/// <param name="laws">需要加密的明文字符串</param>
/// <returns></returns>
public static string MD5Encrypt16(string laws)
{
var md5 = new MD5CryptoServiceProvider();
string cipherText = BitConverter.ToString(md5.ComputeHash(Encoding.Default.GetBytes(laws)), 4, 8);
cipherText = cipherText.Replace("-", "");
return cipherText;
}
/// <summary>
/// 32位MD5加密
/// </summary>
/// <param name="laws">需要加密的明文字符串</param>
/// <returns>32位MD5加密密文字符串</returns>
public static string MD5Encrypt32(string laws)
{
string plainText = laws;
string rule = "";
MD5 md5 = MD5.Create(); //實例化一個md5對像
// 加密后是一個字節類型的數組,這里要注意編碼UTF8/Unicode等的選擇
byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(plainText));
// 通過使用循環,將字節類型的數組轉換為字符串,此字符串是常規字符格式化所得
for (int i = 0; i < s.Length; i++)
{
// 將得到的字符串使用十六進制類型格式。格式后的字符是小寫的字母,如果使用大寫(X)則格式后的字符是大寫字符
rule = rule + s[i].ToString("x2");
}
return rule;
}
/// <summary>
/// 64位MD5加密
/// </summary>
/// <param name="laws">需要加密的明文字符串</param>
/// <returns>64位MD5加密密文字符串</returns>
public static string MD5Encrypt64(string laws)
{
string rule = laws;
MD5 md5 = MD5.Create(); //實例化一個md5對像
// 加密后是一個字節類型的數組,這里要注意編碼UTF8/Unicode等的選擇
byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(rule));
return Convert.ToBase64String(s);
}
/// <summary>
/// 對字符串進MD5加密
/// </summary>
/// <param name="sourceStr">源類型</param>
/// <returns>加密后字符串</returns>
public static string Md5Encrypt(string sourceStr)
{
MD5 md5 = new MD5CryptoServiceProvider();
//將要加密的字符串轉換成字節數組
byte[] palindata = Encoding.Default.GetBytes(sourceStr);
//通過字節數組進行加密
byte[] encryptdata = md5.ComputeHash(palindata);
//將加密后的字節數組轉換成字符串
string returnData = Convert.ToBase64String(encryptdata);
return returnData;
}
/// <summary>
/// Md5密鑰加密
/// </summary>
/// <param name="pToEncrypt">要加密的string字符串</param>
/// <returns></returns>
public static string Md5Encrypt_Key(string pToEncrypt)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
byte[] inputByteArray = Encoding.Default.GetBytes(pToEncrypt);
des.Key = Encoding.ASCII.GetBytes(keys);
des.IV = Encoding.ASCII.GetBytes(keys);
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
StringBuilder ret = new StringBuilder();
foreach (byte b in ms.ToArray())
{
ret.AppendFormat("{0:X2}", b);
}
var s = ret.ToString();
return s;
}
/// <summary>
/// Md5解密
/// </summary>
/// <param name="pToDecrypt">解密string</param>
/// <returns></returns>
public static string Md5Decrypt(string pToDecrypt)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
byte[] inputByteArray = new byte[pToDecrypt.Length / 2];
for (int x = 0; x < pToDecrypt.Length / 2; x++)
{
int i = (Convert.ToInt32(pToDecrypt.Substring(x * 2, 2), 16));
inputByteArray[x] = (byte)i;
}
des.Key = Encoding.ASCII.GetBytes(_appSecret);
des.IV = Encoding.ASCII.GetBytes(_appSecret);
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
return Encoding.Default.GetString(ms.ToArray());
}
/// <summary>
/// MD5流加密
/// </summary>
/// <param name="inputStream">輸入流</param>
/// <returns></returns>
public static string GenerateMD5(Stream inputStream)
{
using (MD5 mi = MD5.Create())
{
//開始加密
byte[] newBuffer = mi.ComputeHash(inputStream);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < newBuffer.Length; i++)
{
sb.Append(newBuffer[i].ToString("x2"));
}
return sb.ToString();
}
}
#endregion
二、Base64加碼解碼
- 嚴格來說,Base64是一種編碼,而不是加密,通常Base64編碼后字符串會用於傳輸數據。不過也正是因為Base64編碼后字符串具有不可讀性;也有人當做加密算法來使用。
#region Base64加碼解碼
/// <summary>
/// Base64編碼,采用utf8編碼
/// </summary>
/// <param name="strPath">待編碼的明文</param>
/// <returns>Base64編碼后的字符串</returns>
public static string Base64Encrypt(string strPath)
{
string returnData;
Encoding encode = Encoding.UTF8;
byte[] bytedata = encode.GetBytes(strPath);
try
{
returnData = Convert.ToBase64String(bytedata, 0, bytedata.Length);
}
catch
{
returnData = strPath;
}
return returnData;
}
/// <summary>
/// Base64解碼,采用utf8編碼方式解碼
/// </summary>
/// <param name="strPath">待解碼的密文</param>
/// <returns>Base64解碼的明文字符串</returns>
public static string Base64DesEncrypt(string strPath)
{
string returnData;
byte[] bpath = Convert.FromBase64String(strPath);
try
{
returnData = Encoding.UTF8.GetString(bpath);
}
catch
{
returnData = strPath;
}
return returnData;
}
#endregion
三、SHA加密解密
- SHA1加密算法與MD5加密類似,都是不可逆的,只是算法不同。
/// <summary>
/// SHA1 加密
/// </summary>
/// <param name="content">需要加密字符串</param>
/// <param name="encode">指定加密編碼</param>
/// <param name="upperOrLower">大小寫格式(大寫:X2;小寫:x2)默認小寫</param>
public static string SHA1Encrypt(string content, Encoding encode, string upperOrLower = "x2")
{
try
{
var buffer = encode.GetBytes(content);//用指定編碼轉為bytes數組
var data = SHA1.Create().ComputeHash(buffer);
var sb = new StringBuilder();
foreach (var t in data)
{
sb.Append(t.ToString(upperOrLower));
}
return sb.ToString();
}
catch (Exception ex)
{
return "SHA1加密出錯:" + ex.Message;
}
}
/// <summary>
/// SHA256加密
/// </summary>
/// <param name="strIN">要加密的string字符串</param>
/// <returns>SHA256加密之后的密文</returns>
public static string SHA256Encrypt(string strIN)
{
byte[] tmpByte;
SHA256 sha256 = new SHA256Managed();
tmpByte = sha256.ComputeHash(GetKeyByteArray(strIN));
StringBuilder rst = new StringBuilder();
for (int i = 0; i < tmpByte.Length; i++)
{
rst.Append(tmpByte[i].ToString("x2"));
}
sha256.Clear();
return rst.ToString();
}
/// <summary>
/// 獲取要加密的string字符串字節數組
/// </summary>
/// <param name="strKey">待加密字符串</param>
/// <returns>加密數組</returns>
private static byte[] GetKeyByteArray(string strKey)
{
UTF8Encoding Asc = new UTF8Encoding();
int tmpStrLen = strKey.Length;
byte[] tmpByte = new byte[tmpStrLen - 1];
tmpByte = Asc.GetBytes(strKey);
return tmpByte;
}
四、HmacSHA256 Base64加密
/// <summary>
/// HmacSHA256 Base64算法,返回的結果始終是32位
/// </summary>
/// <param name="message">待加密的明文字符串</param>
/// <returns>HmacSHA256算法加密之后的密文</returns>
public static string HmacSHA256(string message)
{
byte[] keyByte = Encoding.GetEncoding("utf-8").GetBytes(_appSecret);
byte[] messageBytes = Encoding.GetEncoding("utf-8").GetBytes(message);
using (var hmacsha256 = new HMACSHA256(keyByte))
{
byte[] hashmessage = hmacsha256.ComputeHash(messageBytes);
return Convert.ToBase64String(hashmessage);
}
}
五、DES加密解密
- DES(Data Encryption Standard)是目前最為流行的加密算法之一。DES是對稱的,也就是說它使用同一個密鑰來加密和解密數據。
- DES還是一種分組加密算法,該算法每次處理固定長度的數據段,稱之為分組。
- DES加密算法對密鑰有要求,必須是8個字符,如12345678這樣的。
#region DES加密解密
/// <summary>
/// DES加密操作
/// </summary>
/// <param name="normalTxt">需要加密的明文字符串</param>
/// <returns>返回DES加密的密文字符串</returns>
public static string DesEncrypt(string normalTxt)
{
DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();
int i = cryptoProvider.KeySize;
MemoryStream ms = new MemoryStream();
CryptoStream cst = new CryptoStream(ms, cryptoProvider.CreateEncryptor(_KEY, _IV), CryptoStreamMode.Write);
StreamWriter sw = new StreamWriter(cst);
sw.Write(normalTxt);
sw.Flush();
cst.FlushFinalBlock();
sw.Flush();
string strRet = Convert.ToBase64String(ms.GetBuffer(), 0, (int)ms.Length);
return strRet;
}
/// <summary>
/// DES解密操作
/// </summary>
/// <param name="securityTxt">需要解密的密文字符串</param>
/// <returns>返回DES解密之后的明文字符串</returns>
public static string DesDecrypt(string securityTxt)//解密
{
byte[] byEnc;
try
{
securityTxt.Replace("_%_", "/");
securityTxt.Replace("-%-", "#");
byEnc = Convert.FromBase64String(securityTxt);
}
catch
{
return null;
}
DESCryptoServiceProvider cryptoProvider = new DESCryptoServiceProvider();
MemoryStream ms = new MemoryStream(byEnc);
CryptoStream cst = new CryptoStream(ms, cryptoProvider.CreateDecryptor(_KEY, _IV), CryptoStreamMode.Read);
StreamReader sr = new StreamReader(cst);
return sr.ReadToEnd();
}
#endregion
六、AES加密解密
- 高級加密標准(AES,Advanced Encryption Standard)為最常見的對稱加密算法(微信小程序加密傳輸就是用這個加密算法的)
#region AES加密解密
/// <summary>
/// AES base64 加密算法;Key 為16位
/// </summary>
/// <param name="Data">需要加密的字符串</param>
/// <returns></returns>
public static string RST_AesEncrypt_Base64(string Data)
{
if (string.IsNullOrEmpty(Data))
{
return null;
}
if (string.IsNullOrEmpty(Key))
{
return null;
}
string Vector = Key.Substring(0, 16);
Byte[] plainBytes = Encoding.UTF8.GetBytes(Data);
Byte[] bKey = new Byte[32];
Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)), bKey, bKey.Length);
Byte[] bVector = new Byte[16];
Array.Copy(Encoding.UTF8.GetBytes(Vector.PadRight(bVector.Length)), bVector, bVector.Length);
Byte[] Cryptograph = null; // 加密后的密文
Rijndael Aes = Rijndael.Create();
//add
Aes.Mode = CipherMode.CBC;//兼任其他語言的des
Aes.BlockSize = 128;
Aes.Padding = PaddingMode.PKCS7;
//add end
try
{
// 開辟一塊內存流
using (MemoryStream Memory = new MemoryStream())
{
// 把內存流對象包裝成加密流對象
using (CryptoStream Encryptor = new CryptoStream(Memory,
Aes.CreateEncryptor(bKey, bVector),
CryptoStreamMode.Write))
{
// 明文數據寫入加密流
Encryptor.Write(plainBytes, 0, plainBytes.Length);
Encryptor.FlushFinalBlock();
Cryptograph = Memory.ToArray();
}
}
}
catch
{
Cryptograph = null;
}
return Convert.ToBase64String(Cryptograph);
}
/// <summary>
/// AES base64 解密算法;Key為16位
/// </summary>
/// <param name="Data">需要解密的字符串</param>
/// <param name="Key">Key為16位 密鑰</param>
/// <returns></returns>
public static string RST_AesDecrypt_Base64(string Data)
{
try
{
if (string.IsNullOrEmpty(Data))
{
return null;
}
if (string.IsNullOrEmpty(Key))
{
return null;
}
string Vector = Key.Substring(0, 16);
Byte[] encryptedBytes = Convert.FromBase64String(Data);
Byte[] bKey = new Byte[32];
Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)), bKey, bKey.Length);
Byte[] bVector = new Byte[16];
Array.Copy(Encoding.UTF8.GetBytes(Vector.PadRight(bVector.Length)), bVector, bVector.Length);
Byte[] original = null; // 解密后的明文
Rijndael Aes = Rijndael.Create();
//add
Aes.Mode = CipherMode.CBC;//兼任其他語言的des
Aes.BlockSize = 128;
Aes.Padding = PaddingMode.PKCS7;
//add end
try
{
// 開辟一塊內存流,存儲密文
using (MemoryStream Memory = new MemoryStream(encryptedBytes))
{
//把內存流對象包裝成加密流對象
using (CryptoStream Decryptor = new CryptoStream(Memory,
Aes.CreateDecryptor(bKey, bVector),
CryptoStreamMode.Read))
{
// 明文存儲區
using (MemoryStream originalMemory = new MemoryStream())
{
Byte[] Buffer = new Byte[1024];
Int32 readBytes = 0;
while ((readBytes = Decryptor.Read(Buffer, 0, Buffer.Length)) > 0)
{
originalMemory.Write(Buffer, 0, readBytes);
}
original = originalMemory.ToArray();
}
}
}
}
catch
{
original = null;
}
return Encoding.UTF8.GetString(original);
}
catch { return null; }
}
/// <summary>
/// 密鑰16位或者32位的AES base64加密
/// </summary>
/// <param name="value">需要進行加密的明文字符串</param>
/// <param name="key">16位或者32位的密鑰</param>
/// <param name="iv">16位以上的向量;默認為:"*Gc_Yy_Cq_@_Ztl_99*"</param>
/// <returns>AES加密之后的密文</returns>
public static string AesEncrypt(string value, string key, string iv = "")
{
if (string.IsNullOrEmpty(value)) return string.Empty;
if (string.IsNullOrEmpty(key))
{
key = Key;
}
if (key.Length < 16) throw new Exception("指定的密鑰長度不能少於16位。");
if (key.Length > 32) throw new Exception("指定的密鑰長度不能多於32位。");
if (key.Length != 16 && key.Length != 24 && key.Length != 32) throw new Exception("指定的密鑰長度不明確。");
if (string.IsNullOrEmpty(iv))
{
iv = vector;
}
if (!string.IsNullOrEmpty(iv))
{
if (iv.Length < 16) throw new Exception("指定的向量長度不能少於16位。");
}
var _keyByte = Encoding.UTF8.GetBytes(key);
var _valueByte = Encoding.UTF8.GetBytes(value);
using (var aes = new RijndaelManaged())
{
aes.IV = !string.IsNullOrEmpty(iv) ? Encoding.UTF8.GetBytes(iv) : Encoding.UTF8.GetBytes(key.Substring(0, 16));
aes.Key = _keyByte;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
var cryptoTransform = aes.CreateEncryptor();
var resultArray = cryptoTransform.TransformFinalBlock(_valueByte, 0, _valueByte.Length);
return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}
}
/// <summary>
/// 密鑰16位或者32位的AES base64解密
/// </summary>
/// <param name="value">需要解密的密文</param>
/// <param name="key">16位或者32位的密鑰需和加密時的密鑰保持一致</param>
/// <param name="iv">16位以上的向量需和加密時的向量保持一致;默認為:"*Gc_Yy_Cq_@_Ztl_99*"</param>
/// <returns>AES解密之后的明文</returns>
public static string AesDecrypt(string value, string key, string iv = "")
{
if (string.IsNullOrEmpty(value)) return string.Empty;
if (string.IsNullOrEmpty(key))
{
key = Key;
}
if (key.Length < 16) throw new Exception("指定的密鑰長度不能少於16位。");
if (key.Length > 32) throw new Exception("指定的密鑰長度不能多於32位。");
if (key.Length != 16 && key.Length != 24 && key.Length != 32) throw new Exception("指定的密鑰長度不明確。");
if (string.IsNullOrEmpty(iv))
{
iv = vector;
}
if (!string.IsNullOrEmpty(iv))
{
if (iv.Length < 16) throw new Exception("指定的向量長度不能少於16位。");
}
var _keyByte = Encoding.UTF8.GetBytes(key);
var _valueByte = Convert.FromBase64String(value);
using (var aes = new RijndaelManaged())
{
aes.IV = !string.IsNullOrEmpty(iv) ? Encoding.UTF8.GetBytes(iv) : Encoding.UTF8.GetBytes(key.Substring(0, 16));
aes.Key = _keyByte;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
var cryptoTransform = aes.CreateDecryptor();
var resultArray = cryptoTransform.TransformFinalBlock(_valueByte, 0, _valueByte.Length);
return Encoding.UTF8.GetString(resultArray);
}
}
#endregion
七、RSA加密解密:采用公鑰,私鑰的模式
- RSA加密采用公鑰加密,私鑰解密的模式或者私鑰加密,公鑰解密的模式。Https的數字證書也是使用這種模式加密的。
- 但是RSA加密有個特點,就是他對被加密的字符串有長度限制;待加密的字節數不能超過密鑰的長度值除以8再減去11(即:RSACryptoServiceProvider.KeySize / 8 - 11,而加密后得到密文的字節數,正好是密鑰的長度值除以 8(即:RSACryptoServiceProvider.KeySize / 8)。注:該長度指的是byte[]數組的長度,而不是字符串的長度,簡單來說,就是被加密字符串不能太長。
#region RSA加密解密:采用公鑰,私鑰的模式
#region 私鑰加密,公鑰解密
/// <summary>
/// RSA私鑰加密
/// </summary>
/// <param name="privateKey">Java格式的RSA私鑰 base64格式</param>
/// <param name="contentData">待加密的數據;調用方法Encoding.GetEncoding("UTF-8").GetBytes(contentData)</param>
/// <param name="algorithm">加密算法</param>
/// <returns>RSA私鑰加密之后的密文</returns>
public static string EncryptWithPrivateKey(string privateKey, byte[] contentData, string algorithm = "RSA/ECB/PKCS1Padding")
{
return Convert.ToBase64String(EncryptWithPrivateKey(Convert.FromBase64String(privateKey), contentData, algorithm));
}
private static byte[] Transform(AsymmetricKeyParameter key, byte[] contentData, string algorithm, bool forEncryption)
{
var c = CipherUtilities.GetCipher(algorithm);
c.Init(forEncryption, new ParametersWithRandom(key));
return c.DoFinal(contentData);
}
/// <summary>
/// RSA私鑰加密
/// </summary>
/// <param name="privateKey">Java格式的RSA私鑰</param>
/// <param name="contentData">待加密的數據;調用方法Encoding.GetEncoding("UTF-8").GetBytes(contentData)</param>
/// <param name="algorithm">加密算法</param>
/// <returns>RSA私鑰加密之后的密文</returns>
public static byte[] EncryptWithPrivateKey(byte[] privateKey, byte[] contentData, string algorithm = "RSA/ECB/PKCS1Padding")
{
RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(privateKey);
return Transform(privateKeyParam, contentData, algorithm, true);
}
/// <summary>
/// RSA公鑰解密
/// </summary>
/// <param name="publicKey">Java格式的RSA公鑰 base64格式</param>
/// <param name="content">待解密數據 base64格式</param>
/// <param name="encoding">解密出來的數據編碼格式,默認UTF-8</param>
/// <param name="algorithm">加密算法</param>
/// <returns>RSA私鑰解密之后的明文</returns>
public static string DecryptWithPublicKey(string publicKey, string content, string encoding = "UTF-8", string algorithm = "RSA/ECB/PKCS1Padding")
{
return Encoding.GetEncoding(encoding).GetString(DecryptWithPublicKey(Convert.FromBase64String(publicKey), Convert.FromBase64String(content), algorithm));
}
/// <summary>
/// RSA公鑰解密
/// </summary>
/// <param name="publicKey">Java格式的RSA公鑰</param>
/// <param name="contentData">待解密數據</param>
/// <param name="algorithm">加密算法</param>
/// <returns>RSA私鑰解密之后的明文</returns>
public static byte[] DecryptWithPublicKey(byte[] publicKey, byte[] contentData, string algorithm = "RSA/ECB/PKCS1Padding")
{
RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(publicKey);
return Transform(publicKeyParam, contentData, algorithm, false);
}
#endregion
#region 公鑰加密,私鑰解密
/// <summary>
/// RSA公鑰加密
/// </summary>
/// <param name="xmlPublicKey">加密公鑰;為空則默認系統公鑰</param>
/// <param name="enptStr">需要加密的明文字符串</param>
/// <param name="encoding">編碼格式;默認:UTF-8</param>
/// <returns>RSA公鑰加密的密文</returns>
public static string RSAEncrypt_Public(string xmlPublicKey, string enptStr, string encoding = "UTF-8")
{
if (string.IsNullOrEmpty(xmlPublicKey))
{
xmlPublicKey = _publicKey;
}
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
byte[] cipherbytes;
rsa.FromXmlString(xmlPublicKey);
cipherbytes = rsa.Encrypt(Encoding.GetEncoding(encoding).GetBytes(enptStr), false);
return Convert.ToBase64String(cipherbytes);
}
}
/// <summary>
/// RSA私鑰解密
/// </summary>
/// <param name="xmlPrivateKey">解密私鑰;為空則默認系統公鑰</param>
/// <param name="enptStr">需要加密的明文字符串</param>
/// <param name="encoding">編碼格式;默認:UTF-8</param>
/// <returns>RSA私鑰解密的明文</returns>
public static string RSADecrypt_Private(string xmlPrivateKey, string enptStr, string encoding = "UTF-8")
{
if (string.IsNullOrEmpty(xmlPrivateKey))
{
xmlPrivateKey = _privateKey;
}
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
byte[] cipherbytes;
rsa.FromXmlString(xmlPrivateKey);
cipherbytes = rsa.Decrypt(Convert.FromBase64String(enptStr), false);
return Encoding.GetEncoding(encoding).GetString(cipherbytes);
}
}
#endregion
#region 使用同一容器的名稱進行RSA加密解密
/// <summary>
/// 進行 RSA 加密
/// </summary>
/// <param name="sourceStr">源字符串</param>
/// <returns>加密后字符串</returns>
public static string RsaEncrypt(string sourceStr)
{
Param = new CspParameters();
//密匙容器的名稱,保持加密解密一致才能解密成功
Param.KeyContainerName = "Navis";
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(Param))
{
//將要加密的字符串轉換成字節數組
byte[] plaindata = Encoding.Default.GetBytes(sourceStr);
//通過字節數組進行加密
byte[] encryptdata = rsa.Encrypt(plaindata, false);
//將加密后的字節數組轉換成字符串
return Convert.ToBase64String(encryptdata);
}
}
/// <summary>
/// 通過RSA 加密方式進行解密
/// </summary>
/// <param name="codingStr">加密字符串</param>
/// <returns>解密后字符串</returns>
public static string RsaDesEncrypt(string codingStr)
{
Param = new CspParameters();
Param.KeyContainerName = "Navis";
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(Param))
{
byte[] encryptdata = Convert.FromBase64String(codingStr);
byte[] decryptdata = rsa.Decrypt(encryptdata, false);
return Encoding.Default.GetString(decryptdata);
}
}
#endregion
#region RSA分段加密:待加密的字符串拆開,每段長度都小於等於限制長度,然后分段加密
/// <summary>
/// RSA分段加密
/// </summary>
/// <param name="xmlPublicKey">RSA C#公鑰</param>
/// <param name="enptStr">需要進行RSA加密的長字符串</param>
/// <returns>返回RSA加密后的密文</returns>
public static String SubRSAEncrypt(string xmlPublicKey, string enptStr)
{
RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
provider.FromXmlString(xmlPublicKey);
Byte[] bytes = Encoding.Default.GetBytes(enptStr);
int MaxBlockSize = provider.KeySize / 8 - 11; //加密塊最大長度限制
if (bytes.Length <= MaxBlockSize)
return Convert.ToBase64String(provider.Encrypt(bytes, false));
using (MemoryStream PlaiStream = new MemoryStream(bytes))
using (MemoryStream CrypStream = new MemoryStream())
{
Byte[] Buffer = new Byte[MaxBlockSize];
int BlockSize = PlaiStream.Read(Buffer, 0, MaxBlockSize);
while (BlockSize > 0)
{
Byte[] ToEncrypt = new Byte[BlockSize];
Array.Copy(Buffer, 0, ToEncrypt, 0, BlockSize);
Byte[] Cryptograph = provider.Encrypt(ToEncrypt, false);
CrypStream.Write(Cryptograph, 0, Cryptograph.Length);
BlockSize = PlaiStream.Read(Buffer, 0, MaxBlockSize);
}
return Convert.ToBase64String(CrypStream.ToArray(), Base64FormattingOptions.None);
}
}
/// <summary>
/// RSA分段解密,應對長字符串
/// </summary>
/// <param name="xmlPrivateKey">RSA C#私鑰</param>
/// <param name="enptStr">需要解密的長字符串</param>
/// <returns>返回RSA分段解密的明文</returns>
public static String SubRSADecrypt(string xmlPrivateKey, string enptStr)
{
RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
provider.FromXmlString(xmlPrivateKey);
Byte[] bytes = Convert.FromBase64String(enptStr);
int MaxBlockSize = provider.KeySize / 8; //解密塊最大長度限制
if (bytes.Length <= MaxBlockSize)
return Encoding.Default.GetString(provider.Decrypt(bytes, false));
using (MemoryStream CrypStream = new MemoryStream(bytes))
using (MemoryStream PlaiStream = new MemoryStream())
{
Byte[] Buffer = new Byte[MaxBlockSize];
int BlockSize = CrypStream.Read(Buffer, 0, MaxBlockSize);
while (BlockSize > 0)
{
Byte[] ToDecrypt = new Byte[BlockSize];
Array.Copy(Buffer, 0, ToDecrypt, 0, BlockSize);
Byte[] Plaintext = provider.Decrypt(ToDecrypt, false);
PlaiStream.Write(Plaintext, 0, Plaintext.Length);
BlockSize = CrypStream.Read(Buffer, 0, MaxBlockSize);
}
return Encoding.Default.GetString(PlaiStream.ToArray());
}
}
#endregion
#endregion