首页 新闻 会员 周边 捐助

asp.net C# 支付宝支付接口 SHA256WithRSA 签名错误

0
悬赏园豆:100 [待解决问题]
@functions{
    public static string Alipay(string method, string gateway, string notifyUrl, string returnUrl, string paysn, string subject, decimal PaySUM)
    {
        var AlipayAppId = razor.AlipayAppId();
        var AlipayPrivateKey = razor.AlipayPrivateKey();

        var order = new { out_trade_no = paysn, product_code = "FAST_INSTANT_TRADE_PAY", subject = subject, total_amount = PaySUM };

        IDictionary<string, string> data = new SortedDictionary<string, string>();
        data.Add("app_id", AlipayAppId.ToString());
        data.Add("charset", "utf-8");
        data.Add("format", "JSON");
        data.Add("method", method);
        data.Add("notify_url", notifyUrl);
        data.Add("return_url", returnUrl);
        data.Add("sign_type", "RSA2");
        data.Add("sign", "");
        data.Add("timestamp", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
        data.Add("version", "1.0");
        data.Add("biz_content", Json.Encode(order));
        
        //筛选
        data.Remove("sign");
        //拼接
        var dataString = string.Join("&", data.Select(pattern => pattern.Key + "=" + pattern.Value));
        //签名
        var sign = razor.RsaSign(dataString, AlipayPrivateKey.ToString());
        data.Add("sign",sign);
        //拼接
        dataString = string.Join("&", data.Select(pattern => pattern.Key + "=" + HttpUtility.UrlEncode(pattern.Value)));

        var url = gateway + "?" + dataString;
   
        return url;
    }
}
复制代码
@functions{
    public static string RsaSign(string data, string privatekey)
    {
        CspParameters CspParameters = new CspParameters();
        RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(2048, CspParameters);
        byte[] bytes = Encoding.UTF8.GetBytes(data);
        privatekey = RSA.ToXmlString(true);
        RSA.FromXmlString(privatekey);
        byte[] sign = RSA.SignData(bytes, "SHA256");

        return Convert.ToBase64String(sign);
    }
}
复制代码
问题补充:
调试错误,请回到请求来源地,重新发起请求。
错误代码 invalid-signature 错误原因: 验签出错,建议检查签名字符串或签名私钥与应用公钥是否匹配,网关生成的验签字符串为:app_id=2016091400508139&amp;biz_content={&quot;out_trade_no&quot;:&quot;20180606012665123456&quot;,&quot;product_code&quot;:&quot;FAST_INSTANT_TRADE_PAY&quot;,&quot;subject&quot;:&quot;达人设计购物&quot;,&quot;total_amount&quot;:5.20}&amp;charset=utf-8&amp;format=JSON&amp;method=alipay.trade.page.pay&amp;notify_url=http://www.mastersws.com/Account/payAlipay&amp;return_url=http://www.mastersws.com/Account/payAlipay/buy&amp;sign_type=RSA2&amp;timestamp=2018-06-12 16:35:44&amp;version=1.0
我用支付宝的demo测试是正确的,所以感觉应该是签名哪里不对,那个demo太繁琐了,所以想自己写一个简洁的。
缘分0919的主页 缘分0919 | 初学一级 | 园豆:96
提问于:2018-06-12 16:57

签名规则使用了支付宝的就可以了,见下面我的回答。代码比较繁琐,不知道有没有简洁的方法。其他的人回答我没时间去试,不知道可以不。

缘分0919 4年前
< >
分享
所有回答(5)
0

分别使用demo和你自己的代码RsaSign计算,看结果是否一致

另外,我记得RSA签名有好几种参数的,你上面用了默认的参数,并不一定和服务器的一样

诶碧司 | 园豆:1912 (小虾三级) | 2018-06-16 17:10
0

解决了吗?目前我也遇到该问题,还想问下你验签怎么演

博学君 | 园豆:202 (菜鸟二级) | 2019-01-10 17:51
0

怎么解决的,我也遇到了这个问题,头痛

草下飞 | 园豆:212 (菜鸟二级) | 2019-07-23 01:49
0

public static string sign(string content, string privateKey, string input_charset)
{
byte[] Data = Encoding.GetEncoding(input_charset).GetBytes(content);
RSACryptoServiceProvider rsa = DecodePemPrivateKey(privateKey);
SHA256CryptoServiceProvider sh = new SHA256CryptoServiceProvider();
byte[] signData = rsa.SignData(Data, sh);
return Convert.ToBase64String(signData);
}
content:待签字符串
privateKey:私钥
input_charset:charset类型
待签字符串处理的没问题 签名类换下这个试试
如果是RSA SHA256CryptoServiceProvider换成SHA1就行了

GoodTimeGGB | 园豆:202 (菜鸟二级) | 2020-04-07 16:39
0

//支付宝支付数据处理
@functions{
public static string Alipay(string method, string notifyUrl, string returnUrl, string paysn, string ProductCode, string subject, decimal total)
{
var AlipayAppId = razor.AlipayAppId();
var AlipayPrivateKey = razor.AlipayPrivateKey();
var gateway = "https://openapi.alipaydev.com/gateway.do";

    var order = new { out_trade_no = paysn, product_code = ProductCode, subject = subject, total_amount = total };

    SortedDictionary<string, string> data = new SortedDictionary<string, string>();
    data.Add("app_id", AlipayAppId.ToString());
    data.Add("charset", "utf-8");
    data.Add("format", "JSON");
    data.Add("method", method);
    data.Add("notify_url", notifyUrl);
    data.Add("return_url", returnUrl);
    data.Add("sign", "");
    data.Add("sign_type", "RSA2");
    data.Add("timestamp", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
    data.Add("version", "1.0");
    data.Add("biz_content", Json.Encode(order));

    //筛选
    data.Remove("sign");
    //拼接
    var dataString = string.Join("&", data.Select(pattern => pattern.Key + "=" + pattern.Value));
    //签名
    var sign = AlipaySignature.AlipaySignature.RSASign(dataString, AlipayPrivateKey.ToString(), "RSA2", "utf-8");
    data.Add("sign", sign);
    //拼接
    dataString = string.Join("&", data.Select(pattern => pattern.Key + "=" + HttpUtility.UrlEncode(pattern.Value)));

    var url = gateway + "?" + dataString;

    return url;
}

}

//签名规则用支付宝的

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

namespace AlipaySignature
{
public class AlipaySignature
{
//签名
public static string RSASign(string data, string privatekey, string signType, string charset)
{
RSACryptoServiceProvider rsaCsp = LoadCertificateString(privatekey, signType);
byte[] dataBytes = null;
if (string.IsNullOrEmpty(charset))
{
dataBytes = Encoding.UTF8.GetBytes(data);
}
else
{
dataBytes = Encoding.GetEncoding(charset).GetBytes(data);
}

        if ("RSA2".Equals(signType))
        {
            byte[] signatureBytes = rsaCsp.SignData(dataBytes, "SHA256");
            return Convert.ToBase64String(signatureBytes);
        }
        else
        {
            byte[] signatureBytes = rsaCsp.SignData(dataBytes, "SHA1");
            return Convert.ToBase64String(signatureBytes);
        }
    }
    //验签
    public static bool RSACheck(string data, string publickey, string sign, string signType, string charset, bool keyFromFile)
    {
        try
        {
            if (string.IsNullOrEmpty(charset))
            {
                charset = "utf-8";
            }

            string sPublicKeyPEM;

            if (keyFromFile)
            {
                sPublicKeyPEM = File.ReadAllText(publickey);
            }
            else
            {
                sPublicKeyPEM = "-----BEGIN PUBLIC KEY-----\r\n";
                sPublicKeyPEM += publickey;
                sPublicKeyPEM += "-----END PUBLIC KEY-----\r\n\r\n";
            }

            if ("RSA2".Equals(signType))
            {
                RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
                rsa.PersistKeyInCsp = false;
                RSACryptoServiceProviderExtension.LoadPublicKeyPEM(rsa, sPublicKeyPEM);
                bool bVerifyResultOriginal = rsa.VerifyData(Encoding.GetEncoding(charset).GetBytes(data), "SHA256", Convert.FromBase64String(sign));
                return bVerifyResultOriginal;
            }
            else
            {
                RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
                rsa.PersistKeyInCsp = false;
                RSACryptoServiceProviderExtension.LoadPublicKeyPEM(rsa, sPublicKeyPEM);

                SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();
                bool bVerifyResultOriginal = rsa.VerifyData(Encoding.GetEncoding(charset).GetBytes(data), sha1, Convert.FromBase64String(sign));
                return bVerifyResultOriginal;
            }
        }
        catch
        {
            return false;
        }
    }

    //签名算法规则
    private static RSACryptoServiceProvider LoadCertificateString(string strKey, string signType)
    {
        byte[] data = null;
        data = Convert.FromBase64String(strKey);
        try
        {
            RSACryptoServiceProvider rsa = DecodeRSAPrivateKey(data, signType);
            return rsa;
        }
        catch
        {
        }
        return null;
    }
    private static RSACryptoServiceProvider DecodeRSAPrivateKey(byte[] privkey, string signType)
    {
        byte[] MODULUS, E, D, P, Q, DP, DQ, IQ;

        MemoryStream mem = new MemoryStream(privkey);
        BinaryReader binr = new BinaryReader(mem);
        byte bt = 0;
        ushort twobytes = 0;
        int elems = 0;
        try
        {
            twobytes = binr.ReadUInt16();
            if (twobytes == 0x8130)
                binr.ReadByte();
            else if (twobytes == 0x8230)
                binr.ReadInt16();
            else
                return null;

            twobytes = binr.ReadUInt16();
            if (twobytes != 0x0102)
                return null;
            bt = binr.ReadByte();
            if (bt != 0x00)
                return null;

            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);

            CspParameters CspParameters = new CspParameters();
            CspParameters.Flags = CspProviderFlags.UseMachineKeyStore;

            int bitLen = 1024;
            if ("RSA2".Equals(signType))
            {
                bitLen = 2048;
            }

            RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(bitLen, CspParameters);
            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
        {
            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)
            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;
    }
}

}

using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.IO;

namespace AlipaySignature
{
public static class RSACryptoServiceProviderExtension
{
#region Methods
public static void LoadPublicKeyDER(RSACryptoServiceProvider provider, byte[] DERData)
{
byte[] RSAData = RSACryptoServiceProviderExtension.GetRSAFromDER(DERData);
byte[] publicKeyBlob = RSACryptoServiceProviderExtension.GetPublicKeyBlobFromRSA(RSAData);
provider.ImportCspBlob(publicKeyBlob);
}

    public static void LoadPublicKeyPEM(RSACryptoServiceProvider provider, string sPEM)
    {
        byte[] DERData = RSACryptoServiceProviderExtension.GetDERFromPEM(sPEM);
        RSACryptoServiceProviderExtension.LoadPublicKeyDER(provider, DERData);
    }

    internal static byte[] GetPublicKeyBlobFromRSA(byte[] RSAData)
    {
        byte[] data = null;
        UInt32 dwCertPublicKeyBlobSize = 0;
        if (RSACryptoServiceProviderExtension.CryptDecodeObject(CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING,
            new IntPtr((int)CRYPT_OUTPUT_TYPES.RSA_CSP_PUBLICKEYBLOB), RSAData, (UInt32)RSAData.Length, CRYPT_DECODE_FLAGS.NONE,
            data, ref dwCertPublicKeyBlobSize))
        {
            data = new byte[dwCertPublicKeyBlobSize];
            if (!RSACryptoServiceProviderExtension.CryptDecodeObject(CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING,
                new IntPtr((int)CRYPT_OUTPUT_TYPES.RSA_CSP_PUBLICKEYBLOB), RSAData, (UInt32)RSAData.Length, CRYPT_DECODE_FLAGS.NONE,
                data, ref dwCertPublicKeyBlobSize))
                throw new Win32Exception(Marshal.GetLastWin32Error());
        }
        else
            throw new Win32Exception(Marshal.GetLastWin32Error());
        return data;
    }

    internal static byte[] GetRSAFromDER(byte[] DERData)
    {
        byte[] data = null;
        byte[] publicKey = null;
        CERT_PUBLIC_KEY_INFO info;
        UInt32 dwCertPublicKeyInfoSize = 0;
        IntPtr pCertPublicKeyInfo = IntPtr.Zero;
        if (RSACryptoServiceProviderExtension.CryptDecodeObject(CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING, new IntPtr((int)CRYPT_OUTPUT_TYPES.X509_PUBLIC_KEY_INFO),
            DERData, (UInt32)DERData.Length, CRYPT_DECODE_FLAGS.NONE, data, ref dwCertPublicKeyInfoSize))
        {
            data = new byte[dwCertPublicKeyInfoSize];
            if (RSACryptoServiceProviderExtension.CryptDecodeObject(CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING, new IntPtr((int)CRYPT_OUTPUT_TYPES.X509_PUBLIC_KEY_INFO),
                DERData, (UInt32)DERData.Length, CRYPT_DECODE_FLAGS.NONE, data, ref dwCertPublicKeyInfoSize))
            {
                GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
                try
                {
                    info = (CERT_PUBLIC_KEY_INFO)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(CERT_PUBLIC_KEY_INFO));
                    publicKey = new byte[info.PublicKey.cbData];
                    Marshal.Copy(info.PublicKey.pbData, publicKey, 0, publicKey.Length);
                }
                finally
                {
                    handle.Free();
                }
            }
            else
                throw new Win32Exception(Marshal.GetLastWin32Error());
        }
        else
            throw new Win32Exception(Marshal.GetLastWin32Error());
        return publicKey;
    }

    internal static byte[] GetDERFromPEM(string sPEM)
    {
        UInt32 dwSkip, dwFlags;
        UInt32 dwBinarySize = 0;

        if (!RSACryptoServiceProviderExtension.CryptStringToBinary(sPEM, (UInt32)sPEM.Length, CRYPT_STRING_FLAGS.CRYPT_STRING_BASE64HEADER, null, ref dwBinarySize, out dwSkip, out dwFlags))
            throw new Win32Exception(Marshal.GetLastWin32Error());

        byte[] decodedData = new byte[dwBinarySize];
        if (!RSACryptoServiceProviderExtension.CryptStringToBinary(sPEM, (UInt32)sPEM.Length, CRYPT_STRING_FLAGS.CRYPT_STRING_BASE64HEADER, decodedData, ref dwBinarySize, out dwSkip, out dwFlags))
            throw new Win32Exception(Marshal.GetLastWin32Error());
        return decodedData;
    }
    #endregion Methods

    #region P/Invoke Constants
    internal enum CRYPT_ACQUIRE_CONTEXT_FLAGS : uint
    {
        CRYPT_NEWKEYSET = 0x8,
        CRYPT_DELETEKEYSET = 0x10,
        CRYPT_MACHINE_KEYSET = 0x20,
        CRYPT_SILENT = 0x40,
        CRYPT_DEFAULT_CONTAINER_OPTIONAL = 0x80,
        CRYPT_VERIFYCONTEXT = 0xF0000000
    }

    internal enum CRYPT_PROVIDER_TYPE : uint
    {
        PROV_RSA_FULL = 1
    }

    internal enum CRYPT_DECODE_FLAGS : uint
    {
        NONE = 0,
        CRYPT_DECODE_ALLOC_FLAG = 0x8000
    }

    internal enum CRYPT_ENCODING_FLAGS : uint
    {
        PKCS_7_ASN_ENCODING = 0x00010000,
        X509_ASN_ENCODING = 0x00000001,
    }

    internal enum CRYPT_OUTPUT_TYPES : int
    {
        X509_PUBLIC_KEY_INFO = 8,
        RSA_CSP_PUBLICKEYBLOB = 19,
        PKCS_RSA_PRIVATE_KEY = 43,
        PKCS_PRIVATE_KEY_INFO = 44
    }

    internal enum CRYPT_STRING_FLAGS : uint
    {
        CRYPT_STRING_BASE64HEADER = 0,
        CRYPT_STRING_BASE64 = 1,
        CRYPT_STRING_BINARY = 2,
        CRYPT_STRING_BASE64REQUESTHEADER = 3,
        CRYPT_STRING_HEX = 4,
        CRYPT_STRING_HEXASCII = 5,
        CRYPT_STRING_BASE64_ANY = 6,
        CRYPT_STRING_ANY = 7,
        CRYPT_STRING_HEX_ANY = 8,
        CRYPT_STRING_BASE64X509CRLHEADER = 9,
        CRYPT_STRING_HEXADDR = 10,
        CRYPT_STRING_HEXASCIIADDR = 11,
        CRYPT_STRING_HEXRAW = 12,
        CRYPT_STRING_NOCRLF = 0x40000000,
        CRYPT_STRING_NOCR = 0x80000000
    }
    #endregion P/Invoke Constants

    #region P/Invoke Structures
    [StructLayout(LayoutKind.Sequential)]
    internal struct CRYPT_OBJID_BLOB
    {
        internal UInt32 cbData;
        internal IntPtr pbData;
    }

    [StructLayout(LayoutKind.Sequential)]
    internal struct CRYPT_ALGORITHM_IDENTIFIER
    {
        internal IntPtr pszObjId;
        internal CRYPT_OBJID_BLOB Parameters;
    }

    [StructLayout(LayoutKind.Sequential)]
    struct CRYPT_BIT_BLOB
    {
        internal UInt32 cbData;
        internal IntPtr pbData;
        internal UInt32 cUnusedBits;
    }

    [StructLayout(LayoutKind.Sequential)]
    struct CERT_PUBLIC_KEY_INFO
    {
        internal CRYPT_ALGORITHM_IDENTIFIER Algorithm;
        internal CRYPT_BIT_BLOB PublicKey;
    }
    #endregion P/Invoke Structures

    #region P/Invoke Functions
    [DllImport("advapi32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    internal static extern bool CryptDestroyKey(IntPtr hKey);

    [DllImport("advapi32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    internal static extern bool CryptImportKey(IntPtr hProv, byte[] pbKeyData, UInt32 dwDataLen, IntPtr hPubKey, UInt32 dwFlags, ref IntPtr hKey);

    [DllImport("advapi32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    internal static extern bool CryptReleaseContext(IntPtr hProv, Int32 dwFlags);

    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    internal static extern bool CryptAcquireContext(ref IntPtr hProv, string pszContainer, string pszProvider, CRYPT_PROVIDER_TYPE dwProvType, CRYPT_ACQUIRE_CONTEXT_FLAGS dwFlags);

    [DllImport("crypt32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    [return: MarshalAs(UnmanagedType.Bool)]
    internal static extern bool CryptStringToBinary(string sPEM, UInt32 sPEMLength, CRYPT_STRING_FLAGS dwFlags, [Out] byte[] pbBinary, ref UInt32 pcbBinary, out UInt32 pdwSkip, out UInt32 pdwFlags);

    [DllImport("crypt32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    internal static extern bool CryptDecodeObjectEx(CRYPT_ENCODING_FLAGS dwCertEncodingType, IntPtr lpszStructType, byte[] pbEncoded, UInt32 cbEncoded, CRYPT_DECODE_FLAGS dwFlags, IntPtr pDecodePara, ref byte[] pvStructInfo, ref UInt32 pcbStructInfo);

    [DllImport("crypt32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    internal static extern bool CryptDecodeObject(CRYPT_ENCODING_FLAGS dwCertEncodingType, IntPtr lpszStructType, byte[] pbEncoded, UInt32 cbEncoded, CRYPT_DECODE_FLAGS flags, [In, Out] byte[] pvStructInfo, ref UInt32 cbStructInfo);
    #endregion P/Invoke Functions
}

}

缘分0919 | 园豆:96 (初学一级) | 2020-04-09 10:24
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册