马大波 1 year ago
commit
a3249d47ac
5 changed files with 555 additions and 0 deletions
  1. 26 0
      .gitignore
  2. 59 0
      Program.cs
  3. 335 0
      RSAUtil.cs
  4. 135 0
      TransactionResultDTO.cs
  5. BIN
      lib/BouncyCastle.Crypto.dll

+ 26 - 0
.gitignore

@@ -0,0 +1,26 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+stats.html

+ 59 - 0
Program.cs

@@ -0,0 +1,59 @@
+using System;
+using System.Text;
+using System.Runtime.Serialization.Json;
+using System.IO;
+
+namespace RSAUtility
+{
+    class Program
+    {
+        private static String PUBLIC_KEY = @"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzw1Ib0qlD3ynCPLMUAqE2fkzeXuV5YLAyHtd/Gw8gPMeRWea9caentQpK5k4VFHjCP1LPmWlK7tsyi/9KYbRtK9/Gpasja0qSC1M/ZH6pJZZp81DWiGzQ8gAZ8YVp9+sW6eaH4CvDqCBeMSOTw3VS5yq7ArENbgIcSzCC05fZDwIDAQAB";
+
+        static void Main(string[] args)
+        {
+            
+            //定义对象
+            TransactionResultDTO trans = new TransactionResultDTO();
+            trans.setPartnerRefNo("486595880571");
+            trans.setMerchantShortCode("8810002");
+            trans.setMerchant("oway");
+            trans.setAmount(0.01);
+            trans.setCurrency("MMK");
+            trans.setFee(0.0);
+            trans.setGoods("bus");
+            trans.setBackURL(@"http://dev.meemee.online:8080");
+
+            //转换Json
+            MemoryStream ms = new MemoryStream();
+            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(TransactionResultDTO));
+            ser.WriteObject(ms, trans);
+
+            ms.Position = 0;
+
+            string jsonString;
+
+            using (StreamReader sr = new StreamReader(ms))
+            {
+                jsonString = sr.ReadToEnd().Replace("\\", "");
+            }
+            ms.Close();
+
+
+            Console.WriteLine("Json String:\n" + jsonString +"\n");
+
+            //加解密
+            RSAUtil rsa = new RSAUtil();
+
+            //公钥加密
+            string encryptResult = rsa.EncryptByPublicKey(jsonString, PUBLIC_KEY);
+
+            Console.WriteLine("Public Key Encrypt Result:\n"+encryptResult+"\n");
+
+            string cipherText = @"SkZzWUg0cTJQVkhnUURLMG84UWFrd3hYc2MyMHBOY3RYZlJNb3ZmMkR3dno5THU2VmJvaEhDN1Nkck14ZlZhd3NyN3JTOHY0M3JHVQ0KQVRlbVVHZWtRMVBwTUxlKzhEempiT1BldlJoRVpvMCsrcUJWcFJaWnNuUUd1aVJWZTllMXNSTi9tait1S2R3eHhMZ3U4Z3MzNk1tcA0KNFAwT3c1WDdDTXc5OVhSTGJOWjN3QncyZC9iTXNxTVM5Sjh1RDZOdmJmeHNlN0dkUUI2YWdRWGkyNEpmRytlVzEvNzZrQkdyKzhPVA0Kd1dTUG1FVER0YVZva3IrcE50KzEzZjVISUtGZTJKVDhMZW1RZTNmOE1kYkVGeHVhRGw2SE96WXlNeGRBR2NyMWNQREQ3ZWg4NkQ1Vw0KSDRtQVRMTDczQ1puTVhhMnpnbDd2YnUxWGpqdU1udkNRR3BIWUE9PQ==";
+            //公钥解密
+            string plainText = rsa.DecryptByPublicKey(cipherText, PUBLIC_KEY);
+            Console.WriteLine("Public Key Decrypt Result:\n" + plainText+"\n");
+
+        }
+    }
+}

+ 335 - 0
RSAUtil.cs

@@ -0,0 +1,335 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Crypto.Generators;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Pkcs;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Crypto.Engines;
+using Org.BouncyCastle.X509;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Crypto.Encodings;
+
+
+namespace RSAUtility
+{
+    public class RSAUtil
+    {
+        private static Encoding Encoding_UTF8 = Encoding.UTF8;
+
+        /// <summary>
+        /// KEY 结构体
+        /// </summary>
+        public struct RSAKEY
+        {
+            /// <summary>
+            /// 公钥
+            /// </summary>
+            public string PublicKey
+            {
+                get;
+                set;
+            }
+            /// <summary>
+            /// 私钥
+            /// </summary>
+            public string PrivateKey
+            {
+                get;
+                set;
+            }
+
+        }
+        public RSAKEY GetKey()
+        {
+            //RSA密钥对的构造器  
+            RsaKeyPairGenerator keyGenerator = new RsaKeyPairGenerator();
+
+            //RSA密钥构造器的参数  
+            RsaKeyGenerationParameters param = new RsaKeyGenerationParameters(
+                Org.BouncyCastle.Math.BigInteger.ValueOf(3),
+                new Org.BouncyCastle.Security.SecureRandom(),
+                1024,   //密钥长度  
+                25);
+            //用参数初始化密钥构造器  
+            keyGenerator.Init(param);
+            //产生密钥对  
+            AsymmetricCipherKeyPair keyPair = keyGenerator.GenerateKeyPair();
+            //获取公钥和密钥  
+            AsymmetricKeyParameter publicKey = keyPair.Public;
+            AsymmetricKeyParameter privateKey = keyPair.Private;
+
+            SubjectPublicKeyInfo subjectPublicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey);
+            PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKey);
+
+
+            Asn1Object asn1ObjectPublic = subjectPublicKeyInfo.ToAsn1Object();
+
+            byte[] publicInfoByte = asn1ObjectPublic.GetEncoded("UTF-8");
+            Asn1Object asn1ObjectPrivate = privateKeyInfo.ToAsn1Object();
+            byte[] privateInfoByte = asn1ObjectPrivate.GetEncoded("UTF-8");
+
+            RSAKEY item = new RSAKEY()
+            {
+                PublicKey = Convert.ToBase64String(publicInfoByte),
+                PrivateKey = Convert.ToBase64String(privateInfoByte)
+            };
+            return item;
+        }
+        private AsymmetricKeyParameter GetPublicKeyParameter(string keyBase64)
+        {
+            keyBase64 = keyBase64.Replace("\r", "").Replace("\n", "").Replace(" ", "");
+            byte[] publicInfoByte = Convert.FromBase64String(keyBase64);
+            Asn1Object pubKeyObj = Asn1Object.FromByteArray(publicInfoByte);//这里也可以从流中读取,从本地导入   
+            AsymmetricKeyParameter pubKey = PublicKeyFactory.CreateKey(publicInfoByte);
+            return pubKey;
+        }
+
+        private AsymmetricKeyParameter GetPrivateKeyParameter(string keyBase64)
+        {
+            keyBase64 = keyBase64.Replace("\r", "").Replace("\n", "").Replace(" ", "");
+            byte[] privateInfoByte = Convert.FromBase64String(keyBase64);
+            // Asn1Object priKeyObj = Asn1Object.FromByteArray(privateInfoByte);//这里也可以从流中读取,从本地导入   
+            // PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKey);
+            AsymmetricKeyParameter priKey = PrivateKeyFactory.CreateKey(privateInfoByte);
+            return priKey;
+        }
+
+        /// <summary>
+        /// 私钥加密
+        /// </summary>
+        /// <param name="data">加密内容</param>
+        /// <param name="privateKey">私钥(Base64后的)</param>
+        /// <returns>返回Base64内容</returns>
+        public string EncryptByPrivateKey(string data, string privateKey)
+        {
+            //非对称加密算法,加解密用  
+            IAsymmetricBlockCipher engine = new Pkcs1Encoding(new RsaEngine());
+
+            //加密
+            try
+            {
+                RsaPrivateCrtKeyParameters key = (RsaPrivateCrtKeyParameters)GetPrivateKeyParameter(privateKey);
+
+                engine.Init(true, key);
+
+                byte[] byteData = Encoding_UTF8.GetBytes(data);
+
+                int maxBlock = key.Modulus.BitLength / 8 - 11;
+
+
+                List<byte> resultData = new List<byte>();
+
+                //多次加密位置指示器
+                int offSet = 0;
+
+                for (int i = 0; byteData.Length > offSet; i++)
+                {
+
+                    byte[] tmpByte = new byte[] { };
+
+                    if (byteData.Length - offSet > maxBlock)
+                    {
+                        tmpByte = engine.ProcessBlock(byteData, offSet, maxBlock);
+                    }
+                    else
+                    {
+                        tmpByte = engine.ProcessBlock(byteData, offSet, byteData.Length - offSet);
+                    }
+                    offSet = maxBlock * (i + 1);
+                    //中间结果加入结果数组
+                    resultData.AddRange(tmpByte);
+                }
+
+                string cipherText = Convert.ToBase64String(
+                    Encoding.UTF8.GetBytes(
+                        Convert.ToBase64String(resultData.ToArray())));
+
+                return cipherText;
+            }
+            catch (Exception ex)
+            {
+                throw ex;
+            }
+        }
+
+        /// <summary>
+        /// 私钥解密
+        /// </summary>
+        /// <param name="data">待解密的内容</param>
+        /// <param name="privateKey">私钥(Base64编码后的)</param>
+        /// <returns>返回明文</returns>
+        public string DecryptByPrivateKey(string data, string privateKey)
+        {
+            data = data.Replace("\r", "").Replace("\n", "").Replace(" ", "");
+            //非对称加密算法,加解密用  
+            IAsymmetricBlockCipher engine = new Pkcs1Encoding(new RsaEngine());
+
+            //解密  
+            try
+            {
+                RsaPrivateCrtKeyParameters key = (RsaPrivateCrtKeyParameters)GetPrivateKeyParameter(privateKey);
+
+                engine.Init(false, key);
+
+                int maxBlock = key.Modulus.BitLength/8;
+                
+                //用于解密的原始数据,经过两次Base64解码
+                byte[] byteData = 
+                    Convert.FromBase64String(
+                        Encoding.UTF8.GetString(
+                            Convert.FromBase64String(data)));
+
+                List<byte> resultData = new List<byte>();
+
+                //多次加密位置指示器
+                int offSet = 0;
+
+                for (int i = 0;byteData.Length>offSet ;i++)
+                {
+                    
+                    byte[] tmpByte= new byte[] { };
+
+                    if (byteData.Length - offSet > maxBlock)
+                    {
+                        tmpByte= engine.ProcessBlock(byteData, offSet, maxBlock);
+                    }
+                    else
+                    {
+                        tmpByte=engine.ProcessBlock(byteData, offSet, byteData.Length - offSet);
+                    }
+                    offSet = maxBlock * (i+1);
+                    //中间结果加入结果数组
+                    resultData.AddRange(tmpByte);
+                }
+
+                return Encoding_UTF8.GetString(resultData.ToArray());
+            }
+            catch (Exception ex)
+            {
+                throw ex;
+            }
+        }
+
+        /// <summary>
+        /// 公钥加密
+        /// </summary>
+        /// <param name="data">加密内容</param>
+        /// <param name="publicKey">公钥(Base64编码后的)</param>
+        /// <returns>返回Base64内容</returns>
+        public string EncryptByPublicKey(string data, string publicKey)
+        {
+            //非对称加密算法,加解密用  
+            IAsymmetricBlockCipher engine = new Pkcs1Encoding(new RsaEngine());
+
+            //加密
+            try
+            {
+                RsaKeyParameters key = (RsaKeyParameters)GetPublicKeyParameter(publicKey);
+
+                engine.Init(true, key);
+
+                byte[] byteData = Encoding_UTF8.GetBytes(data);
+
+                int maxBlock = key.Modulus.BitLength / 8 - 11;
+
+
+                List<byte> resultData = new List<byte>();
+
+                //多次加密位置指示器
+                int offSet = 0;
+
+                for (int i = 0; byteData.Length > offSet; i++)
+                {
+
+                    byte[] tmpByte = new byte[] { };
+
+                    if (byteData.Length - offSet > maxBlock)
+                    {
+                        tmpByte = engine.ProcessBlock(byteData, offSet, maxBlock);
+                    }
+                    else
+                    {
+                        tmpByte = engine.ProcessBlock(byteData, offSet, byteData.Length - offSet);
+                    }
+                    offSet = maxBlock * (i + 1);
+                    //中间结果加入结果数组
+                    resultData.AddRange(tmpByte);
+                }
+
+                string cipherText = Convert.ToBase64String(
+                    Encoding.UTF8.GetBytes(
+                        Convert.ToBase64String(resultData.ToArray())));
+
+                return cipherText;
+            }
+            catch (Exception ex)
+            {
+                throw ex;
+            }
+        }
+
+        /// <summary>
+        /// 公钥解密
+        /// </summary>
+        /// <param name="data">待解密的内容</param>
+        /// <param name="publicKey">公钥(Base64编码后的)</param>
+        /// <returns>返回明文</returns>
+        public string DecryptByPublicKey(string data, string publicKey)
+        {
+            data = data.Replace("\r", "").Replace("\n", "").Replace(" ", "");
+            //非对称加密算法,加解密用  
+            IAsymmetricBlockCipher engine = new Pkcs1Encoding(new RsaEngine());
+
+            //解密  
+            try
+            {
+                RsaKeyParameters key = (RsaKeyParameters)GetPublicKeyParameter(publicKey);
+
+                engine.Init(false, key);
+
+                //用于解密的原始数据,经过两次Base64解码
+                byte[] byteData =
+                    Convert.FromBase64String(
+                        Encoding.UTF8.GetString(
+                            Convert.FromBase64String(data)));
+
+                int maxBlock = key.Modulus.BitLength / 8;
+
+                List<byte> resultData = new List<byte>();
+
+                //多次加密位置指示器
+                int offSet = 0;
+
+                for (int i = 0; byteData.Length > offSet; i++)
+                {
+
+                    byte[] tmpByte = new byte[] { };
+
+                    if (byteData.Length - offSet > maxBlock)
+                    {
+                        tmpByte = engine.ProcessBlock(byteData, offSet, maxBlock);
+                    }
+                    else
+                    {
+                        tmpByte = engine.ProcessBlock(byteData, offSet, byteData.Length - offSet);
+                    }
+                    offSet = maxBlock * (i + 1);
+                    //中间结果加入结果数组
+                    resultData.AddRange(tmpByte);
+                }
+
+                return Encoding_UTF8.GetString(resultData.ToArray());
+
+            }
+            catch (Exception ex)
+            {
+                throw ex;
+            }
+        }
+    }
+}

+ 135 - 0
TransactionResultDTO.cs

@@ -0,0 +1,135 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using System.Text;
+
+namespace RSAUtility
+{
+    [DataContract]
+    class TransactionResultDTO
+    {
+        /**
+     * Mpt交易ID
+     */[DataMember]
+        public String partnerRefNo { get; set; }
+        /**
+         * Merchant Short Code
+         */
+        [DataMember]
+        public String merchantShortCode { get; set; }
+        /**
+         * 货币类型
+         */
+        [DataMember]
+        public String currency { get; set; }
+        /**
+         * 单个交易金额
+         */
+        [DataMember]
+        public Double amount { get; set; }
+        /**
+         * 交易费
+         */
+        [DataMember]
+        public Double fee { get; set; }
+        /**
+         * 代理商名字
+         */
+        [DataMember]
+        public String merchant { get; set; }
+        /**
+         * 商品名称
+         */
+        [DataMember]
+        public String goods { get; set; }
+        /**
+         * 三方系统返回url
+         */
+        [DataMember]
+        public String backURL { get; set; }
+
+        public TransactionResultDTO()
+        {
+        }
+
+        public String getPartnerRefNo()
+        {
+            return partnerRefNo;
+        }
+
+        public void setPartnerRefNo(String partnerRefNo)
+        {
+            this.partnerRefNo = partnerRefNo;
+        }
+
+        public String getMerchantShortCode()
+        {
+            return merchantShortCode;
+        }
+
+        public void setMerchantShortCode(String merchantShortCode)
+        {
+            this.merchantShortCode = merchantShortCode;
+        }
+
+        public String getCurrency()
+        {
+            return currency;
+        }
+
+        public void setCurrency(String currency)
+        {
+            this.currency = currency;
+        }
+
+        public Double getAmount()
+        {
+            return amount;
+        }
+
+        public void setAmount(Double amount)
+        {
+            this.amount = amount;
+        }
+
+        public Double getFee()
+        {
+            return fee;
+        }
+
+        public void setFee(Double fee)
+        {
+            this.fee = fee;
+        }
+
+        public String getMerchant()
+        {
+            return merchant;
+        }
+
+        public void setMerchant(String merchant)
+        {
+            this.merchant = merchant;
+        }
+
+        public String getGoods()
+        {
+            return goods;
+        }
+
+        public void setGoods(String goods)
+        {
+            this.goods = goods;
+        }
+
+        public String getBackURL()
+        {
+            return backURL;
+        }
+
+        public void setBackURL(String backURL)
+        {
+            this.backURL = backURL;
+        }
+    }
+}

BIN
lib/BouncyCastle.Crypto.dll