银联手机支付(.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算法 ...
随机推荐
- Graphics类绘制图形
1. 画直线 void drawLine(int startX,int startY,int endX,int endY); 四个参数分别为:起始点的x坐标和y坐标以及终点的x坐标和y坐标,该方法用于 ...
- ios专题 - CocoaPods - 安装
职业走得很累,停下来,温故技术.顺便开始我得ios博客文章. [原创]http://www.cnblogs.com/luoguoqiang1985 安装 第一步:执行以下命令 sudo gem ins ...
- 算法专题训练 搜索a-T3 Ni骑士(ni)
搞了半天八数码弄不出来就只好来打题解 这道题是在搜索a碰到的(链接: http://pan.baidu.com/s/1jG9rQsQ ) 感觉题目最大亮点就是这英文简写"ni", ...
- 桂电在线-php-提取菜单到配置文件2
继续昨晚没完成的主菜单模板: <!-- 菜单块 --> <div class="on-light" id="menus"> <?p ...
- 使用php发送电子邮件(phpmailer)
在项目开发过程中,经常会用到通过程序发送电子邮件,例如:注册用户通过邮件激活,通过邮件找回密码,发送报表等.这里介绍几种通过PHP发送电子邮件的 方式(1)通过mail()函数发送邮件(2)使用fso ...
- 移动端消除click事件的延迟效果
https://github.com/Plaputta/jquery.event.special.fastclick 用fastclick事件,类似zepto的tap事件,若想去除连点效果,可在外层显 ...
- python【第十一篇】消息队列RabbitMQ、缓存数据库Redis
大纲 1.RabbitMQ 2.Redis 1.RabbitMQ消息队列 1.1 RabbitMQ简介 AMQP,即Advanced Message Queuing Protocol,高级消息队列协议 ...
- uboot的mtd功能支持
一.概述 1.MTD MTD是Flash的一种管理方法,将Flash划分成几个分区,便于管理. u-boot的MTD功能是在文件cmd_jffs2.c中实现的,由此我们可以知道怎样打开u-boot的M ...
- ”ENV_IS_EMBEDDED“解惑以及相关的移植实验
一.概述( ENV_IS_EMBEDDED的目的) 经典资料 认识 ENV_IS_EMBEDDED只有在CFG_ENV_IS_IN_FLASH或者CFG_ENV_IS_IN_NAND定义了才有 ...
- babun,windows shell
babun是windows上的一个第三方shell,在这个shell上面你可以使用几乎所有linux,unix上面的命令,他几乎可以取代windows的shell. babun的几个特点: 使用bab ...