前段时间做的银联支付,折腾了好久,拼凑的一些代码,有需要的朋友可以参考,本人.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 Csharp),3DES加密解密,RSA加密解密,RSA私钥加密公钥解密,.Net RSA 3DES C#的更多相关文章

  1. NetCore 生成RSA公私钥对,公钥加密私钥解密,私钥加密公钥解密

    using Newtonsoft.Json; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Encodings; using ...

  2. RSA 加密算法 Java 公钥加密私钥解密 和 私钥加密公钥解密 的特点

    package com.smt.cipher.unsymmetry; import org.apache.commons.codec.binary.Base64; import org.apache. ...

  3. base64,AES,RSA,SHA和MD5等加密方式(jdk)

    import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; import javax.crypto.Cipher; import jav ...

  4. RSA加解密工具类RSAUtils.java,实现公钥加密私钥解密和私钥解密公钥解密

    package com.geostar.gfstack.cas.util; import org.apache.commons.codec.binary.Base64; import javax.cr ...

  5. 可用的 .net core 支持 RSA 私钥加密工具类

    首先说明 MS并不建议私钥加密,而且.net 于安全的考虑,RSACryptoServiceProvider类解密时只有同时拥有公钥和私钥才可以,原因是公钥是公开的,会被多人持有,这样的数据传输是不安 ...

  6. RSA不限长度非对称加密解密C#

    RSA 分段加解密[解决“不正确的长度”的异常] RSA 是常用的非对称加密算法.最近使用时却出现了“不正确的长度”的异常,研究发现是由于待加密的数据超长所致. .NET Framework 中提供的 ...

  7. C# 与JAVA 的RSA 加密解密交互,互通,C#使用BouncyCastle来实现私钥加密,公钥解密的方法

    因为C#的RSA加密解密只有公钥加密,私钥解密,没有私钥加密,公钥解密.在网上查了很久也没有很好的实现.BouncyCastle的文档少之又少.很多人可能会说,C#也是可以的,通过Biginteger ...

  8. C# 加密–RSA前端与后台的加密&解密

    1. 前言 本问是根据网上很多文章的总结得到的. 2. 介绍 RSA加密算法是一种非对称加密算法. 对极大整数做因数分解的难度决定了RSA算法的可靠性.换言之,对一极大整数做因数分解愈困难,RSA算法 ...

  9. 加密–RSA前端与后台的加密&解密

    1. 前言 本问是根据网上很多文章的总结得到的. 2. 介绍 RSA加密算法是一种非对称加密算法. 对极大整数做因数分解的难度决定了RSA算法的可靠性.换言之,对一极大整数做因数分解愈困难,RSA算法 ...

随机推荐

  1. 小知识 Vector的枚举 和foreach的用法

    package com.java.c.votetor.www; import java.util.Enumeration;import java.util.Iterator;import java.u ...

  2. 批量翻转PNG图片

    用了好几个软件都不好用. 要么不能翻转PNG, 要么翻转之后没有透明度了. 基本上全是图形界面, 要鼠标批量拖放. 所以, 还是自己动手, 写一个批量png翻转工具. #include <ios ...

  3. MVVM模式应用 之的RelayCommand的使用

    实现MVVM模式Command是立下了汗马功劳.当然ICommand要引用using System.Windows.Input命名空间. 比如: (1)我们在xaml页面有一个Button按钮,我们需 ...

  4. 更改css element.style

    样式后面加 !important就可以更改element.style的优先级了

  5. 2、Python djang 框架下的word Excel TXT Image 等文件的下载

    2.python实现文件下载 (1)方法一.直接用a标签的href+数据库中文件地址,即可下载.缺点:word excel是直接弹框下载,对于image txt 等文件的下载方式是直接在新页面打开. ...

  6. 设置服务器远程连接mysql

    一直单人开发所以没有考虑过这方面,到新公司要做合作开发,所以要进行设置,然后开始自己搞 下面把过程罗列一下: 1)由于使用的云服务器 ,所以上面都配置好了,直接配置了mysql的命令行输入密码就可以进 ...

  7. JSOP

    说到 JSONP 就要说到同源策略(Same Origin Policy), 同源策略是浏览器最核心的也是最基本的安全功能. 浏览器的同源策略,限制了来自不同源的 “document” 或脚本,对当前 ...

  8. Contest20140710 loop bellman-ford求负环&&0/1分数规划

    loop|loop.in|loop.out 题目描述: 给出一个有向带权图,权为边权,求一个简单回路,使其平均边权最小. 简单回路指不多次经过同一个点的回路. 输入格式: 第一行两个整数,表示图的点数 ...

  9. [BZOJ 1040] [ZJOI2008] 骑士 【基环+外向树DP】

    题目链接:BZOJ - 1040 题目分析 这道题目的模型就是一个图,不一定联通,每个连通块的点数等于边数. 每个连通块都是一个基环+外向树.即树上增加了一条边. 如果是树,就可以直接树形DP了.然而 ...

  10. android ADT Bundle for Mac下载地址

    直接下载解压就能用 http://developer.android.com/sdk/index.html