C#有自己的一套生成密钥、加解密的库,但是跟其他文互通比较费劲,经过一翻比较后,笔者选择了BouncyCastle这套库,而这套库的缺点是文档很少,只能参考Java的代码才把需求的功能实现。笔者下面提供的代码是经过多语言环境验证,可以与其他语言互通。
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace lhtzbj12.Encryption
{
///
/// Des对称加密工具类
///
public class DesHelper
{
///
/// 加密
///
/// 待加密的数据
/// 加/解密key 8位
/// 偏移向量 8位
/// 密码模式
/// 填充方式
///
public static string Encrypt(string data, string key, string iv, CipherMode model = CipherMode.CBC, PaddingMode padding = PaddingMode.PKCS7)
{
byte[] _KeyByte = null;
if (!string.IsNullOrWhiteSpace(key))
{
_KeyByte = Encoding.UTF8.GetBytes(key);
}
byte[] _IVByte = null;
if (!string.IsNullOrWhiteSpace(iv))
{
_IVByte = Encoding.UTF8.GetBytes(iv);
}
var sa = new DESCryptoServiceProvider();
sa.Mode = model;
sa.Padding = padding;
var ct = sa.CreateEncryptor(_KeyByte, _IVByte);
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, ct, CryptoStreamMode.Write);
byte[] byt = Encoding.UTF8.GetBytes(data);
cs.Write(byt, 0, byt.Length);
cs.FlushFinalBlock();
cs.Close();
return Convert.ToBase64String(ms.ToArray());
}
///
/// 解密
///
/// 加密生成的Base64密文
/// 加/解密key 8位
/// 偏移向量 8位
/// 密码模式
/// 填充方式
///
public static string Decrypt(string encData, string key, string iv, CipherMode model = CipherMode.CBC, PaddingMode padding = PaddingMode.PKCS7)
{
byte[] _KeyByte = null;
if (!string.IsNullOrWhiteSpace(key))
{
_KeyByte = Encoding.UTF8.GetBytes(key);
}
byte[] _IVByte = null;
if (!string.IsNullOrWhiteSpace(iv))
{
_IVByte = Encoding.UTF8.GetBytes(iv);
}
using (ICryptoTransform ct = new DESCryptoServiceProvider()
{ Mode = CipherMode.CBC, Padding = PaddingMode.PKCS7 }.CreateDecryptor(_KeyByte, _IVByte))
{
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, ct, CryptoStreamMode.Write))
{
byte[] byt = Convert.FromBase64String(encData);
try
{
cs.Write(byt, 0, byt.Length);
cs.FlushFinalBlock();
cs.Close();
}
catch (Exception)
{
return string.Empty;
}
}
return Encoding.UTF8.GetString(ms.ToArray());
}
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;
using System.IO;
using System.Text.RegularExpressions;
namespace lhtzbj12.Encryption
{
///
/// Rsa密钥对生成工具
///
public class RsaKeyHelper
{
public static void GenKey(out string publicKey, out string privateKey, out string privateKeyPk8)
{
publicKey = string.Empty;
privateKey = string.Empty;
privateKeyPk8 = string.Empty;
try
{
//RSA密钥对的构造器
RsaKeyPairGenerator r = new RsaKeyPairGenerator();
//RSA密钥构造器的参数
RsaKeyGenerationParameters param = new RsaKeyGenerationParameters(
Org.BouncyCastle.Math.BigInteger.ValueOf(3),
new SecureRandom(),
1024, //密钥长度
25);
r.Init(param);
AsymmetricCipherKeyPair keyPair = r.GenerateKeyPair();
//获取公钥和密钥
AsymmetricKeyParameter private_key = keyPair.Private;
AsymmetricKeyParameter public_key = keyPair.Public;
if (((RsaKeyParameters)public_key).Modulus.BitLength < 1024)
{
Console.WriteLine("failed key generation (1024) length test");
}
using (TextWriter textWriter = new StringWriter())
{
PemWriter pemWriter = new PemWriter(textWriter);
pemWriter.WriteObject(keyPair.Private);
pemWriter.Writer.Flush();
privateKey = textWriter.ToString();
}
using (TextWriter textpubWriter = new StringWriter())
{
PemWriter pempubWriter = new PemWriter(textpubWriter);
pempubWriter.WriteObject(keyPair.Public);
pempubWriter.Writer.Flush();
publicKey = textpubWriter.ToString();
}
//keyPair = ReadPem(privateKey); // 直接读取字符串生成密码钥
//public_key = keyPair.Public;//公钥
//private_key = keyPair.Private;//私钥
// 前面私钥为pkcs1格式,经过下面处理后,变成pkcs8格式
SubjectPublicKeyInfo subjectPublicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(public_key);
PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(private_key);
Asn1Object asn1ObjectPublic = subjectPublicKeyInfo.ToAsn1Object();
byte[] publicInfoByte = asn1ObjectPublic.GetEncoded();
Asn1Object asn1ObjectPrivate = privateKeyInfo.ToAsn1Object();
byte[] privateInfoByte = asn1ObjectPrivate.GetEncoded();
var pubkeyb64 = Convert.ToBase64String(publicInfoByte);
// 这里生成的是Pkcs8的密钥
privateKeyPk8 = PrivateKeyPk8Format(Convert.ToBase64String(privateInfoByte));
privateKey = PrivateKeyFormat(privateKey);
publicKey = PublicKeyFormat(publicKey);
}
catch (Exception ex) {
throw ex;
}
}
///
/// 加载Pkcs8格式的私钥
///
///
///
public static AsymmetricKeyParameter loadPrivateKeyPk8(string privateKey)
{
try
{
privateKey = KeyClear(privateKey);
byte[] prikey = Convert.FromBase64String(privateKey);
Asn1Object priKeyObj = Asn1Object.FromByteArray(prikey);//这里也可以从流中读取,从本地导入
AsymmetricKeyParameter priKey = PrivateKeyFactory.CreateKey(PrivateKeyInfo.GetInstance(priKeyObj));
return priKey;
}
catch (Exception)
{
throw new Exception("密钥格式不正确");
}
}
///
/// 加载Pkcs1格式的私钥
///
///
///
public static AsymmetricKeyParameter loadPrivateKeyPk1(string privateKey)
{
AsymmetricCipherKeyPair keyPair = null;
try
{
keyPair = ReadPem(privateKey); // 直接读取字符串生成密码钥
}
catch (Exception)
{
throw new Exception("密钥格式不正确");
}
try
{
AsymmetricKeyParameter private_key = keyPair.Private;
// 前面私钥为pkcs1格式,经过下面处理后,变成pkcs8格式
PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(private_key);
Asn1Object asn1ObjectPrivate = privateKeyInfo.ToAsn1Object();
AsymmetricKeyParameter priKey = PrivateKeyFactory.CreateKey(PrivateKeyInfo.GetInstance(asn1ObjectPrivate));
return priKey;
}
catch (Exception)
{
throw new Exception("加载失败");
}
}
///
/// 加载公钥
///
///
///
public static AsymmetricKeyParameter loadPublicKey(string publicKey)
{
try
{
publicKey = KeyClear(publicKey);
byte[] pubkey = Convert.FromBase64String(publicKey);
Asn1Object pubKeyObj = Asn1Object.FromByteArray(pubkey);//这里也可以从流中读取,从本地导入
AsymmetricKeyParameter pubKey = PublicKeyFactory.CreateKey(SubjectPublicKeyInfo.GetInstance(pubKeyObj));
return pubKey;
}
catch (Exception)
{
throw new Exception("密钥格式不正确");
}
}
///
/// 将Pkcs1格式的私转成Pkcs8格式
///
///
///
public static string ConvertPriPk1ToPk8(string privateKey)
{
AsymmetricCipherKeyPair keyPair = null;
try
{
keyPair = ReadPem(privateKey); // 直接读取字符串生成密码钥
}
catch (Exception)
{
throw new Exception("密钥格式不正确");
}
try
{
AsymmetricKeyParameter private_key = keyPair.Private;
AsymmetricKeyParameter public_key = keyPair.Public;
// 前面私钥为pkcs1格式,经过下面处理后,变成pkcs8格式
SubjectPublicKeyInfo subjectPublicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(public_key);
PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(private_key);
Asn1Object asn1ObjectPublic = subjectPublicKeyInfo.ToAsn1Object();
byte[] publicInfoByte = asn1ObjectPublic.GetEncoded();
Asn1Object asn1ObjectPrivate = privateKeyInfo.ToAsn1Object();
byte[] privateInfoByte = asn1ObjectPrivate.GetEncoded();
var pubkeyb64 = Convert.ToBase64String(publicInfoByte);
// 这里生成的是Pkcs8的密钥
return PrivateKeyFormat(Convert.ToBase64String(privateInfoByte));
}
catch (Exception)
{
throw new Exception("转换失败");
}
}
public static string KeyClear(string key)
{
key = Regex.Replace(key, @"(-----BEGIN PRIVATE KEY-----)|(-----END PRIVATE KEY-----)|(-----BEGIN RSA PRIVATE KEY-----)|(-----END RSA PRIVATE KEY-----)|(-----BEGIN PUBLIC KEY-----)|(-----END PUBLIC KEY-----)|(-----BEGIN RSA PUBLIC KEY-----)|(-----END RSA PUBLIC KEY-----)|\n|\r", "");
return key;
}
private static string PrivateKeyFormat(string privateKey)
{
privateKey = KeyClear(privateKey);
privateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" + privateKey + "\r\n-----END RSA PRIVATE KEY-----";
return privateKey;
}
private static string PrivateKeyPk8Format(string privateKey)
{
privateKey = KeyClear(privateKey);
privateKey = "-----BEGIN PRIVATE KEY-----\r\n" + privateKey + "\r\n-----END PRIVATE KEY-----";
return privateKey;
}
private static string PublicKeyFormat(string publicKey)
{
publicKey = KeyClear(publicKey);
publicKey = "-----BEGIN PUBLIC KEY-----\r\n" + publicKey + "\r\n-----END PUBLIC KEY-----";
return publicKey;
}
static AsymmetricCipherKeyPair ReadPem(string pem)
{
using (TextReader reader = new StringReader(pem))
{
var obj = new Org.BouncyCastle.OpenSsl.PemReader(reader).ReadObject();
return obj as AsymmetricCipherKeyPair;
}
}
}
}
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace lhtzbj12.Encryption
{
///
/// Rsa非对称加密工具类
///
public class RsaBCHelper
{
///
/// 签名
///
/// 待签名字符串
/// 私钥
/// 签名后字符串
public static string Sign(string content, string privateKey)
{
AsymmetricKeyParameter priKey = RsaKeyHelper.loadPrivateKeyPk1(privateKey);
ISigner sig = SignerUtilities.GetSigner("SHA256withRSA"); //其他算法 如SHA1withRSA
sig.Init(true, priKey);
var bytes = Encoding.UTF8.GetBytes(content);
sig.BlockUpdate(bytes, 0, bytes.Length);
byte[] signature = sig.GenerateSignature();
var signedString = Convert.ToBase64String(signature);
return signedString;
}
///
/// 验签
///
/// 待验签字符串
/// 签名
/// 公钥
/// true(通过),false(不通过)
public static bool Verify(string content, string signedString, string publicKey)
{
AsymmetricKeyParameter pubKey = RsaKeyHelper.loadPublicKey(publicKey);
ISigner signer = SignerUtilities.GetSigner("SHA256withRSA"); //其他算法 如SHA1withRSA
signer.Init(false, pubKey);
var expectedSig = Convert.FromBase64String(signedString);
var msgBytes = Encoding.UTF8.GetBytes(content);
signer.BlockUpdate(msgBytes, 0, msgBytes.Length);
return signer.VerifySignature(expectedSig);
}
///
/// 公钥加密
///
/// 需要加密的字符串
/// 公钥
/// 明文
public static string Encrypt(string resData, string publicKey)
{
try
{
AsymmetricKeyParameter pubKey = RsaKeyHelper.loadPublicKey(publicKey);
IBufferedCipher cipher = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");
cipher.Init(true, pubKey);//true表示加密
var data = Encoding.UTF8.GetBytes(resData.Trim());
byte[] encryptData = cipher.DoFinal(data);
return Convert.ToBase64String(encryptData);
}
catch (Exception)
{
throw new Exception("加密失败");
}
}
///
/// 私钥解密
///
/// 加密字符串
/// 私钥
/// 编码格式
/// 明文
public static string Decrypt(string resData, string privateKey)
{
try
{
AsymmetricKeyParameter priKey = RsaKeyHelper.loadPrivateKeyPk1(privateKey);
IBufferedCipher cipher = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");
cipher.Init(false, priKey);//false表示解密
var encryptData = Convert.FromBase64String(resData);
var decryptData = cipher.DoFinal(encryptData);
return Encoding.UTF8.GetString(decryptData);
}
catch (Exception) {
throw new Exception("解密失败");
}
}
///
/// 私钥加密
///
/// 需要加密的字符串
/// 私钥
/// 明文
public static string EncryptByPrivateKey(string resData, string privateKey)
{
try
{
AsymmetricKeyParameter priKey = RsaKeyHelper.loadPrivateKeyPk1(privateKey);
IBufferedCipher cipher = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");
cipher.Init(true, priKey);//true表示加密
var data = Encoding.UTF8.GetBytes(resData.Trim());
byte[] encryptData = cipher.DoFinal(data);
return Convert.ToBase64String(encryptData);
}
catch (Exception)
{
throw new Exception("加密失败");
}
}
///
/// 公钥解密
///
/// 加密字符串
/// 公钥
/// 明文
public static string DecryptByPublicKey(string resData, string publicKey)
{
try
{
AsymmetricKeyParameter pubKey = RsaKeyHelper.loadPublicKey(publicKey);
IBufferedCipher cipher = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");
cipher.Init(false, pubKey);//false表示解密
var encryptData = Convert.FromBase64String(resData);
var decryptData = cipher.DoFinal(encryptData);
return Encoding.UTF8.GetString(decryptData);
}
catch (Exception)
{
throw new Exception("解密失败");
}
}
}
}
https://github.com/lhtzbj12/csharp_encryption