前段时间做的银联支付,折腾了好久,拼凑的一些代码,有需要的朋友可以参考,本人.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. Javascript实现图片库效果

    思路: 无序列表加载图片文件.用img标签加载一张图片作为占位符.当点击照片链接时,改变<a>元素的href属性.并且阻止浏览器的默认行为. 动态改变描述文字,在图片下方增加P标签.通过获 ...

  2. 复选框字段数组拆分后循环选项值,if判断根据选项值,前端输出html

    {php $specials = explode(',',$r[special]);} <div class="special"> {loop $specials $s ...

  3. LPC1114

    时钟配置: 3个时钟源:系统振荡源(system),IRC振荡源,(IRC,内部RC振荡器)看门狗振荡源(WatchDog) MAINCLKSEL:主时钟源选择寄存器(复位值:0) 只用了前两位: 0 ...

  4. JS实现继承多态

    //类对象构造模版,无new访问,类似静态访问 var Class = { create: function () { return function () { //initialize初始化 //a ...

  5. LightOj_1265 Island of Survival

    题目链接 题意: 在孤岛生存, 孤岛上有t头老虎,d头鹿, 每天会出现随机出现两只生物(包括你自己), 如果出现了一只老虎,那么你将被吃掉, 如果两只老虎, 则两只老虎会同归于尽,其他情况你都将生存下 ...

  6. Codeforces Round #313 (Div. 2)

    大半年没有打Codeforces , 昨天开始恢复打Codeforces, 简直是, 欲语泪先流啊. 手残到爆的写错了范围, 手残的数漏了条件, 简直不能直视, 最坑爹的是, E题没时间写代码了. 题 ...

  7. 应用git(SSH设置)

    git配置完成email和user后,才可以生成SSH Key. $ git config --global user.name "自定义名称" $ git config --gl ...

  8. wcf安全

    http://www.cnblogs.com/artech/archive/2011/07/07/customauthorization01.html 安全 http://www.cnblogs.co ...

  9. BZOJ 2754: [SCOI2012]喵星球上的点名

    2754: [SCOI2012]喵星球上的点名 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 649  Solved: 305[Submit][Sta ...

  10. In machine learning, is more data always better than better algorithms?

    In machine learning, is more data always better than better algorithms? No. There are times when mor ...