• 银联手机支付(.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;
            }
    
        }
    }
    


     

  • 相关阅读:
    【转】使用外部看门狗请三思!
    【转】一招解决MCU启动异常
    【转】电源芯片选型,容易忽略的“QC”
    【转】为什么 MQTT 是最适合物联网的网络协议
    【转】中国芯酸往事
    函数输入参数类型为枚举时,则限定函数参数的接收范围,非枚举值输入则错误
    函数形参为指针与非指针的区别
    【转】函数中的形参问题(指针形参、引用形参、二重指针作为形参)
    【转】Example of using the --info linker option
    【转】STM32
  • 原文地址:https://www.cnblogs.com/riskyer/p/3356210.html
Copyright © 2020-2023  润新知