這一篇文章我將實現一個實驗性的Silverlight控件純客戶端註冊驗證機制。但願作過這方面的朋友多給些指導性意見。
先給你們介紹一下Silverlight客戶端控件的使用情景。通常來講,Silverlight客戶端控件會****給開發Silverlight程序 的公司,他們是控件的購買者。他們開發的程序中會用到Silverlight客戶端控件。可是Silverlight控件最終是在瀏覽 Silverlight程序的網站用戶機器上執行的。說的有點繞,請參照下圖。
這個純客戶端註冊驗證機制主要流程以下:
1, 控件購買者下載使用Silverlight控件(Silverlight控件中包含PublicKey及驗證License的邏輯)。
2, 控件購買者經過控件生成商提供的網站輸入一些註冊信息(如輸入程序部署路徑等惟一標示),付費,完成註冊。控件生成商會記錄這些信息,並使用PrivateKey生成一個RSA簽名過的License文件。
3, 控件生產商會將這個RSA簽名過的License文件返回給控件購買者。
4, 控件購買者會將License文件綁定到他開發部署的程序中。
5, 網站用戶瀏覽控件購買者開發部署的網站,下載Silverlight控件在網站用戶機器上執行,並驗證License文件的簽名及程序部署路徑等惟一標示。 html
這個驗證性Demo中的License格式以下: 算法
<
License
>
<
Id
>
31f81fef-a036-4f6f-b47b-d0c8da1674ea
</
Id
>
<
AssemblyName
>
Vendor.TestControl, Version=1.0.0.0, Culture=neutral, PublicKeyToken=696fd0988622108f
</
AssemblyName
>
<
AuthorisedApp
>
http://localhost:8888/ClientBin/Customer.TestApp.xap
</
AuthorisedApp
>
<
Signature
>
MVALuQLzIK8SWfZ5q25/PD3P6ZV0FLqIhCt5YcZ7yNkBTuLABg/TGggC4imU2S6QyZBOLsXyEOSFfXXxBn7Spwhkr6P+CbQb0MvotPgr5nenLdccm7UwABkn7+PgtEchObGba5KUhHCAkvvSFfwi/e480AYI2YXznVpCsP8RA8o=
</
Signature
>
</
License
>
License中記錄了控件生成商數據庫中License信息記錄Id,強名稱簽名的目標控件程序集全名,程序部署路徑等一些惟一性標示及防止篡改這些信息的RSA數字簽名。 數據庫
當用戶瀏覽網站時,Silverlight控件會下載到在用戶機器上執行,從而進行註冊碼驗證工做。它會首先驗證License的合法性(即便用RSA籤 名驗證算法檢驗License文件是否被篡改),而後會判斷程序集及惟一性標示是否正確。從而判斷控件是否成功註冊。 跨域
驗證License合法性代碼以下: 服務器
代碼
public
class
License
{
private
static
readonly
string
PublicKeyXmlString
=
"
<RSAKeyValue><Modulus>wG5DRppiesQegis92ZyJOO3ADC6ANV470SPyOhuYBpDpwA/UX4gO3XQhEr2jx09ZLQWYvwVJdSg4JhoO46fw11nsQObzwd+wz/jEcjSF9MCfK+CVb3qMHH9TBgHh5dy7zbB+hUkuacm/nKY9bPfaoNj4sA2YnbiPl3+v80qy/gE=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>
"
;
private
static
readonly
RSAManaged.RSAPublicKey PublicKey
=
null
;
static
License()
{
PublicKey
=
RSAManaged.RSAPublicKey.FromXmlString(PublicKeyXmlString);
}
internal
License()
{
}
internal
string
Id {
get
;
set
; }
public
string
AssemblyName {
get
;
internal
set
; }
public
string
AuthorisedApp {
get
;
internal
set
; }
internal
byte
[] Signature {
get
;
set
; }
public
bool
IsValid()
{
//
在這裏驗證License是否合法
byte
[] signData
=
Encoding.UTF8.GetBytes(
this
.Id
+
this
.AssemblyName
+
this
.AuthorisedApp);
SHA1Managed sha1
=
new
SHA1Managed();
bool
verifyResult
=
RSAManaged.RSAManaged.Verify(signData, PublicKey, sha1,
this
.Signature);
sha1.Clear();
return
verifyResult;
}
驗證程序集全名及程序部署路徑等惟一性標示代碼以下: ide
代碼
private
static
bool
ValidateLicenseFile()
{
AssemblyName assemblyName
=
new
AssemblyName(Application.Current.GetType().Assembly.FullName);
Uri uri
=
new
Uri(
"
/
"
+
assemblyName.Name
+
"
;component/license.lic
"
, UriKind.Relative);
StreamResourceInfo sri
=
Application.GetResourceStream(uri);
if
(sri
==
null
)
{
return
false
;
}
string
licenseXmlString
=
new
StreamReader(sri.Stream).ReadToEnd();
License license
=
License.FromXmlString(licenseXmlString);
if
(license
==
null
||
!
license.IsValid())
{
return
false
;
}
//
在這裏驗證程序集全名是否合法
if
(Assembly.GetExecutingAssembly().FullName
!=
license.AssemblyName)
{
return
false
;
}
//
在這裏驗證程序部署路徑等惟一性標示
if
(Application.Current.Host.Source.AbsoluteUri
!=
license.AuthorisedApp)
{
return
false
;
}
return
true
;
}
優缺點分析:
+使用私鑰簽名,公鑰驗證,能有效防止僞造License文件及分析代碼寫出註冊機(不考慮篡改程序邏輯的爆破方式)。
+純客戶端驗證不須要跨域訪問,也不須要控件購買者在程序發佈服務器端部署其餘東西。
-比直接輸入註冊碼麻煩
-在如今的Silverlight版本中,只找到部署地址這個特徵標示,所以只能作部署License受權。不能作成像WinForm控件那樣爲每一個開發人員機器受權的方式。 網站
http://www.th7.cn/Article/bc/SilverLight/201001/372893.html(原文) this