银联手机支付(.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 Csharp),3DES加密解密,RSA加密解密,RSA私钥加密公钥解密,.Net RSA 3DES C#的更多相关文章
- NetCore 生成RSA公私钥对,公钥加密私钥解密,私钥加密公钥解密
using Newtonsoft.Json; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Encodings; using ...
- RSA 加密算法 Java 公钥加密私钥解密 和 私钥加密公钥解密 的特点
package com.smt.cipher.unsymmetry; import org.apache.commons.codec.binary.Base64; import org.apache. ...
- base64,AES,RSA,SHA和MD5等加密方式(jdk)
import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; import javax.crypto.Cipher; import jav ...
- RSA加解密工具类RSAUtils.java,实现公钥加密私钥解密和私钥解密公钥解密
package com.geostar.gfstack.cas.util; import org.apache.commons.codec.binary.Base64; import javax.cr ...
- 可用的 .net core 支持 RSA 私钥加密工具类
首先说明 MS并不建议私钥加密,而且.net 于安全的考虑,RSACryptoServiceProvider类解密时只有同时拥有公钥和私钥才可以,原因是公钥是公开的,会被多人持有,这样的数据传输是不安 ...
- RSA不限长度非对称加密解密C#
RSA 分段加解密[解决“不正确的长度”的异常] RSA 是常用的非对称加密算法.最近使用时却出现了“不正确的长度”的异常,研究发现是由于待加密的数据超长所致. .NET Framework 中提供的 ...
- C# 与JAVA 的RSA 加密解密交互,互通,C#使用BouncyCastle来实现私钥加密,公钥解密的方法
因为C#的RSA加密解密只有公钥加密,私钥解密,没有私钥加密,公钥解密.在网上查了很久也没有很好的实现.BouncyCastle的文档少之又少.很多人可能会说,C#也是可以的,通过Biginteger ...
- C# 加密–RSA前端与后台的加密&解密
1. 前言 本问是根据网上很多文章的总结得到的. 2. 介绍 RSA加密算法是一种非对称加密算法. 对极大整数做因数分解的难度决定了RSA算法的可靠性.换言之,对一极大整数做因数分解愈困难,RSA算法 ...
- 加密–RSA前端与后台的加密&解密
1. 前言 本问是根据网上很多文章的总结得到的. 2. 介绍 RSA加密算法是一种非对称加密算法. 对极大整数做因数分解的难度决定了RSA算法的可靠性.换言之,对一极大整数做因数分解愈困难,RSA算法 ...
随机推荐
- PHP 学习笔记 (四)
Wordpress 框架中的一些函数: wp_get_nav_menu($default): 根据条件$default 获取menu, 默认获取所有的menu 其中 $default 默认如下所示: ...
- 3D Game Programming with directx 11 习题答案 8.2
第八章 第二题 1.首先找到Directx Texture Tool,它位于 2.填入配置 3.用画图工具画好每个level的图片,例如level0 4.用Directx Texture Tool添加 ...
- C#程序中:如何启用进程、结束进程、查找进程
在启动某个程序之前,如果需要先检查改程序是否已经运行,可以查找进程里有没有这个进程,再根据查找进程后的结果进行相应的判断操作. 产找进程的范围是任务管理器中的进程列表.如果进程被隐藏了,结果……(我没 ...
- jQuery动态添加的元素中处理字符串溢出后在指定字符数后添加省略号
"+[jsonData[i].questitle.lenth>40?jsonData[i].questitle.substring(0,40)+"...":json ...
- 研究在SAE上搭建最新wordpress
安装SAE上的wordpress,创建应用选择wordpress模板,安装后是3.4版本 新建一个版本2,下载最新wordpress安装包并解压到版本2中 初步猜想修改地方: 数据库配置:wp-con ...
- GoogleCode新手教程
GoogleCode页面介绍 Project Home 首先显示的是project home,页面左边的是这个项目的介绍,右边的License是说明使用的是什么开源协议,Labels是标签的意思,就是 ...
- swift官方文档中的函数闭包是怎么理解的?
官方文档中的16页: numbers.map({ (number: Int) -> Int in let result = * number return result }) 不知道这个怎么用, ...
- Python正则表达式2
- VS下面的编译错误-----转换到 COFF 期间失败: 文件无效或损坏
最近写了一个vs的小项目,然后编译的时候vs提示了"转换到 COFF 期间失败: 文件无效或损坏"的问题. 去网上搜索了一个解决方案.原作者的链接是:http://jingyan. ...
- css3实现无缝滚动效果
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...