银联手机支付(.Net Csharp),3DES加密解密,RSA加密解密,RSA私钥加密公钥解密,.Net RSA 3DES C#

前段时间做的银联支付,折腾了好久,拼凑的一些代码,有需要的朋友可以参考,本人.Net新手,不保证准确性!

这个银联手机支付没有SDK提供,技术支持也没有.Net的,真心不好搞!

RSA加解密,这里有个麻烦就是私钥加密/公钥解密;

3DES加解密,这里有个问题是所用的密钥长度不一样,银联向我们发送报文时密钥用32字节长度的,我们.Net最多用24字节,办法是直接取密钥前24字节就行了;

 

下面是RSA算法的加解密,用到一个BigInteger类(http://www.codeproject.com/csharp/biginteger.asp):

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Security.Cryptography.X509Certificates;

using System.Security.Cryptography;



namespace Kad.ThridParty.ChinaPayWap

{

    /// <summary>

    /// 非对称RSA加解密,私钥加密/公钥解密

    /// 仅用于银联Wap支付报文收发

    /// By : EnVon(E旺) 2013-08-20

    /// </summary>

    internal class RSAHelper

    {



        /// <summary>

        /// RSA加密(用私钥加密哟)

        /// </summary>

        /// <param name="key">私钥</param>

        /// <param name="data">待加密的数据</param>

        /// <returns></returns>

        public static byte[] Encrypt(String key, byte[] data)

        {

            //由密钥xml取得RSA对象

            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();

            rsa.FromXmlString(key);

            //取得加密时使用的2个参数

            RSAParameters par = rsa.ExportParameters(true);

            BigInteger mod = new BigInteger(par.Modulus);

            BigInteger ep = new BigInteger(par.D);

            //计算填充长度

            int mLen = par.Modulus.Length;

            int fLen = mLen - data.Length - 3;

            //组建bytes

            List<byte> lis = new List<byte>();

            lis.Add(0x00);

            lis.Add(0x01);//兼容java

            for (int i = 0; i < fLen; i++) lis.Add(0xff);

            lis.Add(0x00);

            lis.AddRange(data);

            byte[] bytes = lis.ToArray();

            //加密就这么简单?

            BigInteger m = new BigInteger(bytes);

            BigInteger c = m.modPow(ep, mod);

            return c.getBytes();

        }





        /// <summary>

        /// RSA解密(用公钥解密哟)

        /// </summary>

        /// <param name="key">公钥</param>

        /// <param name="data">待解密的数据</param>

        /// <returns></returns>

        public static byte[] Decrypt(String key, byte[] data)

        {

            //由密钥xml取得RSA对象

            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();

            rsa.FromXmlString(key);

            //取得解密时使用的2个参数

            RSAParameters par = rsa.ExportParameters(false);

            BigInteger mod = new BigInteger(par.Modulus);

            BigInteger ep = new BigInteger(par.Exponent);

            //解密?

            BigInteger m = new BigInteger(data);

            BigInteger c = m.modPow(ep, mod);

            byte[] bytes = c.getBytes();

            //去掉填充域(头部可能填充了一段0xff)

            byte flag = 0;

            for (int i = 1/*我从1开始啦*/; i < bytes.Length; i++)

            {

                if (bytes[i] == flag && i != (bytes.Length - 1))

                {

                    byte[] retBytes = new byte[bytes.Length - i - 1];

                    Array.Copy(bytes, i + 1, retBytes, 0, retBytes.Length);

                    return retBytes;

                }

            }

            return bytes;

        }





        /// <summary>

        /// 取得证书私钥

        /// </summary>

        /// <param name="pfxPath">证书的绝对路径</param>

        /// <param name="password">访问证书的密码</param>

        /// <returns></returns>

        public static String GetPrivateKey(string pfxPath, string password)

        {

            X509Certificate2 pfx = new X509Certificate2(pfxPath, password, X509KeyStorageFlags.Exportable);

            string privateKey = pfx.PrivateKey.ToXmlString(true);

            return privateKey;

        }





        /// <summary>

        /// 取得证书的公钥

        /// </summary>

        /// <param name="cerPath">证书的绝对路径</param>

        /// <returns></returns>

        public static String GetPublicKey(string cerPath)

        {

            X509Certificate2 cer = new X509Certificate2(cerPath);

            string publicKey = cer.PublicKey.Key.ToXmlString(false);

            return publicKey;

        }



    }

}


 

下面是3DES的代码:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Security.Cryptography;



namespace Kad.ThridParty.ChinaPayWap

{

    /// <summary>

    /// 对称加密3DES加解密,代码来源于网络

    /// </summary>

    internal class TripleDESHelper

    {



        /// <summary>

        /// 加密

        /// </summary>

        /// <param name="toEncrypt">要加密的字符串,即明文</param>

        /// <param name="key">公共密钥</param>

        /// <param name="useHashing">是否使用MD5生成机密秘钥</param>

        /// <returns>加密后的字符串,即密文</returns>

        public static string Encrypt(string toEncrypt, string key, bool useHashing)

        {

            try

            {

                byte[] keyArray;

                byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);



                if (useHashing)

                {

                    MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();

                    keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));

                }

                else

                    keyArray = UTF8Encoding.UTF8.GetBytes(key);



                TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();



                tdes.Key = keyArray;

                tdes.Mode = CipherMode.ECB;

                tdes.Padding = PaddingMode.PKCS7;



                ICryptoTransform cTransform = tdes.CreateEncryptor();

                byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);



                return Convert.ToBase64String(resultArray, 0, resultArray.Length);

            }

            catch

            {



            }

            return string.Empty;

        }

        public static string Encrypt(byte[] toEncryptArray, string key, bool useHashing)

        {

            try

            {

                byte[] keyArray;

                //byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);



                if (useHashing)

                {

                    MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();

                    keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));

                }

                else

                    keyArray = UTF8Encoding.UTF8.GetBytes(key);



                TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();



                tdes.Key = keyArray;

                tdes.Mode = CipherMode.ECB;

                tdes.Padding = PaddingMode.PKCS7;



                ICryptoTransform cTransform = tdes.CreateEncryptor();

                byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);



                return Convert.ToBase64String(resultArray, 0, resultArray.Length);

            }

            catch

            {



            }

            return string.Empty;

        }



        /// <summary>

        /// 解密

        /// </summary>

        /// <param name="toDecrypt">要解密的字符串,即密文</param>

        /// <param name="key">公共密钥</param>

        /// <param name="useHashing">是否使用MD5生成机密密钥</param>

        /// <returns>解密后的字符串,即明文</returns>

        public static string Decrypt(string toDecrypt, string key, bool useHashing)

        {

            try

            {

                byte[] keyArray;

                byte[] toEncryptArray = Convert.FromBase64String(toDecrypt);



                if (useHashing)

                {

                    MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();

                    keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));

                }

                else

                    keyArray = UTF8Encoding.UTF8.GetBytes(key);



                TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();

                tdes.Key = keyArray;

                tdes.Mode = CipherMode.ECB;

                tdes.Padding = PaddingMode.PKCS7;



                ICryptoTransform cTransform = tdes.CreateDecryptor();

                byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);



                return UTF8Encoding.UTF8.GetString(resultArray);



            }

            catch

            {



            }

            return string.Empty;

        }

        public static string Decrypt(byte[] toEncryptArray, string key, bool useHashing)

        {

            try

            {

                byte[] keyArray;

                //byte[] toEncryptArray = Convert.FromBase64String(toDecrypt);



                if (useHashing)

                {

                    MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();

                    keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));

                }

                else

                    keyArray = UTF8Encoding.UTF8.GetBytes(key);



                TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();

                tdes.Key = keyArray;

                tdes.Mode = CipherMode.ECB;

                tdes.Padding = PaddingMode.PKCS7;



                ICryptoTransform cTransform = tdes.CreateDecryptor();

                byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);



                return UTF8Encoding.UTF8.GetString(resultArray);



            }

            catch

            {



            }

            return string.Empty;

        }



    }

}


 

 

 

 

你可能感兴趣的:(.net)