關於Windows Phone 中加密算法使用.最近一段時間不少作Windows Phone應用同窗在微博上提了很多問題.其實在客戶端實際需求中大多都會涉及到數據基於加密算法的解析和加密.本篇幅針對Windows Phone數據加密算法的問題.給出一些解決方案.php
首先有必要來講說爲什麼會存在Windows Phone數據加密的問題.作過Silverlight的同窗應該知道.在Silverlight 4版本 .NET類庫中基於System.Security.Cryptography命名空間下.保留了Aes加密算法.關於數據DES和TripleDES[3DES]加密算法已經不存在了.一樣在Windows Phone SDK 7.1.1最新版本中.也可以看出除了SHA1和HMAC_SHA1對稱算法外.若是咱們嘗試作MD5或對稱的HMAC_MD5加密操做發現官方的SDK並無提供相似支持的類. 如是問題就這麼出現了.html
若是須要在服務器端和和客戶端傳遞相似MD五、HMAC_MD5或是解析服務器端傳遞的DES、TripleDES[3DES]數據是發現如今Windows Phone針對數據加密和解析並無對應的支持.其實這些問題.原來都在咱們團隊實際Coding過程都碰到過.也算是找到一些比較成熟的解決方案.以下.git
本篇幅針對MD5,HMAC_MD5,DES,TripleDES[3DES]算法給出Windows Phone移植版本.github
首先來講說MD5.算法
MD5[Message Digest Algorithm MD5]用於確保信息傳輸完整一致,在計算機普遍使用的雜湊算法之一[又譯摘要算法、哈希算法].比較常見使用於保證數據完整性.MD5或者說HASH值是一種不可逆的算法.在.NET 4中也提供相似在System.Security.Cryptography.MD5命名空間下MD5CryptoServiceProvider 類的對應實現.針對Silverlight和WP對應版本不支持MD5的狀況,微軟官方在archive.msdn上給出對應的MD5 Silverlight移植版本.[一樣使用於Windows Phone]:服務器
Silverlight MD5 Implementation:ssh
[http://archive.msdn.microsoft.com/SilverlightMD5]異步
具體實現Code也能夠參考GitHub上地址.這裏再也不贅述.ide
HMAC_MD5.函數
使用 MD5 哈希函數計算基於哈希值的消息驗證代碼 [HMAC].
HMACMD5 是從 MD5 哈希函數構造的一種鍵控哈希算法,被用做基於哈希的消息驗證代碼 [HMAC].此 HMAC 進程將密鑰與消息數據混合,使用哈希函數對混合結果進行哈希計算,將所得哈希值與該密鑰混合,而後再次應用哈希函數。輸出的哈希值長度爲 128 位.
關於HMAC_MD5算法除了在Codeplex 上[http://hmacmd5.codeplex.com/] 找到HMACmd5 Codeplex已經在Windows Phone驗證經過外:
HMACMD5 For Silverlight/Windows Phone:
http://hmacmd5.codeplex.com/
其餘第三方方式均沒有驗證過.考慮該算法核心並不複雜.因而本身動手重寫一個基於Windows Phone 版本HMACMD5的實現[驗證經過]. 核心類以下:
1: ?
using System;
2:
using System.Net;
3:
using System.Windows;
4:
using System.Windows.Controls;
5:
using System.Windows.Documents;
6:
using System.Windows.Ink;
7:
using System.Windows.Input;
8:
using System.Windows.Media;
9:
using System.Windows.Media.Animation;
10:
using System.Windows.Shapes;
11:
12:
namespace DataEncryptBuildDemo.DataEncryptCommon
13: {
14:
/// <summary>
15:
/// HMACMD Data Encrypt Operator
16:
/// Author:chenkai Data:6/7/2011
17:
/// </summary>
18:
public
class HMACMD5DataEncrypt
19: {
20:
/// <summary>
21:
/// HMAC_MD5 DataEncrypt
22:
/// </summary>
23:
/// <param name="original">明文</param>
24:
/// <param name="key">密鑰</param>
25:
/// <returns>返回加密的字符串</returns>
26:
public
static
string HMAC_MD5(
string original,
string key)
27: {
28:
byte[] b_tmp;
29:
byte[] b_tmp1;
30:
if (key ==
null)
31: {
32:
return
null;
33: }
34:
byte[] digest =
new
byte[512];
35:
byte[] k_ipad =
new
byte[64];
36:
byte[] k_opad =
new
byte[64];
37:
38:
byte[] source = System.Text.UTF8Encoding.UTF8.GetBytes(key);
39:
//System.Security.Cryptography.MD5 shainner = new MD5CryptoServiceProvider();
40:
41:
for (
int i = 0; i < 64; i++)
42: {
43: k_ipad[i] = 0 ^ 0x36;
44: k_opad[i] = 0 ^ 0x5c;
45: }
46:
47:
try
48: {
49:
if (source.Length > 64)
50: {
51:
//shainner = new MD5CryptoServiceProvider();
52: source = MD5Core.GetHash(source);
//shainner.ComputeHash(source);
53: }
54:
55:
for (
int i = 0; i < source.Length; i++)
56: {
57: k_ipad[i] = (
byte)(source[i] ^ 0x36);
58: k_opad[i] = (
byte)(source[i] ^ 0x5c);
59: }
60:
61: b_tmp1 = System.Text.UTF8Encoding.UTF8.GetBytes(original);
//內容
62: b_tmp = Adding(k_ipad, b_tmp1);
63:
64:
65:
//shainner = new MD5CryptoServiceProvider();
66: digest = MD5Core.GetHash(b_tmp);
//shainner.ComputeHash(b_tmp);
67: b_tmp = Adding(k_opad, digest);
68:
69:
70:
//shainner = new MD5CryptoServiceProvider();
71: digest = MD5Core.GetHash(b_tmp);
//shainner.ComputeHash(b_tmp);
72:
return ByteToString(digest);
73: }
74:
catch (Exception e)
75: {
76:
throw e;
77: }
78: }
79:
80:
/// <summary>
81:
/// 填充byte
82:
/// </summary>
83:
/// <param name="a"></param>
84:
/// <param name="b"></param>
85:
/// <returns></returns>
86:
private
static
byte[] Adding(
byte[] a,
byte[] b)
87: {
88:
byte[] c =
new
byte[a.Length + b.Length];
89: a.CopyTo(c, 0);
90: b.CopyTo(c, a.Length);
91:
return c;
92: }
93:
94:
/// <summary>
95:
/// Byte To String
96:
/// </summary>
97:
/// <param name="buff"></param>
98:
/// <returns></returns>
99:
private
static
string ByteToString(
byte[] buff)
100: {
101:
string sbinary =
"";
102:
103:
for (
int i = 0; i < buff.Length; i++)
104: {
105: sbinary += buff[i].ToString(
"X2");
// hex format
106: }
107:
return (sbinary);
108: }
109: }
110: }
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }
具體代碼也能夠從HMACMD5 For Windows Phone GitHub上能夠查看.如上代碼驗證經過.
TripleDES[3DES]
Triple DES又稱3DES,是DES加密算法的一種模式.[TDEA,Triple Data Encryption Algorithm]塊密碼的通稱。它至關因而對每一個數據塊應用三次DES加密算法.如今計算機運算能力的加強,原版DES密碼的密鑰長度變得容易被暴力破解;3DES便是設計用來提供一種相對簡單的方法,即經過增長DES的密鑰長度來避免相似的***,而不是設計一種全新的塊密碼算法.
一開始我大概看了DES 算法在C下面的實現很簡單.費了點時間很快就移植Windows Phone DES算法版本. DES算法的核心採用位運算的. 每次8個字節也就是64位內容.密鑰key也爲64位.而後通過16輪置換. 惋惜 TripleDES[3DES]始終沒有移植成功.重複造輪子無果後.果斷尋求第三方解決方案.
在Silverlight和Windows Phone 在CodePlex值得推薦開源第三方庫是SSH.NET Library
SSH.NET Library:
http://sshnet.codeplex.com/
SSH.NET Library庫移植靈感是來源於Java版本.不過SSH。NET是徹底基於.NET 沒有采用任何第三方組件和引用. 其中實現也包含同步和異步的封裝. Socket通訊庫. HTTP代等.其中最爲重要的是基於.NET 實現DES和TripleDES[3DES] 兩種核心算法. 而且支持.NET 3.5 、Silverlight、Windows Phone.
固然除了Codeplex上這個比較成熟SSH.NET Library開源組件外.關於DES和TripleDES[3DES] 還能夠找到其餘相似可選的開源組件.針對Windows Phone 缺少3DES支持.國外一個WP 開發者Nicolas Humann[Link in] 基於broccoliproducts 的DES, TripleDES and BlowFish in Silverlight 版本庫作了進一步的集成和封裝. 併成功移植DES和TripleDES[3DES]Windows phone版本:
Nicolas Humann[Link in] DES And TripleDES[3DES] Component:
TripleDES Cryptography On Silverlight And Windows Phone
針對Nicolas Humann[Link in] 這個3DES版本移植ku.在其基礎作了進一步的封裝.爲了是實現對TripleDESCryptoServiceProvider 類[3DES核心實現類]對數據加密和解密的操做. 大概分爲兩種狀況.一種是須要IV密鑰Key 另一種不須要密鑰Key 數據基於3DES和DES 加密和解密的封裝. 核心Code以下:
1:
using System;
2:
using System.Net;
3:
using System.Windows;
4:
using System.Windows.Controls;
5:
using System.Windows.Documents;
6:
using System.Windows.Ink;
7:
using System.Windows.Input;
8:
using System.Windows.Media;
9:
using System.Windows.Media.Animation;
10:
using System.Windows.Shapes;
11:
12:
using System.Text;
13:
using System.Security.Cryptography;
14:
using DataEncryptBuildDemo.DataEncryptCommon.DESDataEncrypt;
15:
16:
namespace DataEncryptBuildDemo.DataEncryptCommon
17: {
18:
/// <summary>
19:
/// Des And TripleDES DataEncrypt Operator
20:
/// Author:chenkai Date:14/5 2012
21:
/// </summary>
22:
public
class Des_DataEncrypt
23: {
24:
/// <summary>
25:
/// TripleDes Data Encrypt With Ot Encrypt Key Operator
26:
/// </summary>
27:
/// <param name="sourceContent">Source Need to TripleDes Encrpt Data</param>
28:
/// <returns>Encrypt Data Byte[] String</returns>
29:
public
static
byte[] TripleDesEncryptWithOutKey(
string sourceContent)
30: {
31:
if (
string.IsNullOrEmpty(sourceContent))
32:
return
null;
33:
34: var toEncryptSourceStr = Encoding.UTF8.GetBytes(sourceContent);
35: TripleDESCryptoServiceProvider tripleDesEncryptProvider =
new TripleDESCryptoServiceProvider();
36: ICryptoTransform encryptTransform=tripleDesEncryptProvider.CreateEncryptor();
37:
byte[] encryptToBytes = encryptTransform.TransformFinalBlock(toEncryptSourceStr, 0, toEncryptSourceStr.Length);
38:
39:
return encryptToBytes;
40: }
41:
42:
/// <summary>
43:
/// TripleDes Data DeEncrypt With Out Encrypt Key Operator
44:
/// </summary>
45:
/// <param name="encryptBytes">Encrypt Byte Array</param>
46:
/// <returns>DeEncrypt SourceContent String</returns>
47:
public
static
string TripleDesDeEncryptWithOutKey(
byte[] encryptBytes)
48: {
49:
if (encryptBytes ==
null || encryptBytes.Length <= 0)
50:
return
string.Empty;
51:
52: TripleDESCryptoServiceProvider tripleDesProvider =
new TripleDESCryptoServiceProvider();
53: ICryptoTransform deEncryptTransform = tripleDesProvider.CreateDecryptor();
54: var deEncryptBytes = deEncryptTransform.TransformFinalBlock(encryptBytes, 0, encryptBytes.Length);
55: var deEncryptFormatStr = Encoding.UTF8.GetString(deEncryptBytes, 0, deEncryptBytes.Length);
56:
57:
return deEncryptFormatStr;
58: }
59:
60:
/// <summary>
61:
/// TripleDes Data Encrypt Use IVKey Operator
62:
/// </summary>
63:
/// <param name="sourceContent">Source Content</param>
64:
/// <param name="encryptKey">Encrypt Key</param>
65:
/// <returns>Encrypt Bytes Array</returns>
66:
public
static
byte[] TripleDesEncryptUseIvKey(
string sourceContent,
byte[] encryptIVKey)
67: {
68:
if (
string.IsNullOrEmpty(sourceContent) || encryptIVKey ==
null || encryptIVKey.Length <= 0)
69:
return
null;
70:
71: var toEncryptSourceStr = Encoding.UTF8.GetBytes(sourceContent);
72: TripleDESCryptoServiceProvider tripleDesProvider =
new TripleDESCryptoServiceProvider();
73:
74:
//No Seting Pading
76: var key = tripleDesProvider.Key;
//Save Key
77: IsolatedStorageCommon.IsolatedStorageSettingHelper.AddIsolateStorageObj(
"EncryptKey", key);
78: ICryptoTransform encryptTransform = tripleDesProvider.CreateEncryptor(key, encryptIVKey);
79: var encryptBytes = encryptTransform.TransformFinalBlock(toEncryptSourceStr, 0, toEncryptSourceStr.Length);
80:
81:
return encryptBytes;
82: }
83:
84:
85:
86:
/// <summary>
87:
/// Triple Des DeEncrypt Operator Use IvKey
88:
/// </summary>
89:
/// <param name="encryptKey">Encrypt key can be null</param>
90:
/// <param name="ivKey">Iv</param>
91:
/// <param name="encryptBytes">EncryptBytes</param>
92:
/// <returns>Return String </returns>
93:
public
static
string TripleDesDeEncryptUseIvKey(
byte[] encryptKey,
byte[] ivKey,
byte[] encryptBytes)
94: {
95:
if (encryptBytes ==
null || encryptBytes.Length <= 0)
96:
return
string.Empty;
97:
98: TripleDESCryptoServiceProvider tripleDesProvider =
new TripleDESCryptoServiceProvider();
99:
100:
if (encryptKey ==
null)
101: encryptKey = IsolatedStorageCommon.IsolatedStorageSettingHelper.GetIsolateStorageByObj(
"EncryptKey")
as
byte[];
102: ICryptoTransform deEncryptTransform = tripleDesProvider.CreateDecryptor(encryptKey, ivKey);
103: var DecryptBytes = deEncryptTransform.TransformFinalBlock(encryptBytes, 0, encryptBytes.Length);
104:
string unDecryptFomatStr = Encoding.UTF8.GetString(DecryptBytes, 0, DecryptBytes.Length);
105:
106:
return unDecryptFomatStr;
107: }
108: }
109: }
固然這個只是Nicolas Humann[Link in] 對3DEs Windows Phone版本進一步封裝. 目的方便可以造成一套API.無需關心TripleDESCryptoServiceProvider 類具體如何實現.至於這段代碼能夠GitHub上找到.驗證經過.
至此關於應用開發常見的MD五、MAC_MD五、DES、3DES Windows Phone移植版本算法可用庫如上.如上代碼均實際項目中驗證經過.對於還在苦苦重複造輪子同窗.若是以爲爲了使用效率.仍是值得參考的.
關於本片所有源碼能夠GitHub下載到[ https://github.com/chenkai/DataEncryptWindowsPhoneDemo ].若有Bug請即時反饋 Email:chenkaiHome@live.cn
或經過Sina 微博:[http://weibo.com/chenkaihome] 即時溝通.
參考連接:
TripleDES Cryptography On Silverlight And Windows Phone
DES, TripleDES and BlowFish in Silverlight