C# RSA PSS签名 微信的加密与签名

请用C#帮我解答
服务端api签名
https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/getting_started/api_signature.html
这是微信的网址。

这是我访JAVA的成功网址
https://developers.weixin.qq.com/community/develop/article/doc/000e68b8038ed8796f00f6c2f68c13

 public static string RSASignPEM(string data, string privateKeyPEM, string hashAlgorithm = "MD5", string encoding = "UTF-8")

        {

            byte[] pemkey = Convert.FromBase64String(privateKeyPEM);



            RSACryptoServiceProvider RSA = DecodeRSAPrivateKey(privateKeyPEM);//function to parse .pem file 



            RSAParameters rsaParams = RSA.ExportParameters(true);

            RSACng RSACng = new RSACng();

            RSACng.ImportParameters(rsaParams);

            var dataBytes = Encoding.GetEncoding(encoding).GetBytes(data);

           byte[] signature = RSACng.SignData(dataBytes, HashAlgorithmName.SHA256,RSASignaturePadding.Pss);

           return Convert.ToBase64String(signature);





    

        }







        /// <summary>

        /// RSA私钥格式转换

        /// </summary>

        /// <param name="privateKey"></param>

        /// <returns></returns>

        private static RSACryptoServiceProvider DecodeRSAPrivateKey(string privateKey)

        {

            var privateKeyBits = System.Convert.FromBase64String(privateKey);

            var RSA = new RSACryptoServiceProvider();

            var RSAparams = new RSAParameters();

            using (BinaryReader binr = new BinaryReader(new MemoryStream(privateKeyBits)))

            {

                byte bt = 0;

                ushort twobytes = 0;

                twobytes = binr.ReadUInt16();

                if (twobytes == 0x8130)

                    binr.ReadByte();

                else if (twobytes == 0x8230)

                    binr.ReadInt16();

                else

                    throw new Exception("Unexpected value read binr.ReadUInt16()");



                twobytes = binr.ReadUInt16();

                if (twobytes != 0x0102)

                    throw new Exception("Unexpected version");



                bt = binr.ReadByte();

                if (bt != 0x00)

                    throw new Exception("Unexpected value read binr.ReadByte()");



                RSAparams.Modulus = binr.ReadBytes(GetIntegerSize(binr));

                RSAparams.Exponent = binr.ReadBytes(GetIntegerSize(binr));

                RSAparams.D = binr.ReadBytes(GetIntegerSize(binr));

                RSAparams.P = binr.ReadBytes(GetIntegerSize(binr));

                RSAparams.Q = binr.ReadBytes(GetIntegerSize(binr));

                RSAparams.DP = binr.ReadBytes(GetIntegerSize(binr));

                RSAparams.DQ = binr.ReadBytes(GetIntegerSize(binr));

                RSAparams.InverseQ = binr.ReadBytes(GetIntegerSize(binr));

            }

            RSA.ImportParameters(RSAparams);

            return RSA;

        }

        private static int GetIntegerSize(BinaryReader binr)

        {

            byte bt = 0;

            byte lowbyte = 0x00;

            byte highbyte = 0x00;

            int count = 0;

            bt = binr.ReadByte();

            if (bt != 0x02)

                return 0;

            bt = binr.ReadByte();



            if (bt == 0x81)

                count = binr.ReadByte();

            else

if (bt == 0x82)

            {

                highbyte = binr.ReadByte();

                lowbyte = binr.ReadByte();

                byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };

                count = BitConverter.ToInt32(modint, 0);

            }

            else

            {

                count = bt;

            }

            while (binr.ReadByte() == 0x00)

            {

                count -= 1;

            }

            binr.BaseStream.Seek(-1, SeekOrigin.Current);

            return count;

        }





C#,这是签名方法,签名后一直提示签名错误
这是调用签名代码
    String url_path = ctx["url_path"].ToString();   

  int reqTs = req["req_ts"].ObjectToInt();

            String reqData = req["req_data"].ToString();



            String payload = url_path + "\n" + local_appid + "\n" + reqTs + "\n" + reqData;

 RSASignPEM(payload, local_private_key); //这里证书用的是直接下载的证书,一直提示签名错误,也不知道哪里出错了。
  var apiUrl = $"{url_path}?access_token={token}"
                   .WithHeader("Content-Type", "application/json;charset=utf-8")
                   .WithHeader("Wechatmp-Appid", local_appid)
                   .WithHeader("Wechatmp-TimeStamp", localTs)
                   .WithHeader("Wechatmp-Signature", sign)

                   ;

        var result = await apiUrl.PostJsonAsync(reqData).ReceiveJson<JObject>();

POST返回一直提示签名出错

你看看这篇博客,应该对你有帮助:

不行,搞不定

在RSASignPEM方法中,你使用了SHA256作为签名的哈希算法(HashAlgorithmName.SHA256),但是默认情况下hashAlgorithm参数被设置为”MD5”,是不是这么个理儿

你的哈希算法不对,你用的是SHA256

而微信开放平台对签名的要求是HMAC-SHA256算法

所以签名的方法不同导致了签名错误。

给你一段代码你参考下咯


using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;

public static class WeChatSignatureHelper
{
    public static string GenerateSignature(string urlPath, string appid, int timestamp, string data, string privateKey)
    {
        string payload = $"{urlPath}\n{appid}\n{timestamp}\n{data}";

        byte[] keyBytes = Encoding.UTF8.GetBytes(privateKey);
        byte[] payloadBytes = Encoding.UTF8.GetBytes(payload);

        using (var hmac = new HMACSHA256(keyBytes))
        {
            byte[] signatureBytes = hmac.ComputeHash(payloadBytes);
            return Convert.ToBase64String(signatureBytes);
        }
    }
}

C#实现RSA加密与解密、签名与认证
可以参考下

参考开源
https://gitee.com/fudiwei/DotNetCore.SKIT.FlurlHttpClient.Wechat

换不同的加密方法试试

检查下API请求中的参数与微信签名生成的要求一致,以及API请求中的数据是否完整和正确。

看一下签名生成用的参数和api中要求的是否一致

有官方demo吧,看一下他的demo

北京交通大学和中科院光电所都是国内著名的高等学府,均有着优秀的师资力量和科研实力,两者都有着各自的优势和特点,选择哪一个读研究生需要根据个人兴趣、职业规划、未来发展等因素进行决策。

一、学校概况

  1. 北京交通大学

北京交通大学(Beijing Jiaotong University),简称“BJTU”,是中华人民共和国交通运输部直属、教育部共建的全国重点大学,国家“211工程”、“985工程优势学科创新平台”重点建设高校,也是国家“双一流”、“世界一流学科建设高校”。学校创建于1896年,前身为京张铁路师范学校,历经百年风雨沧桑,已经成为国内交通领域和信息技术领域的重要高等学府。

  1. 中科院光电所

中科院光电技术研究所(Institute of Optoelectronics,IOE)是中国科学院下属的研究机构,是中国光电技术领域的重要基地,是国家“双一流”、“世界一流学科建设高校”。研究所创建于1958年,是中国最早从事光电技术研究的机构之一,早期以研制光电系统为主,现在已经发展成为集基础研究、技术研究、产业化应用为一体的综合性研究机构。

二、师资力量

  1. 北京交通大学

北京交通大学拥有一支高水平、有活力、富有创新精神的师资队伍。学校现有教职工3106人,其中教授533人、副教授723人,博士生导师533人、硕士生导师1156人。近年来,北京交通大学还引进了一批优秀人才,包括国家千人计划、长江学者、杰青、优青、青年拔尖人才等。

  1. 中科院光电所

中科院光电所的师资力量也异常雄厚。研究所现有教员近200人,其中包括了14名中科院院士、10名中国工程院院士,还有一批高水平的青年人才,包括国家杰青、优青、千人计划等。

三、学科设置和研究领域

  1. 北京交通大学

北京交通大学的学科建设十分齐全,涉及了工、理、管、文、法、教育和艺术多个领域,尤其在交通领域、信息技术领域、电子科学与技术领域、机械与电子工程领域等方面处于国内领先地位。学校设有15个学院、1所独立学院,开设的本科专业40个,研究生专业95个,涵盖了工、理、管、文、法、教育和艺术等多个领域。

  1. 中科院光电所

中科院光电所主要开展的是光电技术研究和应用,研究领域非常专业,包括光学、光电子、半导体物理、微纳光电子、光学工程等方面,研究所拥有了许多具有国际水平的研究团队和实验室,这些实验室和团队都是在光电领域取得了举世瞩目的进展。

四、学术氛围

  1. 北京交通大学

北京交通大学注重培养学生的实践能力和实用技能,教学内容与时俱进,培养的学生不仅具备深厚的专业知识和理论基础,还能熟练应用所学知识为社会做出贡献。学校有着良好的学术氛围和创新氛围,各个学院开设了许多学术团体和社团,帮助学生深入探究科学问题和提升学术水平。

  1. 中科院光电所

中科院光电所以研究为主,注重培养学生的研究能力和创新能力。学生在这里可以接触到许多前沿的研究项目和技术,学校还有一系列的学术活动和科研论坛,让学生在这里能够更好地开展研究和学术交流。

五、教育教学和科研成果

  1. 北京交通大学

北京交通大学是国内首批具有博士和硕士学位授权的高校之一,学校有着严格、规范的教育教学质量监控体系,注重培养学生的创新思维和实践能力。学校的科研实力也非常强大,近年来在多个领域都取得了一系列的重要科研成果,为中国的经济和科技发展做出了巨大的贡献。

  1. 中科院光电所

中科院光电所在光电技术领域取得了很多突破性成果,为我国的光电技术领域发展做出了极大的贡献,科研实力得到了广泛的认可。研究所注重基础研究与应用研究相结合,不仅积极推动科技成果的转化和产业化,还致力于推广创新精神和科技文化,努力培养与光电技术相关的高端人才。

结论:

总体而言,北京交通大学和中科院光电所都是具有较高声望和教学科研水平的高等学府,两者各自有着各自的优势和特点。如若您偏好交通领域和计算机科学和技术领域,建议您选择北京交通大学;如果您对光学或光电子等方面更感兴趣,或者想要深度钻研科研,那么您可以选择中科院光电所。当然,最终的选择还是需要以个人兴趣、职业规划、未来发展等因素为重要考量。

RSA PSS签名是一种基于RSA加密算法的签名方式,它具有强大的数字签名安全性和防篡改性能。微信的加密与签名涉及微信接口的调用和开发,需要使用到微信提供的SDK和API。

在微信中,数据进行加密和签名有以下两种场景:

  1. 微信支付

在微信支付中,使用RSA算法进行数据签名,保证数据的安全性和完整性。具体实现过程如下:

a. 商户使用RSA密钥对生成公钥和私钥;

b. 在支付请求中,商户使用私钥对数据进行签名,将签名和加密前的数据一并发送给微信支付;

c. 微信支付收到数据后,使用商户公钥进行验签,确保数据的完整性,防止数据被篡改和伪造;

d. 微信支付使用对称加密算法对数据进行加密,保证数据的保密性,然后将加密后的数据和签名一并返回给商户。

  1. 微信公众号/小程序/APP接口

在微信公众号/小程序/APP中,使用SHA1算法进行数据签名,保证数据的安全性和完整性。具体实现过程如下:

a. 微信公众号/小程序/APP向微信服务器发送HTTP请求,请求中携带了四个参数:timestamp、nonce、token和signature;

b. 微信服务器收到请求后,先将timestamp、nonce和token按字典序排序,然后将这三个参数拼接成一个字符串进行SHA1签名,得到signature;

c. 微信服务器将计算得到的signature和请求中的signature进行比较,如果一致,则说明请求合法,返回对应的数据,否则拒绝请求。

总的来说,微信的加密与签名涉及到不同的算法和流程,在开发过程中需要仔细阅读微信提供的文档和API,保证接口的安全性和可靠性。