本人菜鸟一枚,大学里凭兴趣学了一点WP的皮毛,后来又幸运(或者不幸)的进了一家专注于Windows生态的公司做了一段时间的UWP。在博客园写点自己遇到的东西,作为分享,也作为自己的备忘,如果有错误的地方,或者可以提升B格的地方,希望园子里的大神们不吝赐教。

初进公司时,公司要做支付相关的业务,需要和支付宝、优易付、爱贝等支付渠道对接,对新手的我来说,加密或者是签名简直难到死,学校里哪用过这个,OMG,只能迎着头皮找资料。

这里我想请教大家一个问题,就是如何学习。例如当你遇到一个陌生的东西,你是如何查找资料解决问题的?当我需要做加密的时候我的做法是打开百度搜索“WP 3des加密”,这样找出来的结果基本都不能用。。。后来终于在博客园看到了两篇相关的博客,我才知道原来要实现相关功能需要哪几个类哪几个方法,这个过程大概用了一周吧,效率超低。

解决我燃眉之急的两篇博客分别是:

王磊:http://www.cnblogs.com/webabcd/archive/2013/06/03/3114657.html

老周:http://www.cnblogs.com/tcjiaan/p/4303918.html

看了这两篇博客就知道该使用哪些类了,再接下来就相对简单了。非常感谢两位老师的分享和指导。

在RT应用中,涉及到加/解密的API都在以下几个命名空间里:

1、Windows.Security.Cryptography

2、Windows.Security.Cryptography.Core

3、Windows.Security.Cryptography.DataProtection

接下来分享一下我在项目中做过的几个加密/签名,进行了一下简单的封装,还望大家指点

1.3des加密

    internal sealed class TripleDesEncryptHelper
{ //加/解密 第一步
//通过SymmetricKeyAlgorithmProvider的静态方法OpenAlgorithm()得到一个SymmetricKeyAlgorithmProvider实例
//该方法参数是要使用的加/解密算法的名字
internal static SymmetricKeyAlgorithmProvider syprd = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.TripleDesEcb); /// <summary>
/// 加密函数
/// </summary>
/// <param name="data">需要加密的字符串</param>
/// <returns>返回加密后的结果</returns>
public static string Encrypt(string data, string key)
{
string encryptedData = null;
try
{
byte[] dataBytes = Encoding.UTF8.GetBytes(data);
//这里我自己写了一个pkcs5对齐,不过后来有看到过C#pkcs5和pkcs7是一样的说法,有待验证
byte[] pkcs5databytes = pkcs5(dataBytes);
IBuffer databuffer = pkcs5databytes.AsBuffer(); byte[] keyBytes = Convert.FromBase64String(key);
IBuffer keybuffer = keyBytes.AsBuffer();
//构造CryptographicKey
CryptographicKey cryptographicKey = syprd.CreateSymmetricKey(keybuffer);
//加密
//Encrypt需要三个参数分别为加密使用的Key,需要加密的Data,以及向量IV
//Des加密中Ecb模式和Cbc模式的区别就在于是否必须使用向量IV
IBuffer cryptBuffer = CryptographicEngine.Encrypt(cryptographicKey, databuffer, null); **************/
byte[] enctyptedBytes = cryptBuffer.ToArray();
//进行base64编码
encryptedData = Convert.ToBase64String(enctyptedBytes);
}
catch (Exception ex)
{
DebugHelper.Log("TripleDesEncryptHelper.Encrypt", ex.Message);
}
return encryptedData.Trim();
} /// <summary>
/// 解密函数
/// </summary>
/// <param name="data">待解密的字符串</param>
/// <returns>解密后的数据</returns>
public static string Decrypt(string data, string key)
{
string decryptedData = null;
try
{
byte[] dataBytes = Convert.FromBase64String(data);
IBuffer dataBuffer = dataBytes.AsBuffer();
byte[] keyBytes = Convert.FromBase64String(key);
IBuffer keybuffer = keyBytes.AsBuffer();
CryptographicKey cryptographicKey = syprd.CreateSymmetricKey(keybuffer);
IBuffer decryptedBuffer = CryptographicEngine.Decrypt(cryptographicKey, dataBuffer, null);
decryptedData = CryptographicBuffer.ConvertBinaryToString(BinaryStringEncoding.Utf8, decryptedBuffer);
//防止乱码
var result = System.Text.RegularExpressions.Regex.Match(decryptedData, "[a-zA-Z0-9]*");
decryptedData = result.ToString();
}
catch (Exception ex)
{
DebugHelper.Log("TripleDesEncryptHelper.Decrypt", ex.Message);
}
return decryptedData;
} /// <summary>
/// 把数据进行pkcs5对齐
/// </summary>
/// <param name="databytes">待处理的数据</param>
/// <returns></returns>
private static byte[] pkcs5(byte[] databytes)
{
byte[] newBytes = null; int datalength = databytes.Length;
int blocksize = (int)syprd.BlockLength;
if (!(datalength % blocksize == ))
{
int need = blocksize - (datalength % );
newBytes = new byte[datalength + need];
for (int i = ; i < datalength; i++)
{
newBytes[i] = databytes[i];
}
byte xx = 0x0;
switch (need)
{
case :
xx = 0x1;
break;
case :
xx = 0x2;
break;
case :
xx = 0x3;
break;
case :
xx = 0x4;
break;
case :
xx = 0x5;
break;
case :
xx = 0x6;
break;
case :
xx = 0x7;
break;
}
for (int i = ; i < need; i++)
{
newBytes[datalength + i] = xx;
}
}
else
{
newBytes = new byte[datalength + ];
for (int i = ; i < datalength; i++)
{
newBytes[i] = databytes[i];
}
byte xx = 0x8;
for (int i = ; i < ; i++)
{
newBytes[datalength + i] = xx;
}
}
return newBytes;
}
}

2. Sha1签名

根据爱贝的要求,需要先将数据进行sha1 hash,再将hash后的数据进行sha1签名

internal sealed class Sha1SignHelper
{
/// <summary>
/// 用sha1进行签名
/// </summary>
/// <param name="data">需要签名的数据</param>
/// <param name="key">签名私钥</param>
/// <returns></returns>
internal static string Sha1Sign(string data, string key)
{
string signedData = null;
IBuffer dataBuffer = Encoding.UTF8.GetBytes(data).AsBuffer();
try
{
AsymmetricKeyAlgorithmProvider asymmetricAlgorithm = AsymmetricKeyAlgorithmProvider.OpenAlgorithm("RSASIGN_PKCS1_SHA1");
//创建一个公钥私钥对
CryptographicKey KeyPair = asymmetricAlgorithm.ImportKeyPair(CryptographicBuffer.DecodeFromBase64String(key), CryptographicPrivateKeyBlobType.Pkcs1RsaPrivateKey);
//哈希计算data
HashAlgorithmProvider provider = HashAlgorithmProvider.OpenAlgorithm(Windows.Security.Cryptography.Core.HashAlgorithmNames.Sha1);
IBuffer hashedData = provider.HashData(dataBuffer);
//签名
IBuffer signedHashedBuffer = CryptographicEngine.SignHashedData(KeyPair, hashedData);
signedData = CryptographicBuffer.EncodeToBase64String(signedHashedBuffer);
}
catch (Exception ex)
{
DebugHelper.Log("Sha1SignHelper.Sha1Sign", ex.Message);
}
return signedData;
} internal static bool Sha1VerifySignature(string oldText, string signature, string publicKey)
{
bool dataCorrect = false;
try
{
AsymmetricKeyAlgorithmProvider asymmetricAlgorithm = AsymmetricKeyAlgorithmProvider.OpenAlgorithm("RSASIGN_PKCS1_SHA1");
//创建一个公钥私钥对
IBuffer pubKeyBuffer = Convert.FromBase64String(publicKey).AsBuffer();
CryptographicKey KeyPair = asymmetricAlgorithm.ImportPublicKey(CryptographicBuffer.DecodeFromBase64String(publicKey));
// 验证签名(通过公钥)
IBuffer databuffer = CryptographicBuffer.ConvertStringToBinary(oldText, BinaryStringEncoding.Utf8); ;
dataCorrect = CryptographicEngine.VerifySignature(KeyPair, databuffer, Convert.FromBase64String(signature).AsBuffer());
}
catch (Exception ex)
{
DebugHelper.Log("Sha1SignHelper.Sha1VerifySignature", ex.Message);
}
return dataCorrect;
}
}

对接过支付宝的大神们应该比较熟悉,支付宝与爱贝的区别就在于支付宝是先md5哈希,再sha1签名,可是我将

HashAlgorithmProvider provider = HashAlgorithmProvider.OpenAlgorithm(Windows.Security.Cryptography.Core.HashAlgorithmNames.Sha1);

改为

HashAlgorithmProvider provider = HashAlgorithmProvider.OpenAlgorithm(Windows.Security.Cryptography.Core.HashAlgorithmNames.Md5);

签名后得到的数据却始终与支付宝匹配不上,无奈只能在服务器上完成这一环节,有知道问题所在的大神们可以指点一下。

以上就是我在做支付时用到过的加密/签名算法,自己封装成了类以便使用。

做完这个项目后其实我对加密/签名算法本身还是一头雾水,并不理解算法的本质原理,只是完成了功能而已,所以过程中也遇到了几个问题:

1.永远sha1签名的私钥的格式 CryptographicKey KeyPair = asymmetricAlgorithm.ImportKeyPair(CryptographicBuffer.DecodeFromBase64String(key), CryptographicPrivateKeyBlobType.Pkcs1RsaPrivateKey)中CryptographicPrivateKeyBlobType.Pkcs1RsaPrivateKey和CryptographicPrivateKeyBlobType.Pkcs8RawPrivateKeyInfo的区别

2.pem格式密钥和xml格式密钥怎么转换

3.为什么先md5哈希再rsa签名始终和支付宝对不上?

如果有理解深入的大神,希望可以指点一下。

第一次写博客,可能思路不清晰,望见谅!

复习做UWP时涉及到的几种加密签名相关的更多相关文章

  1. MySQL做练习时总结的一些知识点

    MySQL做练习时总结的一些知识点     0:mysql有三种注释方法 上午插入记录的时候一直没有成功,郁闷不知道为什么.因为是很多条记录一起插入,中间一些不用的数据就用"--" ...

  2. 使用C++做算法时,对内存的管理的办法

    使用C++做算法时,对内存的管理的办法 最近老是在想C++的内存控制机制,查了一些资料所以有点想法,自己记录一下免得以后自己忘了. 1. 需求 在做线性代数的算法时,首要的就实现Matrix这个类.由 ...

  3. angular中service封装$http做权限时拦截403等状态及获取验证码倒计时、跨域问题解决

    封装$http.做权限时拦截403等状态及获取验证码倒计时: 拦截接口返回状态 var app = angular.module('app'); app.factory('UserIntercepto ...

  4. 怎样让oracle实验本在不做实验时性能提升——win7下举例

    怎样让oracle实验本在不做实验时性能提升--win7下举例 型号:ThinkPad E431 系统:WIN7 实验使用的笔记本不使用数据库时.建议将oracle关闭,使其释放占用的资源. orac ...

  5. 【Unity_UWP】Unity 工程发布win10 UWP 时的本地文件读取 (上篇)

    Universal Windows Platform(UWP)是微软Windows10专用的通用应用平台,其目的在于在统一操作系统下控制所有智能电子设备. 自从Unity 5.2之后,配合VS 201 ...

  6. 在使用R做数据挖掘时,最常用的数据结构莫过于dataframe了,下面列出几种常见的dataframe的操作方法

    原网址 http://blog.sina.com.cn/s/blog_6bb07f83010152z0.html 在使用R做数据挖掘时,最常用的数据结构莫过于dataframe了,下面列出几种常见的d ...

  7. TortoiseGit做push时提示Disconnected: No supported authentication methods available (server sent: publickey)错误

    通过Git从远程服务器上获得到自己的项目,但是通过TortoiseGit做push时提示Disconnected: No supported authentication methods availa ...

  8. 做dg时遇到的log_archive_dest、log_archive_dest_1、db_recovery_file_dest之间互相影响

    前提:归档开启.默认不指定归档文件夹. 今晚遇到客户那里设置了闪回区和log_archive_dest.不停库做DG时,无法指定log_archive_dest_n參数,巨坑. .实验了下.结论例如以 ...

  9. django 做 migrate 时 表已存在的处理方法

    django 做 migrate 时 表已存在的处理方法 文章来源:嗨学网 http://www.piaodoo.com 在开发web的时候,如果是以前已存在的项目,项目下载下来后,为了使用测试库的数 ...

随机推荐

  1. 关于Kb/s,KB/s的一些知识

    我们常见的有KB/s和Kb/s两种 1,Kb/s也就是Kbps.这里面小写的b是bit(比特)的缩写,是位的意思.一个位就是二进制的0或者1.一般代表传输单位,p就是/号,s是秒.bps就是b/s=比 ...

  2. Android根据APP包名启动应用

    public void openApp(String packageName, Context context) { PackageManager packageManager = context.g ...

  3. IOS Quartz2D简介

    Quartz2D 简介( 后续会有相关应用) 第一部分 绘制直线 代码示例: - (void)drawRect:(CGRect)rect{ //获取图形上下文 CGContextRef cxConte ...

  4. OC语言-06-OC语言-block与protocol

    一.block 1> 基本使用 相当于用来存放代码的代码块 效率高 若没有形参可以省略小括号 2> block与函数的相同点 可以保存代码 可以有返回值 可以有形参 调用方式一样 3> ...

  5. XMind快捷键

    XMind 是一款非常实用的思维导图软件,可以画各种结构图鱼骨图.二维图.树形图.逻辑图.组织结构图等!下面是常用的快捷键统计! 快捷鍵(Windows) 快捷鍵(Mac) 描述 Ctrl+N Com ...

  6. IDO分享 | 如何在centos下安装OpenCMS

    本次的opencms环境是在两台机器上搭建的. 一台服务器安装mySQL, 一台服务器安装jdk.tomcat.opencms.也可以将jdk.mySQL.tomcat.opencms安装在同一个机器 ...

  7. 问题解决——XP线程池找不到QueueUserWorkItem

    2013年7月11号 主管让同事写一个并发100的小工具进行什么压力测试,据说是创建100个线程. 我表示这真真的是在坑人! 线程创建消耗资源,以自己的笔记本来跑这个东西,时间片都消耗在了线程切换上了 ...

  8. IP工具类-自己动手做个ip解析器

    IP工具类-自己动手做个ip解析器 一.资料准备 导入依赖包:

  9. 【DPDK】虚拟机开发环境配置

    DPDK介绍见:www.dpdk.org 本文介绍的步骤基本适用于dpdk 1.7.0 - dpdk 2.0.0 各版本.只是setup.sh显示的菜单有一些小的不同:同样的,也适用于ubuntu更高 ...

  10. Linux基础问答

    1.简述TCP三次握手四次挥手过程及各过程中客户端和服务器端的状态. 1 2 3 4 5 6 7 8 9 10 11 12 13 #三次握手 客户端向服务器端发送SYN包,客户端进入SYN_SEND状 ...