C# .NET CORE .NET6 RSA 公钥加密 私钥解密
环境说明:
.NET CORE 版本:.NET 6 。
.NET CORE 对于RSA的支持:
1. .NET 6 中内置了对 PKCS1,PKCS8 2种私钥格式的支持。
2. 如果你要部署在Linux,docker ,k8s 中;一定要用 “RSA”这个类,不能是 .NET FRAMEWORK 的 RSACryptoServiceProvider。
3. .NET 中默认加密算法为“RSA/ECB/PKCS1Padding” ,要和JAVA互通,JAVA 那边也得是 RSA/ECB/PKCS1Padding 。
加密解析:
//假设私钥长度为1024, 1024/8-11=117。
//如果明文的长度小于117,直接全加密,然后转base64。(data.Length <= maxBlockSize)
//如果明文长度大于117,则每117分一段加密,写入到另一个Stream中,最后转base64。while (blockSize > 0)
如果要和其它语言互通,这个分段长度需要和其它语言约定好,不一是 私钥长度/8-11。
解密解析:
//假设私钥长度为1024, 1024/8 =128。
//如果明文的长度小于 128,直接全解密。(data.Length <= maxBlockSize)
//如果明文长度大于 128,则每 128 分一段解密,写入到另一个Stream中,最后 GetString。while (blockSize > 0)
用“支付宝开放平台开发助手”生成一组公私钥:
PKCS8私钥:
MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBAMz0Czg6QUtTISa2pUkloeQB/TEpHdqrfyroWpKLW9B/LWFSOGH9nyTk1pPZaeadyEZQ6gay/C0pUAetLraq9bMA/Luxq68b87uG7WX7dKytEO2/87qGpGMRs97H+GlkzWil2QO2KK4cHnAcVicPsmi5aZ72U0BWJFyPhtd+qdmrAgMBAAECgYEAvW67iAbgHt0BASVD9C3iSjpEaVHVlC165o/IVzaTcEx8Bz3Ve0zN8W3JnvIO3ebsG4HiLLr2Nk++9rltOc0eNeGMv7F1e/OFot1wN0ON6s1g4bYh1z5Uz8FcYiMWcqHHICrx+oSFeK9x+I2Zge7enQXcsVnqEhm77ZE5YczSryECQQD9nB58e5efYchF+cYbmURioX18cUMuhQbB9Aq2N55cd689Lg35KZqT8JQTp/8tQSdCJG8d2nU8VKspUKTEAuaDAkEAzuKIIoc9PVJvy90LhIPA9c1S8BPCI7EMCaTZqJ5o3VaR2dqvUZDGX7kL3kYkQ+n7mq3KIECvkEFzA+FOP96XuQJBAJQTKHW0T/YeSKoayUHp/lS8R6F2HCy4PRbXn71+wfbpZqcJEd2OHhQM3tiPOV258esbjMlYeSUNppZL4LgVnXMCQQC7Lvs9Ql+GPDAqo7ToEM1lmICR906QPIBHuX+1sJ3wpYMROWumwPa7ZRH36j6ls+6R5OwcgmpWeuE1gYTrBNsBAkEAn2pEtAljX1foQff6CLozYg/J6J9RmVFcJ6qz0LX3052qNFBQYw8CMHB7VkVNzsDIDC8LX5uP2pzTrdPLew+pPA==
与之匹配的 PKCS1 私钥,用助手转换的:
MIICXwIBAAKBgQDM9As4OkFLUyEmtqVJJaHkAf0xKR3aq38q6FqSi1vQfy1hUjhh/Z8k5NaT2WnmnchGUOoGsvwtKVAHrS62qvWzAPy7sauvG/O7hu1l+3SsrRDtv/O6hqRjEbPex/hpZM1opdkDtiiuHB5wHFYnD7JouWme9lNAViRcj4bXfqnZqwIDAQABAoGBAL1uu4gG4B7dAQElQ/Qt4ko6RGlR1ZQteuaPyFc2k3BMfAc91XtMzfFtyZ7yDt3m7BuB4iy69jZPvva5bTnNHjXhjL+xdXvzhaLdcDdDjerNYOG2Idc+VM/BXGIjFnKhxyAq8fqEhXivcfiNmYHu3p0F3LFZ6hIZu+2ROWHM0q8hAkEA/ZwefHuXn2HIRfnGG5lEYqF9fHFDLoUGwfQKtjeeXHevPS4N+Smak/CUE6f/LUEnQiRvHdp1PFSrKVCkxALmgwJBAM7iiCKHPT1Sb8vdC4SDwPXNUvATwiOxDAmk2aieaN1Wkdnar1GQxl+5C95GJEPp+5qtyiBAr5BBcwPhTj/el7kCQQCUEyh1tE/2HkiqGslB6f5UvEehdhwsuD0W15+9fsH26WanCRHdjh4UDN7YjzldufHrG4zJWHklDaaWS+C4FZ1zAkEAuy77PUJfhjwwKqO06BDNZZiAkfdOkDyAR7l/tbCd8KWDETlrpsD2u2UR9+o+pbPukeTsHIJqVnrhNYGE6wTbAQJBAJ9qRLQJY19X6EH3+gi6M2IPyeifUZlRXCeqs9C199OdqjRQUGMPAjBwe1ZFTc7AyAwvC1+bj9qc063Ty3sPqTw=
与之匹配的公钥:
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDM9As4OkFLUyEmtqVJJaHkAf0xKR3aq38q6FqSi1vQfy1hUjhh/Z8k5NaT2WnmnchGUOoGsvwtKVAHrS62qvWzAPy7sauvG/O7hu1l+3SsrRDtv/O6hqRjEbPex/hpZM1opdkDtiiuHB5wHFYnD7JouWme9lNAViRcj4bXfqnZqwIDAQAB
加密工具类:
RsaEncryptUtil
using System.Security.Cryptography;
using System.Text; namespace CommonUtils
{
public static class RsaEncryptUtil
{
#region 标准的-公钥加密-私钥解密 /** 默认编码字符集 */
private static string DEFAULT_CHARSET = "UTF-8"; /// <summary>
/// 公钥加密(超过 私钥长度 / 8 - 11,分段加密)
/// </summary>
/// <param name="content">明文</param>
/// <param name="charset">编码</param>
/// <param name="publicKeyPem">公钥</param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static string RSAEncrypt(string content, string charset, string publicKeyPem)
{
try
{
//假设私钥长度为1024, 1024/8-11=117。
//如果明文的长度小于117,直接全加密,然后转base64。(data.Length <= maxBlockSize)
//如果明文长度大于117,则每117分一段加密,写入到另一个Stream中,最后转base64。while (blockSize > 0) //转为纯字符串,不带格式
publicKeyPem = publicKeyPem.Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", "").Replace("\r", "").Replace("\n", "").Trim(); RSA rsa = RSA.Create();
rsa.ImportSubjectPublicKeyInfo(Convert.FromBase64String(publicKeyPem), out _); if (string.IsNullOrEmpty(charset))
{
charset = DEFAULT_CHARSET;
}
byte[] data = Encoding.GetEncoding(charset).GetBytes(content);
int maxBlockSize = rsa.KeySize / 8 - 11; //加密块最大长度限制
if (data.Length <= maxBlockSize)
{
byte[] cipherbytes = rsa.Encrypt(data, RSAEncryptionPadding.Pkcs1);
return Convert.ToBase64String(cipherbytes);
}
MemoryStream plaiStream = new MemoryStream(data);
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 = rsa.Encrypt(toEncrypt, RSAEncryptionPadding.Pkcs1);
crypStream.Write(cryptograph, 0, cryptograph.Length);
blockSize = plaiStream.Read(buffer, 0, maxBlockSize);
} return Convert.ToBase64String(crypStream.ToArray(), Base64FormattingOptions.None);
}
catch (Exception ex)
{
throw new Exception("EncryptContent = " + content + ",charset = " + charset, ex);
}
} /// <summary>
/// 私钥解密(超过 私钥长度 / 8 - 11,分段加密)
/// </summary>
/// <param name="content">密文</param>
/// <param name="charset">编码</param>
/// <param name="privateKeyPem">私钥</param>
/// <param name="keyFormat">私钥格式 PKCS1,PKCS8</param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public static string RSADecrypt(string content, string charset, string privateKeyPem, string keyFormat)
{
try
{
//假设私钥长度为1024, 1024/8 =128。
//如果明文的长度小于 128,直接全解密。(data.Length <= maxBlockSize)
//如果明文长度大于 128,则每 128 分一段解密,写入到另一个Stream中,最后 GetString。while (blockSize > 0) //转为纯字符串,不带格式
privateKeyPem = privateKeyPem.Replace("-----BEGIN RSA PRIVATE KEY-----", "").Replace("-----END RSA PRIVATE KEY-----", "").Replace("\r", "").Replace("\n", "").Trim();
privateKeyPem = privateKeyPem.Replace("-----BEGIN PRIVATE KEY-----", "").Replace("-----END PRIVATE KEY-----", "").Replace("\r", "").Replace("\n", "").Trim(); RSA rsaCsp = RSA.Create();
if (keyFormat == "PKCS8")
rsaCsp.ImportPkcs8PrivateKey(Convert.FromBase64String(privateKeyPem), out _);
else if (keyFormat == "PKCS1")
rsaCsp.ImportRSAPrivateKey(Convert.FromBase64String(privateKeyPem), out _);
else
throw new Exception("只支持PKCS8,PKCS1"); if (string.IsNullOrEmpty(charset))
{
charset = DEFAULT_CHARSET;
}
byte[] data = Convert.FromBase64String(content);
int maxBlockSize = rsaCsp.KeySize / 8; //解密块最大长度限制
if (data.Length <= maxBlockSize)
{
byte[] cipherbytes = rsaCsp.Decrypt(data, RSAEncryptionPadding.Pkcs1);
return Encoding.GetEncoding(charset).GetString(cipherbytes);
}
MemoryStream crypStream = new MemoryStream(data);
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[] cryptograph = rsaCsp.Decrypt(toDecrypt, RSAEncryptionPadding.Pkcs1);
plaiStream.Write(cryptograph, 0, cryptograph.Length);
blockSize = crypStream.Read(buffer, 0, maxBlockSize);
} return Encoding.GetEncoding(charset).GetString(plaiStream.ToArray());
}
catch (Exception ex)
{
throw new Exception("DecryptContent = " + content + ",charset = " + charset, ex);
}
} #endregion }
}
调用代码:
// See https://aka.ms/new-console-template for more information using CommonUtils; try
{
//PKCS8私钥格式
string strPriPkcs8 = "MIICeQIBADANBgkqhkiG9w0BAQEFAASCAmMwggJfAgEAAoGBAMz0Czg6QUtTISa2pUkloeQB/TEpHdqrfyroWpKLW9B/LWFSOGH9nyTk1pPZaeadyEZQ6gay/C0pUAetLraq9bMA/Luxq68b87uG7WX7dKytEO2/87qGpGMRs97H+GlkzWil2QO2KK4cHnAcVicPsmi5aZ72U0BWJFyPhtd+qdmrAgMBAAECgYEAvW67iAbgHt0BASVD9C3iSjpEaVHVlC165o/IVzaTcEx8Bz3Ve0zN8W3JnvIO3ebsG4HiLLr2Nk++9rltOc0eNeGMv7F1e/OFot1wN0ON6s1g4bYh1z5Uz8FcYiMWcqHHICrx+oSFeK9x+I2Zge7enQXcsVnqEhm77ZE5YczSryECQQD9nB58e5efYchF+cYbmURioX18cUMuhQbB9Aq2N55cd689Lg35KZqT8JQTp/8tQSdCJG8d2nU8VKspUKTEAuaDAkEAzuKIIoc9PVJvy90LhIPA9c1S8BPCI7EMCaTZqJ5o3VaR2dqvUZDGX7kL3kYkQ+n7mq3KIECvkEFzA+FOP96XuQJBAJQTKHW0T/YeSKoayUHp/lS8R6F2HCy4PRbXn71+wfbpZqcJEd2OHhQM3tiPOV258esbjMlYeSUNppZL4LgVnXMCQQC7Lvs9Ql+GPDAqo7ToEM1lmICR906QPIBHuX+1sJ3wpYMROWumwPa7ZRH36j6ls+6R5OwcgmpWeuE1gYTrBNsBAkEAn2pEtAljX1foQff6CLozYg/J6J9RmVFcJ6qz0LX3052qNFBQYw8CMHB7VkVNzsDIDC8LX5uP2pzTrdPLew+pPA==";
//PKCS1私钥格式
string strPriPkcs1 = "MIICXwIBAAKBgQDM9As4OkFLUyEmtqVJJaHkAf0xKR3aq38q6FqSi1vQfy1hUjhh/Z8k5NaT2WnmnchGUOoGsvwtKVAHrS62qvWzAPy7sauvG/O7hu1l+3SsrRDtv/O6hqRjEbPex/hpZM1opdkDtiiuHB5wHFYnD7JouWme9lNAViRcj4bXfqnZqwIDAQABAoGBAL1uu4gG4B7dAQElQ/Qt4ko6RGlR1ZQteuaPyFc2k3BMfAc91XtMzfFtyZ7yDt3m7BuB4iy69jZPvva5bTnNHjXhjL+xdXvzhaLdcDdDjerNYOG2Idc+VM/BXGIjFnKhxyAq8fqEhXivcfiNmYHu3p0F3LFZ6hIZu+2ROWHM0q8hAkEA/ZwefHuXn2HIRfnGG5lEYqF9fHFDLoUGwfQKtjeeXHevPS4N+Smak/CUE6f/LUEnQiRvHdp1PFSrKVCkxALmgwJBAM7iiCKHPT1Sb8vdC4SDwPXNUvATwiOxDAmk2aieaN1Wkdnar1GQxl+5C95GJEPp+5qtyiBAr5BBcwPhTj/el7kCQQCUEyh1tE/2HkiqGslB6f5UvEehdhwsuD0W15+9fsH26WanCRHdjh4UDN7YjzldufHrG4zJWHklDaaWS+C4FZ1zAkEAuy77PUJfhjwwKqO06BDNZZiAkfdOkDyAR7l/tbCd8KWDETlrpsD2u2UR9+o+pbPukeTsHIJqVnrhNYGE6wTbAQJBAJ9qRLQJY19X6EH3+gi6M2IPyeifUZlRXCeqs9C199OdqjRQUGMPAjBwe1ZFTc7AyAwvC1+bj9qc063Ty3sPqTw=";
//公钥
string strPub = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDM9As4OkFLUyEmtqVJJaHkAf0xKR3aq38q6FqSi1vQfy1hUjhh/Z8k5NaT2WnmnchGUOoGsvwtKVAHrS62qvWzAPy7sauvG/O7hu1l+3SsrRDtv/O6hqRjEbPex/hpZM1opdkDtiiuHB5wHFYnD7JouWme9lNAViRcj4bXfqnZqwIDAQAB"; string strDJM = "泰酷拉!123ABC";//待加密字符串
strDJM = "泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC泰酷拉!123ABC";//待加密字符串,超过117字符的测试 Console.WriteLine("待加密字符串:" + strDJM);
string charSet = "UTF-8";
string strJMH = RsaEncryptUtil.RSAEncrypt(strDJM, charSet, strPub);//密文
Console.WriteLine("密文:" + strJMH); string strDecryptedByPkcs8 = RsaEncryptUtil.RSADecrypt(strJMH, charSet, strPriPkcs8, "PKCS8");//使用PKCS8私钥格式解密
Console.WriteLine("PKCS8 解密后:" + strDecryptedByPkcs8); string strDecryptedByPkcs1 = RsaEncryptUtil.RSADecrypt(strJMH, charSet, strPriPkcs1, "PKCS1");//使用PKCS1私钥格式解密 Console.WriteLine("PKCS1 解密后:" + strDecryptedByPkcs1); }
catch (Exception ex)
{ Console.WriteLine("ex:" + ex.Message);
} Console.WriteLine("Hello, World!");
Console.ReadKey();
-
C# .NET CORE .NET6 RSA 公钥加密 私钥解密的更多相关文章
- RSA 公钥加密——私钥解密
作者:刘巍然-学酥链接:http://www.zhihu.com/question/25912483/answer/31653639来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请 ...
- RSA公钥加密私钥解密
公司的项目需要电科院测评,必须保证数据的完整性和保密性,为这两个特性不得不搞个RSA+SHA1加密. 页面处理过程: 每次登录前,先向后端发送请求,由RSA生成一对公钥和私钥,获取公钥中的模modul ...
- RSA公钥加密-私钥解密/私钥加密-公钥解密
package com.tebon.ams.util;import org.apache.commons.codec.binary.Base64;import org.apache.log4j.Log ...
- Java RSA 公钥加密私钥解密
package com.lee.utils; import java.io.DataInputStream; import java.io.File; import java.io.FileInput ...
- RSA不对称加密,公钥加密私钥解密,私钥加密公钥解密
RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作. RSA是被研究得最广泛的公钥算法,从提出到现在已近二十年,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一 ...
- RSA加解密工具类RSAUtils.java,实现公钥加密私钥解密和私钥解密公钥解密
package com.geostar.gfstack.cas.util; import org.apache.commons.codec.binary.Base64; import javax.cr ...
- RSA 加密算法 Java 公钥加密私钥解密 和 私钥加密公钥解密 的特点
package com.smt.cipher.unsymmetry; import org.apache.commons.codec.binary.Base64; import org.apache. ...
- C# 基于大整数类的RSA算法实现(公钥加密私钥解密,私钥加密公钥解密)
但是C#自带的RSA算法类RSACryptoServiceProvider只支持公钥加密私钥解密,即数字证书的使用. 所以参考了一些网上的资料写了一个RSA的算法实现.算法实现是基于网上提供的一个大整 ...
- .NET Core 使用RSA算法 加密/解密/签名/验证签名
前言 前不久移植了支付宝官方的SDK,以适用ASP.NET Core使用支付宝支付,但是最近有好几位用户反应在Linux下使用会出错,调试发现是RSA加密的错误,下面具体讲一讲. RSA在.NET C ...
- C#中使用OpenSSL的公钥加密/私钥解密
在C#中进行公钥加密/私钥解密,需要用RSACryptoServiceProvider,但是它不支持由OpenSSL生成的公钥/私钥字符串. 比如这样的公钥/私钥对( 公私钥生成方法见 http:// ...
随机推荐
- Shell---控制流程
操作系统: RHEL7.x 或CentOS 7.x 最小化安装 配置好固定的IP,能访问互联网 配置好yum源(yum repolist 可以查看yum源) 本地光盘 挂载光盘,开机自动挂载 vim ...
- dark room - 2020 年苹果设计奖得主,一个足够强大的照片视频编辑器
2020年苹果设计奖得主 2015年App Store最佳应用 Darkroom 是一个高级照片和视频编辑器.它对业余摄影师来说很容易操作,但对专业摄影师来说足够强大. 下载 ➤ Darkroom 下 ...
- How to implement UDP protocal
Server implementation Open a socket on the server that listens to the UDP requests. (I've chosen 888 ...
- abc294G
Upd G 看上好模板的样子, 果然是个模板题 好题 , 首先考虑这张图的 \(Euler \ Tour\), 简单点说, 就是dfs一遍, 把每个点入栈出栈顺序存起来, 举个例子· 2 1 2 2 ...
- 开源项目audioFlux: 针对音频领域的深度学习工具库
目录 时频变换 频谱重排 倒谱系数 解卷积 谱特征 音乐信息检索 audioFlux是一个Python和C实现的库,提供音频领域系统.全面.多维度的特征提取与组合,结合各种深度学习网络模型,进行音频领 ...
- vulnhub靶场之DRIFTINGBLUES: 5
准备: 攻击机:虚拟机kali.本机win10. 靶机:DriftingBlues: 5,下载地址:https://download.vulnhub.com/driftingblues/driftin ...
- [操作系统] - 进程状态&进程描述
2.1 进程(Process) 2.1.1 定义 chatGPT版:一个具有独立功能的程序关于某个数据集合的一次运行活动 人话版:程序在并发环境中的执行过程& 进程是程序的一次执行 2.1.2 ...
- UniApp小程序开发如何获取用户手机号
我们在小程序开发的时候经常遇到这种需求,需要在账号登陆的时候进行手机号获取,并使用手机号登陆. 本文讲述如何在前后端分离的状态下获取手机号 查阅官网文档不难发现我们需要使用uni.login()这个方 ...
- pandlepanlde-01-必备数学知识
文章目录 必备数学知识 数学基础知识 高等数学 线性代数 行列式 矩阵 向量 线性方程组 矩阵的特征值和特征向量 二次型 概率论和数理统计 随机事件和概率 随机变量及其概率分布 多维随机变量及其分布 ...
- C# POST提交以及 解析 JSON 实例
一.解析的JSON字符串如下 {"tinyurl":"http:\/\/dwz.cn\/v9BxE","status":0,"lo ...