在C#中,RSA私钥只能签名,不能加密,如果要加密,要借助BouncyCastle库。

nuget 中引用 Portable.BouncyCastle。

工具类:

RsaEncryptUtil

using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
using System;
using System.Security.Cryptography;
using System.Text; namespace CommonUtils
{
public static class RsaEncryptUtil
{
/// <summary>
/// 私钥加密 .Net平台默认是使用公钥进行加密,私钥进行解密。私钥加密需要自己实现或者使用第三方dll
/// </summary>
/// <param name="data"></param>
/// <param name="key">私钥,格式:PKCS8</param>
/// <returns></returns>
public static byte[] encryptByPrivateKey(String data, String key)
{
String priKey = key.Trim();
String xmlPrivateKey = RSAPrivateKeyJava2DotNet(priKey);
//加载私钥
RSACryptoServiceProvider privateRsa = new RSACryptoServiceProvider();
privateRsa.FromXmlString(xmlPrivateKey);
//转换密钥
AsymmetricCipherKeyPair keyPair = DotNetUtilities.GetKeyPair(privateRsa);
IBufferedCipher c = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");// 参数与Java中加密解密的参数一致
c.Init(true, keyPair.Private); //第一个参数为true表示加密,为false表示解密;第二个参数表示密钥
byte[] DataToEncrypt = Encoding.UTF8.GetBytes(data);
byte[] outBytes = c.DoFinal(DataToEncrypt);//加密
return outBytes; } /// <summary>
/// 私钥加密
/// </summary>
/// <param name="data">明文</param>
/// <param name="key">私钥</param>
/// <param name="keyFormat">私钥格式:PKCS1,PKCS8</param>
/// <returns></returns>
public static byte[] encryptByPrivateKey(String data, String key,string keyFormat)
{
String priKey = key.Trim(); //加载私钥
RSACryptoServiceProvider privateRsa = RsaUtil.LoadPrivateKey(key,keyFormat); //转换密钥
AsymmetricCipherKeyPair keyPair = DotNetUtilities.GetKeyPair(privateRsa);
IBufferedCipher c = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");// 参数与Java中加密解密的参数一致
c.Init(true, keyPair.Private); //第一个参数为true表示加密,为false表示解密;第二个参数表示密钥
byte[] DataToEncrypt = Encoding.UTF8.GetBytes(data);
byte[] outBytes = c.DoFinal(DataToEncrypt);//加密
return outBytes; } /// <summary>
/// RSA私钥格式转换,java->.net
/// </summary>
/// <param name="privateKey"></param>
/// <returns></returns>
private static string RSAPrivateKeyJava2DotNet(string privateKey)
{
RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey)); return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent><P>{2}</P><Q>{3}</Q><DP>{4}</DP><DQ>{5}</DQ><InverseQ>{6}</InverseQ><D>{7}</D></RSAKeyValue>",
Convert.ToBase64String(privateKeyParam.Modulus.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.PublicExponent.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.P.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.Q.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.DP.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.DQ.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.QInv.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.Exponent.ToByteArrayUnsigned()));
} /// <summary>
/// 用公钥解密
/// </summary>
/// <param name="data"></param>
/// <param name="key"></param>
/// <returns></returns>
public static byte[] decryptByPublicKey(String data, String key)
{
String pubKey = key.Trim();
String xmlPublicKey = RSAPublicKeyJava2DotNet(pubKey); RSACryptoServiceProvider publicRsa = new RSACryptoServiceProvider();
publicRsa.FromXmlString(xmlPublicKey); AsymmetricKeyParameter keyPair = DotNetUtilities.GetRsaPublicKey(publicRsa);
//转换密钥
// AsymmetricCipherKeyPair keyPair = DotNetUtilities.GetRsaKeyPair(publicRsa);
IBufferedCipher c = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");// 参数与Java中加密解密的参数一致
c.Init(false, keyPair); //第一个参数为true表示加密,为false表示解密;第二个参数表示密钥
byte[] DataToEncrypt = Convert.FromBase64String(data);
byte[] outBytes = c.DoFinal(DataToEncrypt);//解密
return outBytes;
} /// <summary>
/// RSA公钥格式转换,java->.net
/// </summary>
/// <param name="publicKey"></param>
/// <returns></returns>
private static string RSAPublicKeyJava2DotNet(string publicKey)
{
RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey));
return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>",
Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()),
Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned()));
} }
}

RsaUtil

using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
using System;
using System.IO;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates; namespace CommonUtils
{
public static class RsaUtil
{
#region 加载私钥 /// <summary>
/// 转换私钥字符串为RSACryptoServiceProvider
/// </summary>
/// <param name="privateKeyStr">私钥字符串</param>
/// <param name="keyFormat">PKCS8,PKCS1</param>
/// <param name="signType">RSA 私钥长度1024 ,RSA2 私钥长度2048</param>
/// <returns></returns>
public static RSACryptoServiceProvider LoadPrivateKey(string privateKeyStr, string keyFormat)
{
string signType = "RSA";
if (privateKeyStr.Length > 1024)
{
signType = "RSA2";
}
//PKCS8,PKCS1
if (keyFormat == "PKCS1")
{
return LoadPrivateKeyPKCS1(privateKeyStr, signType);
}
else
{
return LoadPrivateKeyPKCS8(privateKeyStr);
}
} /// <summary>
/// PKCS1 格式私钥转 RSACryptoServiceProvider 对象
/// </summary>
/// <param name="strKey">pcsk1 私钥的文本内容</param>
/// <param name="signType">RSA 私钥长度1024 ,RSA2 私钥长度2048 </param>
/// <returns></returns>
public static RSACryptoServiceProvider LoadPrivateKeyPKCS1(string privateKeyPemPkcs1, string signType)
{
try
{
privateKeyPemPkcs1 = privateKeyPemPkcs1.Replace("-----BEGIN RSA PRIVATE KEY-----", "").Replace("-----END RSA PRIVATE KEY-----", "").Replace("\r", "").Replace("\n", "").Trim();
privateKeyPemPkcs1 = privateKeyPemPkcs1.Replace("-----BEGIN PRIVATE KEY-----", "").Replace("-----END PRIVATE KEY-----", "").Replace("\r", "").Replace("\n", "").Trim(); byte[] data = null;
//读取带 data = Convert.FromBase64String(privateKeyPemPkcs1); RSACryptoServiceProvider rsa = DecodeRSAPrivateKey(data, signType);
return rsa;
}
catch (Exception ex)
{
throw ex;
}
return null;
} private static RSACryptoServiceProvider DecodeRSAPrivateKey(byte[] privkey, string signType)
{
byte[] MODULUS, E, D, P, Q, DP, DQ, IQ; // --------- Set up stream to decode the asn.1 encoded RSA private key ------
MemoryStream mem = new MemoryStream(privkey);
BinaryReader binr = new BinaryReader(mem); //wrap Memory Stream with BinaryReader for easy reading
byte bt = 0;
ushort twobytes = 0;
int elems = 0;
try
{
twobytes = binr.ReadUInt16();
if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
binr.ReadByte(); //advance 1 byte
else if (twobytes == 0x8230)
binr.ReadInt16(); //advance 2 bytes
else
return null; twobytes = binr.ReadUInt16();
if (twobytes != 0x0102) //version number
return null;
bt = binr.ReadByte();
if (bt != 0x00)
return null; //------ all private key components are Integer sequences ----
elems = GetIntegerSize(binr);
MODULUS = binr.ReadBytes(elems); elems = GetIntegerSize(binr);
E = binr.ReadBytes(elems); elems = GetIntegerSize(binr);
D = binr.ReadBytes(elems); elems = GetIntegerSize(binr);
P = binr.ReadBytes(elems); elems = GetIntegerSize(binr);
Q = binr.ReadBytes(elems); elems = GetIntegerSize(binr);
DP = binr.ReadBytes(elems); elems = GetIntegerSize(binr);
DQ = binr.ReadBytes(elems); elems = GetIntegerSize(binr);
IQ = binr.ReadBytes(elems); // ------- create RSACryptoServiceProvider instance and initialize with public key -----
CspParameters CspParameters = new CspParameters();
CspParameters.Flags = CspProviderFlags.UseMachineKeyStore; int bitLen = 1024;
if ("RSA2".Equals(signType))
{
bitLen = 2048;
} RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(bitLen, CspParameters);
//RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(); RSAParameters RSAparams = new RSAParameters();
RSAparams.Modulus = MODULUS;
RSAparams.Exponent = E;
RSAparams.D = D;
RSAparams.P = P;
RSAparams.Q = Q;
RSAparams.DP = DP;
RSAparams.DQ = DQ;
RSAparams.InverseQ = IQ;
RSA.ImportParameters(RSAparams);
return RSA;
}
catch (Exception ex)
{
throw ex;
// return null;
}
finally
{
binr.Close();
}
} private static int GetIntegerSize(BinaryReader binr)
{
byte bt = 0;
byte lowbyte = 0x00;
byte highbyte = 0x00;
int count = 0;
bt = binr.ReadByte();
if (bt != 0x02) //expect integer
return 0;
bt = binr.ReadByte(); if (bt == 0x81)
count = binr.ReadByte(); // data size in next byte
else
if (bt == 0x82)
{
highbyte = binr.ReadByte(); // data size in next 2 bytes
lowbyte = binr.ReadByte();
byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
count = BitConverter.ToInt32(modint, 0);
}
else
{
count = bt; // we already have the data size
} while (binr.ReadByte() == 0x00)
{ //remove high order zeros in data
count -= 1;
}
binr.BaseStream.Seek(-1, SeekOrigin.Current); //last ReadByte wasn't a removed zero, so back up a byte
return count;
} /// <summary>
/// PKCS8 文本转RSACryptoServiceProvider 对象
/// </summary>
/// <param name="privateKeyPemPkcs8"></param>
/// <returns></returns>
public static RSACryptoServiceProvider LoadPrivateKeyPKCS8(string privateKeyPemPkcs8)
{ try
{
//PKCS8是“BEGIN PRIVATE KEY”
privateKeyPemPkcs8 = privateKeyPemPkcs8.Replace("-----BEGIN RSA PRIVATE KEY-----", "").Replace("-----END RSA PRIVATE KEY-----", "").Replace("\r", "").Replace("\n", "").Trim();
privateKeyPemPkcs8 = privateKeyPemPkcs8.Replace("-----BEGIN PRIVATE KEY-----", "").Replace("-----END PRIVATE KEY-----", "").Replace("\r", "").Replace("\n", "").Trim(); //pkcs8 文本先转为 .NET XML 私钥字符串
string privateKeyXml = RSAPrivateKeyJava2DotNet(privateKeyPemPkcs8); RSACryptoServiceProvider publicRsa = new RSACryptoServiceProvider();
publicRsa.FromXmlString(privateKeyXml);
return publicRsa;
}
catch (Exception ex)
{
throw ex;
}
} /// <summary>
/// PKCS8 私钥文本 转 .NET XML 私钥文本
/// </summary>
/// <param name="privateKeyPemPkcs8"></param>
/// <returns></returns>
public static string RSAPrivateKeyJava2DotNet(string privateKeyPemPkcs8)
{
RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKeyPemPkcs8));
return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent><P>{2}</P><Q>{3}</Q><DP>{4}</DP><DQ>{5}</DQ><InverseQ>{6}</InverseQ><D>{7}</D></RSAKeyValue>",
Convert.ToBase64String(privateKeyParam.Modulus.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.PublicExponent.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.P.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.Q.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.DP.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.DQ.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.QInv.ToByteArrayUnsigned()),
Convert.ToBase64String(privateKeyParam.Exponent.ToByteArrayUnsigned()));
} #endregion /// <summary>
/// 加载公钥证书
/// </summary>
/// <param name="publicKeyCert">公钥证书文本内容</param>
/// <returns></returns>
public static RSACryptoServiceProvider LoadPublicCert(string publicKeyCert)
{ publicKeyCert = publicKeyCert.Replace("-----BEGIN CERTIFICATE-----", "").Replace("-----END CERTIFICATE-----", "").Replace("\r", "").Replace("\n", "").Trim(); byte[] bytesCerContent = Convert.FromBase64String(publicKeyCert);
X509Certificate2 x509 = new X509Certificate2(bytesCerContent);
RSACryptoServiceProvider rsaPub = (RSACryptoServiceProvider)x509.PublicKey.Key;
return rsaPub; } /// <summary>
/// pem 公钥文本 转 .NET RSACryptoServiceProvider。
/// </summary>
/// <param name="publicKeyPem"></param>
/// <returns></returns>
public static RSACryptoServiceProvider LoadPublicKey(string publicKeyPem)
{ publicKeyPem = publicKeyPem.Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", "").Replace("\r", "").Replace("\n", "").Trim(); //pem 公钥文本 转 .NET XML 公钥文本。
string publicKeyXml = RSAPublicKeyJava2DotNet(publicKeyPem); RSACryptoServiceProvider publicRsa = new RSACryptoServiceProvider();
publicRsa.FromXmlString(publicKeyXml);
return publicRsa; } /// <summary>
/// pem 公钥文本 转 .NET XML 公钥文本。
/// </summary>
/// <param name="publicKey"></param>
/// <returns></returns>
private static string RSAPublicKeyJava2DotNet(string publicKey)
{
RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey));
return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>",
Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()),
Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned()));
} }
}

使用:

这个方法只能加密 私钥长度/8 -11 个字符,分段加密的代码要自己处理了。

私钥加密:

private void btnPrivateKeyEncrypt_Click(object sender, EventArgs e)
{
try
{
//byte[] rst = RsaEncryptUtil.encryptByPrivateKey(txtMingWen.Text, txtPrivateKey.Text);
byte[] rst = RsaEncryptUtil.encryptByPrivateKey(txtMingWen.Text, txtPrivateKey.Text,cbxPrivateKeyFormat.Text); //加密后一般转Base64String ,Base64FormattingOptions.InsertLineBreaks.
string base64str = Convert.ToBase64String(rst, Base64FormattingOptions.InsertLineBreaks); txtJiaMiHou.Text = base64str;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}

公钥解密:

private void btnPubKeyDecrypt_Click(object sender, EventArgs e)
{
try
{
byte[] rst = RsaEncryptUtil.decryptByPublicKey(txtJiaMiHou.Text, txtPubKey.Text); string strRst = Encoding.UTF8.GetString(rst);
txtJieMiHou.Text = strRst;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}

-

C#.NET Rsa私钥加密公钥解密的更多相关文章

  1. 求求你们不要再用 RSA 私钥加密公钥解密了,这非常不安全!

    最近经常在网上看到有人说巨硬的 CNG(Cryptography Next Generation 即下一代加密技术) 只提供 RSA 公钥加密私钥解密,没有提供 RSA 私钥加密公钥解密,他们要自己封 ...

  2. 银联手机支付(.Net Csharp),3DES加密解密,RSA加密解密,RSA私钥加密公钥解密,.Net RSA 3DES C#

    前段时间做的银联支付,折腾了好久,拼凑的一些代码,有需要的朋友可以参考,本人.Net新手,不保证准确性! 这个银联手机支付没有SDK提供,技术支持也没有.Net的,真心不好搞! RSA加解密,这里有个 ...

  3. RSA私钥加密公钥解密、各种密钥格式转换

    此随笔解决RSA加解密相关的3个问题,详情可以查看源码. 1.公钥加密.私钥解密2.各种格式RSA密钥之间的转换3.不限制加密原文的长度

  4. 基于私钥加密公钥解密的RSA算法C#实现

    RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作. RSA是被研究得最广泛的公钥算法,从提出到现在已近二十年,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一 ...

  5. RSA不对称加密,公钥加密私钥解密,私钥加密公钥解密

    RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作. RSA是被研究得最广泛的公钥算法,从提出到现在已近二十年,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一 ...

  6. RSA 加密算法 Java 公钥加密私钥解密 和 私钥加密公钥解密 的特点

    package com.smt.cipher.unsymmetry; import org.apache.commons.codec.binary.Base64; import org.apache. ...

  7. golang 私钥"加密"公钥"解密"

    ---恢复内容开始---   之前工作主要使用C/C++与银行/第三方支付对接,但C/C++无法满足客户"当天给协议明天实盘上载"的开发速度以及现公司一些特殊情况,所以决定用go来 ...

  8. NetCore 生成RSA公私钥对,公钥加密私钥解密,私钥加密公钥解密

    using Newtonsoft.Json; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Encodings; using ...

  9. RSA加解密 私钥加密公钥解密 私加公解 && C++ 调用openssl库 的代码实例

    前提:秘钥长度=1024 ============================================== 对一片(117字节)明文加密  私加 ===================== ...

  10. C# 基于大整数类的RSA算法实现(公钥加密私钥解密,私钥加密公钥解密)

    但是C#自带的RSA算法类RSACryptoServiceProvider只支持公钥加密私钥解密,即数字证书的使用. 所以参考了一些网上的资料写了一个RSA的算法实现.算法实现是基于网上提供的一个大整 ...

随机推荐

  1. 力扣224(java)-基本计算器(困难)

    题目: 给你一个字符串表达式 s ,请你实现一个基本计算器来计算并返回它的值. 注意:不允许使用任何将字符串作为数学表达式计算的内置函数,比如 eval() . 示例 1: 输入:s = " ...

  2. Apsara Stack 技术百科 | 数字化业务系统安全工程

    ​简介:数字化平台已经与我们生活紧密结合,其用户规模庞大,一旦系统出现故障,势必会造成一定生活的不便.比如疫情时代,健康码已经成为人们出门必备的条件,一旦提供健康码服务平台出现故障,出行将变得寸步难行 ...

  3. Spring Boot Serverless 实战 | Serverless 应用的监控与调试

    ​简介:Spring Boot 是基于 Java Spring 框架的套件,它预装了 Spring 的一系列组件,让开发者只需要很少的配置就可以创建独立运行的应用程序.在云原生的环境中,有大量的平台可 ...

  4. OpenKruise v1.0:云原生应用自动化达到新的高峰

    ​简介:OpenKruise 是针对 Kubernetes 的增强能力套件,聚焦于云原生应用的部署.升级.运维.稳定性防护等领域. 云原生应用自动化管理套件.CNCF Sandbox 项目 -- Op ...

  5. Serverless Devs 的官网是如何通过 Serverless Devs 部署的

    简介: 只有自己吃自己的狗粮,自己做的东西才不"".Serverless Devs 自发展之处到现在,已经经历了几个月的时间,在这几个月,Serverless Devs 的成长是迅 ...

  6. 探究 Java 应用的启动速度优化

    简介: Java 的执行效率非常高,约为最快的C语言的一半.这在主流的编程语言中,仅次于C.Rust 和 C++.但在高性能的背后,Java 的启动性能差也令人印象深刻,大家印象中的 Java 笨重缓 ...

  7. [FAQ] Win10 WSL Ubuntu 根目录实际位置

    1. 运行(win+R),直接输入 \\wsl$ 进入Ubuntu的目录. 2. 或者文件夹里同样输入  \\wsl$ 进行查找. Refer:Win10 WSL 路径 Link:https://ww ...

  8. 11.Node节点维护

    题目:Node节点维护 配置环境kubectl config use-context ek8s 将名为ek8s-node-0的node节点设置为不可用,并重新调度该node上所有运行的pods. 官方 ...

  9. .NET Aspire 预览版 6 发布

    .NET Aspire 预览版 6 引入了一系列重大更新,主要包括 API 的重大更改.安全性和可靠性的提升.新的资源和组件.应用程序主机的更新.测试支持.模板更新.组件更新.Azure 配置包的更新 ...

  10. LVGL 日志

    一.启动日志 在 lv_conf.h 中将 LV_USE_LOG 设置为 1,如下图所示: 二.日志级别 在文件 lvgl/src/misc/lv_log.h 中定义了日志等级,等级是从小到大,所以 ...