Remember Alipay interface, docking, involves extracting certificate number SN Solutions

Alipay for .NET SDK package does not have a method to extract the certificate serial number SN, the only method for the Java platform have corresponding (outright discrimination ah ~ ~)

There are two options in order to extract the serial number SN:

1. Java SDK package directly extracted SN

2. The conversion into Java code C # code to extract

 

Following the prompts on the signature guide Alipay:

 

I have two options to use to extract the certificate application SN is used to extract Java, no problem; but in the SN Alipay to extract the root certificate through the Java SDK, it returns an error;

Because Java code is not familiar with, change does not move, SN extracted directly replaced with C # code;

Code from the Internet to find, here record:

using Org.BouncyCastle.Math;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;

namespace Qcnt.ThreeParty.Payment
{
    /// <summary>
    /// party payment related to static helper class.
    /// </summary>
    public static class Alipay_Crt_SN_Helper
    {
        /// <summary>
        /// Gets the timestamp of the current time.
        /// </summary>
        public static string Timestamp
        {
            get
            {
                TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);

                return Convert.ToInt64(ts.TotalSeconds).ToString();
            }
        }

        /// <summary>
        /// Gets a random string of specified length.
        /// </summary>
        /// <param name = "length"> be generated random string length. </ Param>
        /// <returns> Returns the generated random string good. </ Returns>
        public static string GetRandomString(int length)
        {
            string str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

            StringBuilder result = new StringBuilder();

            Random rd = new Random();

            while (length > 0)
            {
                result.Append(str[rd.Next(str.Length)]);

                length--;
            }

            return result.ToString();
        }

        /// <summary>
        /// the string MD5 encryption.
        /// </summary>
        /// <param name = "str"> require encryption string. </ Param>
        /// <param name = "encoding"> string code set used. </ Param>
        /// <param name = "delimiter"> separator. </ Param>
        /// <returns> encrypted string returned. </ Returns>
        public static string MD5Encrypt(string str, Encoding encoding, char? delimiter)
        {
            if (string.IsNullOrEmpty(str))
                return null;

            byte[] result = encoding.GetBytes(str);

            MD5 md5 = new MD5CryptoServiceProvider();

            byte[] output = md5.ComputeHash(result);

            if (delimiter != null && delimiter.HasValue)
                return BitConverter.ToString(output).ToUpper().Replace('-', delimiter.Value);

            return BitConverter.ToString(output).ToUpper().Replace("-", "");
        }

        /// <summary>
        /// analog transmit an HTTP POST request.
        /// </summary>
        /// <param name = "url"> URL address to be requested. </ Param>
        /// <param name = "data"> request parameter string. </ Param>
        /// <param name = "encoding"> string code sets used by the request. </ Param>
        /// <returns> return request results. </ Returns>
        public static string HttpPost(string url, string data, Encoding encoding)
        {
            return HttpPost(url, data, null, null, encoding);
        }

        /// <summary>
        /// analog transmit an HTTP POST request.
        /// </summary>
        /// <param name = "url"> URL address to be requested. </ Param>
        /// <param name = "data"> request parameter string. </ Param>
        /// <param name = "certPath"> additional certification path (Double-mounted prior to use the certificate). </ Param>
        /// <param name = "certPassword"> additional certificate password. </ Param>
        /// <param name = "encoding"> string code sets used by the request. </ Param>
        /// <returns> return request results. </ Returns>
        public static string HttpPost(string url, string data, string certPath, string certPassword, Encoding encoding)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Timeout = 10000;
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";

            if (!string.IsNullOrWhiteSpace(certPath) && !string.IsNullOrWhiteSpace(certPassword) && File.Exists(certPath))
            {
                ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback((sender, certificate, chain, errors) =>
                {
                    if (errors == SslPolicyErrors.None)
                        return true;

                    return false;
                });

                request.ClientCertificates.Add(new X509Certificate2(certPath, certPassword, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable));
            }

            if (!string.IsNullOrWhiteSpace(data))
            {
                byte[] dataBytes = encoding.GetBytes(data);

                request.ContentLength = dataBytes.Length;

                using (Stream stream = request.GetRequestStream())
                {
                    stream.Write(dataBytes, 0, dataBytes.Length);
                }
            }

            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                using (Stream responseStream = response.GetResponseStream())
                {
                    using (StreamReader streamReader = new StreamReader(responseStream, Encoding.GetEncoding("gb2312")))
                    {
                        return streamReader.ReadToEnd();
                    }
                }
            }
        }

        /// <summary>
        /// Get a match to the first value according to the XmlNode XmlNode InnerText name.
        /// </summary>
        /// <param name = "node"> root XmlNode XmlNode matching. </ Param>
        /// <param name = "nodeName"> to get the name of InnerText XmlNode value. </ Param>
        /// <returns> If the specified value of the XmlNode XmlNode find InnerText is returned, otherwise null. </ Returns>
        public static string GetNodeInnerText(this XmlNode node, string nodeName)
        {
            if (node == null)
                return null;

            XmlNode resultNode = node.SelectSingleNode(nodeName);

            if (resultNode == null)
                return null;

            return resultNode.InnerText;
        }

        /// <summary>
        /// specified set of parameters to generate MD5 signature.
        /// </summary>
        /// <param name = "pars"> set of parameters to generate signature used. </ Param>
        /// <param name = "key"> Key signature generation used. </ Param>
        /// <returns> good signature generated return string. </ Returns>
        public static string CreateMD5Sign(Dictionary<string, string> pars, string key)
        {
            List<string> sortedKey = new List<string>(pars.Keys);

            sortedKey.Sort();

            StringBuilder parsString = new StringBuilder();

            foreach (string itemKey in sortedKey)
            {
                parsString.AppendFormat("{0}={1}&", itemKey, pars[itemKey]);
            }

            parsString.AppendFormat("key={0}", key);

            return MD5Encrypt(parsString.ToString(), Encoding.UTF8, null);
        }

        /// <summary>
        /// specified set of parameters to generate RSA2 signature.
        /// </summary>
        /// <param name = "pars"> set of parameters to generate signature used. </ Param>
        /// <param name = "privateKey"> signature generating private keys used. </ Param>
        /// <returns> good signature generated return string. </ Returns>
        public static string CreateRSA2Sign(Dictionary<string, string> pars, string privateKey)
        {
            List<string> sortedKey = new List<string>(pars.Keys);

            sortedKey.Sort();

            StringBuilder parsString = new StringBuilder();

            int i = 0;

            foreach (string key in sortedKey)
            {
                if (i > 0)
                    parsString.Append("&");

                parsString.AppendFormat("{0}={1}", key, pars[key]);

                i++;
            }

            return RSA2Encrypt(parsString.ToString(), privateKey);
        }

        /// <summary>
        /// converted into the specified string Xml <see cref = "Dictionary {TKey, TValue}" /> type parameter set.
        /// </summary>
        /// <param name = "xmlString"> Xml string to be converted. </ Param>
        /// <returns> parameter set conversion if the conversion is successful is returned. </ Returns>
        public static Dictionary<string, string> XmlToParameters(string xmlString)
        {
            if (string.IsNullOrWhiteSpace(xmlString))
                return null;

            XmlDocument xml = new XmlDocument();
            xml.LoadXml (xmlString);

            XmlNode xmlRoot = xml.DocumentElement;

            Dictionary<string, string> result = new Dictionary<string, string>();

            foreach (XmlNode childNode in xmlRoot.ChildNodes)
            {
                result.Add(childNode.Name, childNode.InnerText);
            }

            return result;
        }

        /// <summary>
        /// Converts the specified parameter set to string format Xml.
        /// </summary>
        /// <param name = "pars"> set of parameters to be converted. </ Param>
        /// <returns> Xml return string conversion. </ Returns>
        public static string ParametersToXmlString(Dictionary<string, string> pars)
        {
            StringBuilder parsString = new StringBuilder("<xml>");

            foreach (string key in pars.Keys)
            {
                parsString.AppendFormat("<{0}>{1}</{0}>", key, pars[key].Replace("<", "<").Replace(">", ">").Replace("&", "&").Replace("\"", """));
            }

            parsString.Append("</xml>");

            return parsString.ToString();
        }

        /// <summary>
        /// Converts the specified set of parameters to the POST data string.
        /// </summary>
        /// <param name = "pars"> set of parameters to be converted. </ Param>
        The POST data string /// <returns> return conversion. </ Returns>
        public static string ParametersToPostDataString(Dictionary<string, string> pars)
        {
            StringBuilder postDataString = new StringBuilder();

            int i = 0;

            foreach (string key in pars.Keys)
            {
                if (i > 0)
                    postDataString.Append("&");

                postDataString.AppendFormat("{0}={1}", key, System.Web.HttpUtility.UrlEncode(pars[key]));

                i++;
            }

            return postDataString.ToString();
        }

        /// <summary>
        /// direction of the string AES encryption AES decryption.
        /// </summary>
        /// <param name = "decryptStr"> character string to be decrypted. </ Param>
        /// <param name="key">AES解密Key。</param>
        /// <returns> Returns a string decrypted. </ Returns>
        public static string AESDecrypt(string decryptStr, string key)
        {
            byte[] keyByte = Encoding.UTF8.GetBytes(key);

            byte[] encryptByte = Convert.FromBase64String(decryptStr);

            RijndaelManaged rijndaelManaged = new RijndaelManaged();

            rijndaelManaged.Key = keyByte;

            rijndaelManaged.Mode = CipherMode.ECB;

            rijndaelManaged.Padding = PaddingMode.PKCS7;

            ICryptoTransform cryptoTransform = rijndaelManaged.CreateDecryptor();

            byte[] resultByte = cryptoTransform.TransformFinalBlock(encryptByte, 0, encryptByte.Length);

            return Encoding.UTF8.GetString(resultByte);
        }

        /// <summary>
        /// RSA2 encryption algorithm using a string.
        /// </summary>
        /// <param name = "str"> character string to be encrypted. </ Param>
        /// <param name = "privateKey"> encrypted private keys. </ Param>
        /// <returns> succeed the serial number of the CRT certificate of return, otherwise return null. </ Returns>
        private static string RSA2Encrypt(string str, string privateKey)
        {
            RSACryptoServiceProvider rsaCrypto = GetRSACryptoFromPrivateKey(privateKey);

            return Convert.ToBase64String(rsaCrypto.SignData(Encoding.UTF8.GetBytes(str), "SHA256"));
        }

        /// <summary>
        /// Gets an object from the RSA encryption RSA private keys strings.
        /// </summary>
        /// <param name = "privateKey"> private secret key string. </ Param>
        /// <returns> Returns RSA encryption target acquired. </ Returns>
        private static RSACryptoServiceProvider GetRSACryptoFromPrivateKey(string privateKey)
        {
            byte[] modulus, exponent, d, p, q, dp, dq, inverseQ;

            MemoryStream memoryStream = new MemoryStream(Convert.FromBase64String(privateKey));

            BinaryReader binaryReader = new BinaryReader(memoryStream);

            switch (binaryReader.ReadUInt16())
            {
                case 0x8130:
                    binaryReader.ReadByte();
                    break;
                case 0x8230:
                    binaryReader.ReadInt16();
                    break;
            }

            if (binaryReader.ReadUInt16() != 0x0102)
                return null;

            if (binaryReader.ReadByte() != 0x00)
                return null;

            int elementCount = GetIntegerSize(binaryReader);
            modulus = binaryReader.ReadBytes(elementCount);

            elementCount = GetIntegerSize(binaryReader);
            exponent = binaryReader.ReadBytes(elementCount);

            elementCount = GetIntegerSize(binaryReader);
            d = binaryReader.ReadBytes(elementCount);

            elementCount = GetIntegerSize(binaryReader);
            p = binaryReader.ReadBytes(elementCount);

            elementCount = GetIntegerSize(binaryReader);
            q = binaryReader.ReadBytes(elementCount);

            elementCount = GetIntegerSize(binaryReader);
            dp = binaryReader.ReadBytes(elementCount);

            elementCount = GetIntegerSize(binaryReader);
            dq = binaryReader.ReadBytes(elementCount);

            elementCount = GetIntegerSize(binaryReader);
            inverseQ = binaryReader.ReadBytes(elementCount);

            CspParameters cspParameters = new CspParameters();

            cspParameters.Flags = CspProviderFlags.UseMachineKeyStore;

            RSACryptoServiceProvider rsaCrypto = new RSACryptoServiceProvider(2048, cspParameters);

            RSAParameters rsaParams = new RSAParameters();

            rsaParams.Modulus = modulus;
            rsaParams.Exponent = exponent;
            rsaParams.D = d;
            rsaParams.P = p;
            rsaParams.Q = q;
            rsaParams.DP = dp;
            rsaParams.DQ = dq;
            rsaParams.InverseQ = inverseQ;

            rsaCrypto.ImportParameters (rsaParams);

            return rsaCrypto;
        }

        /// <summary>
        /// Get the next byte length of a substantial portion.
        /// </summary>
        /// <param name = "binaryReader"> Binary Reader. </ Param>
        /// <returns> Returns the next byte length of a basic portion. </ Returns>
        private static int GetIntegerSize(BinaryReader binaryReader)
        {
            byte byteValue = 0;
            byte lowByte = 0x00;
            byte highByte = 0x00;
            int count = 0;

            byteValue = binaryReader.ReadByte();

            if (byteValue != 0x02)
                return 0;

            byteValue = binaryReader.ReadByte();

            if (byteValue == 0x81)
            {
                count = binaryReader.ReadByte();
            }
            else
            {
                if (byteValue == 0x82)
                {
                    highByte = binaryReader.ReadByte();

                    lowByte = binaryReader.ReadByte();

                    byte[] modelInt = { lowByte, highByte, 0x00, 0x00 };

                    count = BitConverter.ToInt32(modelInt, 0);
                }
                else
                {
                    count = byteValue;
                }
            }

            while (binaryReader.ReadByte() == 0x00)
            {
                count -= 1;
            }

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

            return count;
        }

        /// <summary>
        /// Gets the serial number CRT root certificate.
        /// </summary>
        /// <param name = "rootCertPath"> root certificate path. </ Param>
        /// <returns> Returns the root certificate serial number. </ Returns>
        public static string GetRootCertSN(string rootCertPath)
        {
            List<List<byte>> allCertByte = new List<List<byte>>();
            string beginText = "-----BEGIN CERTIFICATE-----";
            string endText = "-----END CERTIFICATE-----";
            Encoding encoding = Encoding.UTF8;

            using (StreamReader streamRead = new StreamReader(rootCertPath, encoding))
            {
                List<byte> bytes = null;

                while (!streamRead.EndOfStream)
                {
                    string lineText = streamRead.ReadLine();

                    if (lineText.StartsWith(beginText))
                    {
                        bytes = new List<byte>();

                        allCertByte.Add(bytes);

                        if (lineText.Length > beginText.Length)
                            bytes.AddRange(encoding.GetBytes(lineText.Replace(beginText, "").Trim()));
                    }
                    else if (!lineText.StartsWith(endText))
                    {
                        bytes.AddRange(encoding.GetBytes(lineText.Trim()));
                    }
                }
            }

            StringBuilder resultSN = new StringBuilder();

            int index = 0;

            foreach (List<byte> item in allCertByte)
            {
                X509Certificate2 certificate = new X509Certificate2(item.ToArray());

                if (certificate.SignatureAlgorithm.Value.StartsWith("1.2.840.113549.1.1"))
                {
                    if (index > 0)
                        resultSN.Append("_");

                    resultSN.Append(GetCertSN(certificate));

                    index++;
                }
            }

            return resultSN.ToString();
        }

        /// <summary>
        /// obtain the serial number specified CRT certificate file.
        /// </summary>
        /// <param name = "certPath"> certification path. </ Param>
        /// <returns> Returns the certificate serial number. </ Returns>
        public static string GetCertSN(string certPath)
        {
            return GetCertSN(new X509Certificate2(certPath));
        }

        /// <summary>
        /// obtain the serial number specified CRT certificate.
        /// </summary>
        /// <param name = "cert"> certificate object. </ Param>
        /// <returns> Returns the certificate serial number. </ Returns>
        private static string GetCertSN(X509Certificate2 cert)
        {
            string issuerName = new Regex(@"\, +C=").Replace(new Regex(@"\, +O=").Replace(new Regex(@"\, +OU=").Replace(cert.IssuerName.Name, ",OU="), ",O="), ",C=");

            return MD5Encrypt(issuerName + System.Numerics.BigInteger.Parse(string.Format("0{0}", cert.SerialNumber), System.Globalization.NumberStyles.AllowHexSpecifier), Encoding.UTF8, null).ToLower();
        }
    }
}

  

Code is an offer users on CSDN, the original link: https: //blog.csdn.net/aaa907638015/article/details/101246654

 

Guess you like

Origin www.cnblogs.com/xlhblogs/p/11724978.html