当前位置: 首页 > news >正文

C#使用SHA256withRSA加密对接口进行访问

需求:接口改成SHA256withRSA加密访问

材料:自己电脑生成的RSA公钥和私钥(这里公钥提供给接口方配置,私钥我们留着自己用来加密。)

公钥私钥生成方式:

在自己电脑上使用openssl(类似cmd的界面,然后运行以下命令生成,生成后,你会在你【C:\Users\用户名】的路径下找到private_key.pem和public_key.pem这两个文件。

-public_key.pem提供给接口方,我们用private_key.pem进行加密(自留,不外传)。)

image

 

openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048openssl rsa -pubout -in private_key.pem -out public_key.pem

 

代码:

这里引用Portable.BouncyCastle

image

 

        private void button1_Click(object sender, EventArgs e){#regionstring publicKeyPath = @"C:\Users\T709\1\public_key.pem";string privateKeyPath = @"C:\Users\T709\1\private_key.pem";//生成32位随机字符串var requestNonceId = "";var requestDate = "";Guid newG = Guid.NewGuid();requestNonceId = newG.ToString().Replace("-", "");// 获取当前时间的Unix时间戳DateTime now = DateTime.UtcNow;TimeSpan span = now - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);long unixTimestamp = (long)span.TotalMilliseconds;requestDate = unixTimestamp.ToString();string requestUrl = "/api/auth/sign/v1";string signStr = requestNonceId + requestDate + requestUrl;#endregionstring privateKey = LoadPrivateContent(privateKeyPath);//SHA256withRSA//SHA-256withRSAvar s = RSASignJavaBouncyCastle(signStr, privateKey, "SHA256withRSA");var s2 = EncryptPrivateKeyJava(privateKey, signStr);}#region/// <summary>  /// 基于BouncyCastle的RSA私钥加密  /// </summary>  /// <param name="privateKeyJava"></param>  /// <param name="data"></param>  /// <returns></returns>  public static string EncryptPrivateKeyJava(string privateKeyJava, string data, string encoding = "UTF-8")  {  RsaKeyParameters privateKeyParam = (RsaKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKeyJava));  byte[] cipherbytes = Encoding.GetEncoding(encoding).GetBytes(data);  RsaEngine rsa = new RsaEngine();  rsa.Init(true, privateKeyParam);//参数true表示加密/false表示解密。  cipherbytes = rsa.ProcessBlock(cipherbytes, 0, cipherbytes.Length);  return Convert.ToBase64String(cipherbytes);  }  #region  公钥解密  /// <summary>  /// 基于BouncyCastle的RSA公钥解密  /// </summary>  /// <param name="publicKeyJava"></param>  /// <param name="data"></param>  /// <param name="encoding"></param>  /// <returns></returns>  public static string DecryptPublicKeyJava(string publicKeyJava, string data, string encoding = "UTF-8")  {  RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKeyJava));  byte[] cipherbytes = Convert.FromBase64String(data);  RsaEngine rsa = new RsaEngine();  rsa.Init(false, publicKeyParam);//参数true表示加密/false表示解密。  cipherbytes = rsa.ProcessBlock(cipherbytes, 0, cipherbytes.Length);  return Encoding.GetEncoding(encoding).GetString(cipherbytes);  }  #endregion  #region 加签      /// <summary>  /// 基于BouncyCastle的RSA签名  /// </summary>  /// <param name="data"></param>  /// <param name="privateKeyJava"></param>  /// <param name="hashAlgorithm">JAVA的和.NET的不一样,如:MD5(.NET)等同于MD5withRSA(JAVA)</param>  /// <param name="encoding"></param>  /// <returns></returns>  public static string RSASignJavaBouncyCastle(string data, string privateKeyJava, string hashAlgorithm = "MD5withRSA", string encoding = "UTF-8")  {  RsaKeyParameters privateKeyParam = (RsaKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKeyJava));  ISigner signer = SignerUtilities.GetSigner(hashAlgorithm);  signer.Init(true, privateKeyParam);//参数为true验签,参数为false加签  var dataByte = Encoding.GetEncoding(encoding).GetBytes(data);  signer.BlockUpdate(dataByte, 0, dataByte.Length);  //return Encoding.GetEncoding(encoding).GetString(signer.GenerateSignature()); //签名结果 非Base64String  return Convert.ToBase64String(signer.GenerateSignature());  }  #endregion  #region 验签  /// <summary>  /// 基于BouncyCastle的RSA签名  /// </summary>  /// <param name="data">源数据</param>  /// <param name="publicKeyJava"></param>  /// <param name="signature">base64签名</param>  /// <param name="hashAlgorithm">JAVA的和.NET的不一样,如:MD5(.NET)等同于MD5withRSA(JAVA)</param>  /// <param name="encoding"></param>  /// <returns></returns>  public static bool VerifyJavaBouncyCastle(string data, string publicKeyJava, string signature, string hashAlgorithm = "MD5withRSA", string encoding = "UTF-8")  {  RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKeyJava));  ISigner signer = SignerUtilities.GetSigner(hashAlgorithm);  signer.Init(false, publicKeyParam);  byte[] dataByte = Encoding.GetEncoding(encoding).GetBytes(data);             signer.BlockUpdate(dataByte, 0, dataByte.Length);  //byte[] signatureByte = Encoding.GetEncoding(encoding).GetBytes(signature);// 非Base64String  byte[] signatureByte = Convert.FromBase64String(signature);  return signer.VerifySignature(signatureByte);  }#endregion#endregionpublic static string LoadPrivateContent(string pemPath){string content = File.ReadAllText(pemPath);// 精确移除PEM头尾和所有空白字符content = content.Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", "").Replace("-----BEGIN PRIVATE KEY-----", "").Replace("-----END PRIVATE KEY-----", "").Replace("-----BEGIN RSA PRIVATE KEY-----", "").Replace("-----END RSA PRIVATE KEY-----", "").Replace("\r", "").Replace("\n", "");//.Replace("\\s", ""); // 移除所有空白字符,包括换行、空格、制表符return content;}

 

注:

这里我代码自行解析正常,但是Java接口方调用老是显示签名验证错误。

可能的原因:对方配置的不是你提供的公钥。(我这个就是碰到)

另一个就是我用的PostMan中,【Content-Type】、【Content-Length】和【Host】没有勾选。(这里默认勾选的,我测试的时候不小心给去掉了。)

image

 

 

感谢:https://www.cnblogs.com/ggll611928/p/18028968

https://blog.csdn.net/zxy13826134783/article/details/126447948

https://www.cnblogs.com/Alex80/p/11526634.html

https://www.cnblogs.com/kevin860/p/9557859.html

https://www.cnblogs.com/dj258/p/18261075

 

http://www.jsqmd.com/news/769918/

相关文章:

  • Gaspol项目是韭菜盘吗?2026年深度解析其运作模式与市场前景 - GrowthUME
  • BthPS3蓝牙驱动:Windows上完美连接PS3控制器的终极解决方案
  • 不只是boot.img:用AIK和Magisk Boot工具无损修改Android启动镜像的完整指南
  • 炉石传说智能脚本完全指南:3步实现自动化游戏体验
  • 如何高效掌控电脑风扇:Fan Control完整配置指南
  • 深耕西南钢材贸易 13 载,四川鑫方盛打造全品类钢材供应标杆 - 深度智识库
  • 别再只调参了!人工蜂群算法(ABC)的三大实战陷阱与调优心得
  • 2026 全国靠谱腐植酸厂家推荐:正规大厂排名与分类 - 品牌智鉴榜
  • GFlowNet在无线传播路径采样中的工程实践
  • 不只是点Run:用Calculator和参数分析提升Cadence仿真效率的5个技巧
  • 破译COPD的分子密码:生物标志物与多因子检测技术研究进展
  • gvim基本操作
  • 初次使用Taotoken从注册到完成第一个API调用的全过程记录
  • LIBERO+Robosuite实战:手把手教你同时可视化彩色图和深度图,提升机器人视觉调试效率
  • 2026年VI设计公司怎么选:VI设计公司的新形态正在成为趋势 - 2026品牌推荐官
  • 2026年喀什卫浴定制、智能卫浴镜与岩板精切一站式工厂深度选购指南 - 年度推荐企业名录
  • 2026全国腐植酸厂家推荐汇总表(含产区标杆+分类提要) - 品牌智鉴榜
  • FlipIt:当你的Windows屏幕成为一台数字古董钟
  • 3步搞定OBS浏览器插件:从零到精通的完整指南
  • KH Coder完全指南:如何零基础玩转文本挖掘与内容分析
  • 2026最新靠谱包装印刷公司推荐!国内优质权威榜单发布,广东佛山等地高性价比专业品牌精选 - 十大品牌榜
  • 2026年爱采购开户公司怎么选?看完这份正规名单就懂了 - 速递信息
  • 终极音乐解锁指南:3分钟学会浏览器解密加密音乐文件
  • 海口上门回收实测:福正美97分钟达,第二名的数据不好意思写 - 福正美黄金回收
  • 想快速导出视频字幕?2026年剪映导出字幕文字的方法+提词匠全能方案
  • 2026年陕西省国标线缆厂家推荐|西北国标线缆生产基地甄选指南 - 深度智识库
  • 终极iOS激活锁绕过指南:applera1n免费工具完整教程
  • Django AI助手集成指南:从模型部署到生产环境优化
  • 湖北省SCMP报考官方授权机构及相关指南 - 众智商学院课程中心
  • 成都加盟店换老板像走马灯,福正美二十年没挪窝,地址都能背出来 - 福正美黄金回收