Microsoft Updater Application Block 1.4.3 KeyValidator类设计 [翻译]
Microsoft Updater Application Block KeyValidator类设计
译者:Tony Qu
KeyValidator类提供一个基于对称密钥的验证器,该章节将介绍KeyValidator设计的以下几个方面:
问题描述
设计目标、权衡和问题
解决方案描述
具体实现
问题描述
一个通常使用的验证方法是使用对称密钥进行签名和验证数据。为了支持这项技术,必须实现一个基于对称密钥的验证器。
设计目标、权衡和问题
1. KeyValidator应该支持由.net的KeyedHashAlgorithm类支持的对称密钥。
2. 开发人员应该能够在应用程序升级器的配置文件中指定密钥,该密钥应该用base64字符串存储。如果没有密钥被指定,KeyValidator会抛出一个异常。
解决方案描述
KeyValidator类派生自IValidator接口,它使用.net的KeyedHashAlgorithm类基于一个对称密钥生成和验证签名。
具体实现
KeyValidator类由Microsoft.ApplicationBlocks.ApplicationUpdater.Validators命名空间实现。
实现KeyValidator需要考虑四个方面:
1. 密钥初始化
2. 签名
3. 验证
4. KeyValidator配置
密钥初始化
1. Init方法用于从应用程序升级器配置文件传递<validator>元素给KeyValidator类。该元素应该包含<key>子元素,该元素中以base64字符串存储密钥。<key>元素用于初始化验证密钥,该初始化过程代码在下面的代码片断中。
[VB.NET]
   ![]() Sub Init (ByVal config As XmlNode) Implements IValidator.Init
Sub Init (ByVal config As XmlNode) Implements IValidator.Init 
![]() Dim keyNode As XmlNode = config.SelectSingleNode( "key" )
  Dim keyNode As XmlNode = config.SelectSingleNode( "key" ) 
![]() _key = ExtractKeyFromNode (keyNode)
  _key = ExtractKeyFromNode (keyNode) 
![]() If _key Is Nothing Then
  If _key Is Nothing Then 
![]() 'Throw a cryptographic exception
    'Throw a cryptographic exception 
![]() End If
  End If 
![]() End Sub 
   
[C#]
End Sub 
   
[C#] 
   ![]() void IValidator.Init( XmlNode config )
void IValidator.Init( XmlNode config ) 
![]() {
{                     
![]() XmlNode keyNode = config.SelectSingleNode( "key" );
  XmlNode keyNode = config.SelectSingleNode( "key" ); 
![]() _key = ExtractKeyFromNode( keyNode );
  _key = ExtractKeyFromNode( keyNode ); 
![]() if ( null == _key )
  if ( null == _key ) 
![]() {
  { 
![]() // Throw a cryptographic exception
    // Throw a cryptographic exception 
![]() }
  } 
![]() } 
   
2. Init方法使用一个ExtractKeyFromNode私有函数解析位于配置文件中的base64加密的字符串,并且返回一个byte数组。下面的代码展示了ExtractKeyFromNode函数。
} 
   
2. Init方法使用一个ExtractKeyFromNode私有函数解析位于配置文件中的base64加密的字符串,并且返回一个byte数组。下面的代码展示了ExtractKeyFromNode函数。 
[VB.NET]
   ![]() Private Function ExtractKeyFromNode(ByVal keyNode As XmlNode) As Byte()
Private Function ExtractKeyFromNode(ByVal keyNode As XmlNode) As Byte() 
![]() Dim key As Byte() = Nothing
  Dim key As Byte() = Nothing 
![]() If keyNode Is Nothing Then
  If keyNode Is Nothing Then 
![]() Return Nothing
     Return Nothing 
![]() End If
  End If 
![]() Try
  Try 
![]() key = Convert.FromBase64String(keyNode.InnerText)
    key = Convert.FromBase64String(keyNode.InnerText) 
![]() Catch e As Exception
  Catch e As Exception 
![]() 'exception handling code
    'exception handling code 
![]() End Try
  End Try 
![]() Return key
  Return key 
![]() End Function 
   
[C#]
End Function 
   
[C#] 
   ![]() private byte[] ExtractKeyFromNode( XmlNode keyNode )
private byte[] ExtractKeyFromNode( XmlNode keyNode ) 
![]() {
{ 
![]() byte[] key = null;
  byte[] key = null; 
![]() if ( null == keyNode )
  if ( null == keyNode ) 
![]() {
  { 
![]() return null;
    return null; 
![]() }
  } 
![]() try
  try 
![]() {
  { 
![]() key = Convert.FromBase64String( keyNode.InnerText );
    key = Convert.FromBase64String( keyNode.InnerText ); 
![]() }
  } 
![]() catch( Exception e )
  catch( Exception e ) 
![]() {
  {                         
![]() // exception handling code
    // exception handling code 
![]() }
  } 
![]() return key;
  return key; 
![]() }
} 
   
签名
重载的Sign方法使用KeyedHashAlgorithm类生成hashed签名,下面的代码片断展示了这一过程:
[VB.NET]
   ![]() Overloads Function Sign(ByVal filePath As String, ByVal key As String) As String _
Overloads Function Sign(ByVal filePath As String, ByVal key As String) As String _ 
![]() Implements IValidator.Sign
    Implements IValidator.Sign  
![]() Dim outSignature As Byte() = Nothing
  Dim outSignature As Byte() = Nothing 
![]() Dim fs As FileStream = Nothing
  Dim fs As FileStream = Nothing 
![]() Try
  Try 
![]() fs = New FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)
    fs = New FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read) 
![]() Dim kha As KeyedHashAlgorithm = KeyedHashAlgorithm.Create()
    Dim kha As KeyedHashAlgorithm = KeyedHashAlgorithm.Create() 
![]() kha.Key = Convert.FromBase64String(key)
    kha.Key = Convert.FromBase64String(key) 
![]() outSignature = kha.ComputeHash(fs)
    outSignature = kha.ComputeHash(fs) 
![]() Catch e As Exception
  Catch e As Exception 
![]() ' exception handling code
    ' exception handling code 
![]() Finally
  Finally 
![]() If Not (fs Is Nothing) Then
    If Not (fs Is Nothing) Then 
![]() fs.Close()
      fs.Close() 
![]() End If
     End If 
![]() End Try
   End Try 
![]() Return Convert.ToBase64String(outSignature)
   Return Convert.ToBase64String(outSignature) 
![]() End Function
End Function 
![]() 
  
![]() Overloads Function Sign(ByVal xml As XmlNode, ByVal key As String) As String _
Overloads Function Sign(ByVal xml As XmlNode, ByVal key As String) As String _ 
![]() Implements IValidator.Sign
    Implements IValidator.Sign 
![]() Dim outSignature As Byte() = Nothing
  Dim outSignature As Byte() = Nothing 
![]() Dim xmlNodeByte As Byte() = Nothing
  Dim xmlNodeByte As Byte() = Nothing 
![]() xmlNodeByte = Encoding.Unicode.GetBytes(Xml.InnerXml)
  xmlNodeByte = Encoding.Unicode.GetBytes(Xml.InnerXml) 
![]() Try
  Try 
![]() Dim kha As KeyedHashAlgorithm = KeyedHashAlgorithm.Create()
    Dim kha As KeyedHashAlgorithm = KeyedHashAlgorithm.Create() 
![]() kha.Key = Convert.FromBase64String(key)
    kha.Key = Convert.FromBase64String(key) 
![]() outSignature = kha.ComputeHash(xmlNodeByte)
    outSignature = kha.ComputeHash(xmlNodeByte) 
![]() Catch e As Exception
  Catch e As Exception 
![]() 'exception handling code
    'exception handling code 
![]() End Try
  End Try 
![]() Return Convert.ToBase64String(outSignature)
  Return Convert.ToBase64String(outSignature) 
![]() End Function 
   
[C#]
End Function 
   
[C#] 
   ![]() string IValidator.Sign( string filePath, string key )
string IValidator.Sign( string filePath, string key ) 
![]() {
{ 
![]() byte[] outSignature = null;
  byte[] outSignature = null; 
![]() FileStream fs = null;
  FileStream fs = null; 
![]() try
  try 
![]() {
  { 
![]() fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
    fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); 
![]() KeyedHashAlgorithm kha = KeyedHashAlgorithm.Create();
    KeyedHashAlgorithm kha = KeyedHashAlgorithm.Create(); 
![]() kha.Key = Convert.FromBase64String( key );
    kha.Key = Convert.FromBase64String( key ); 
![]() outSignature = kha.ComputeHash( fs );
    outSignature = kha.ComputeHash( fs );        
![]() }
  } 
![]() catch( Exception e )
  catch( Exception e ) 
![]() {
  { 
![]() // exception handling code
    // exception handling code 
![]() }
  } 
![]() finally
  finally 
![]() if ( null != fs )
    if ( null != fs ) 
![]() {
    { 
![]() fs.Close();
      fs.Close(); 
![]() }
    } 
![]() }
  } 
![]() return Convert.ToBase64String( outSignature );
  return Convert.ToBase64String( outSignature ); 
![]() }
} 
![]() 
 
![]() string IValidator.Sign( XmlNode xml, string key )
string IValidator.Sign( XmlNode xml, string key ) 
![]() {
{ 
![]() byte[] outSignature = null;
  byte[] outSignature = null; 
![]() byte[] xmlNodeByte = null;
  byte[] xmlNodeByte = null; 
![]() xmlNodeByte = Encoding.Unicode.GetBytes( xml.InnerXml );
  xmlNodeByte = Encoding.Unicode.GetBytes( xml.InnerXml ); 
![]() try
  try 
![]() {
  { 
![]() KeyedHashAlgorithm kha = KeyedHashAlgorithm.Create();
    KeyedHashAlgorithm kha = KeyedHashAlgorithm.Create(); 
![]() kha.Key = Convert.FromBase64String( key );
    kha.Key = Convert.FromBase64String( key ); 
![]() outSignature = kha.ComputeHash( xmlNodeByte );
    outSignature = kha.ComputeHash( xmlNodeByte ); 
![]() }
  } 
![]() catch( Exception e )
  catch( Exception e ) 
![]() {
  { 
![]() // exception handling code
    // exception handling code 
![]() }
  } 
![]() return Convert.ToBase64String( outSignature );
  return Convert.ToBase64String( outSignature ); 
![]() }
} 
   
验证
Validate方法使用相同的KeyedHashAlgorithm验证签名和密钥,该密钥用于生成签名。Validate方法在下面的代码片断中实现:
[VB.NET]
   ![]() Overloads Function Validate(ByVal filePath As String, ByVal signature As String) _
Overloads Function Validate(ByVal filePath As String, ByVal signature As String) _ 
![]() As Boolean Implements IValidator.Validate
    As Boolean Implements IValidator.Validate 
![]() 
 
![]() Dim inSignature As Byte() = Nothing
  Dim inSignature As Byte() = Nothing 
![]() Dim outSignature As Byte() = Nothing
  Dim outSignature As Byte() = Nothing 
![]() inSignature = Convert.FromBase64String(signature)
  inSignature = Convert.FromBase64String(signature) 
![]() Dim fs As New FileStream(filePath, FileMode.Open)
  Dim fs As New FileStream(filePath, FileMode.Open) 
![]() Try
  Try 
![]() Dim kha As KeyedHashAlgorithm = KeyedHashAlgorithm.Create()
    Dim kha As KeyedHashAlgorithm = KeyedHashAlgorithm.Create() 
![]() kha.Key = _key
    kha.Key = _key 
![]() outSignature = kha.ComputeHash(fs)
    outSignature = kha.ComputeHash(fs) 
![]() Finally
  Finally 
![]() fs.Close()
    fs.Close() 
![]() End Try
  End Try 
![]() Return compareKeys(outSignature, inSignature)
  Return compareKeys(outSignature, inSignature) 
![]() End Function
End Function 
![]() 
 
![]() Overloads Function Validate(ByVal xml As XmlNode, ByVal signature As String) _
Overloads Function Validate(ByVal xml As XmlNode, ByVal signature As String) _ 
![]() As Boolean Implements IValidator.Validate
    As Boolean Implements IValidator.Validate 
![]() 
 
![]() Dim inSignature As Byte() = Nothing
   Dim inSignature As Byte() = Nothing 
![]() Dim outSignature As Byte() = Nothing
  Dim outSignature As Byte() = Nothing 
![]() Dim xmlNodeByte As Byte() = Nothing
  Dim xmlNodeByte As Byte() = Nothing 
![]() xmlNodeByte = Encoding.Unicode.GetBytes(Xml.InnerXml)
  xmlNodeByte = Encoding.Unicode.GetBytes(Xml.InnerXml) 
![]() inSignature = Convert.FromBase64String(signature)
  inSignature = Convert.FromBase64String(signature) 
![]() Dim kha As KeyedHashAlgorithm = KeyedHashAlgorithm.Create()
  Dim kha As KeyedHashAlgorithm = KeyedHashAlgorithm.Create() 
![]() kha.Key = _key
  kha.Key = _key 
![]() outSignature = kha.ComputeHash(xmlNodeByte)
  outSignature = kha.ComputeHash(xmlNodeByte) 
![]() Return compareKeys(outSignature, inSignature)
  Return compareKeys(outSignature, inSignature) 
![]() End Function 
   
[C#]
End Function 
   
[C#] 
   ![]() bool IValidator.Validate( string filePath, string signature )
bool IValidator.Validate( string filePath, string signature ) 
![]() {
{ 
![]() byte[] inSignature = null;
  byte[] inSignature = null; 
![]() byte[] outSignature = null;
  byte[] outSignature = null; 
![]() inSignature = Convert.FromBase64String( signature );
  inSignature = Convert.FromBase64String( signature ); 
![]() using ( FileStream fs = new FileStream( filePath, FileMode.Open ) )
  using ( FileStream fs = new FileStream( filePath, FileMode.Open ) ) 
![]() {
  { 
![]() KeyedHashAlgorithm kha = KeyedHashAlgorithm.Create();
    KeyedHashAlgorithm kha = KeyedHashAlgorithm.Create(); 
![]() kha.Key = _key;
    kha.Key = _key; 
![]() outSignature = kha.ComputeHash( fs );
    outSignature = kha.ComputeHash( fs ); 
![]() }
  } 
![]() return compareKeys( outSignature, inSignature );
  return compareKeys( outSignature, inSignature ); 
![]() }
}    
![]() 
 
![]() bool IValidator.Validate( XmlNode xml, string signature )
bool IValidator.Validate( XmlNode xml, string signature ) 
![]() {
{ 
![]() byte[] inSignature = null;
  byte[] inSignature = null; 
![]() byte[] outSignature = null;
  byte[] outSignature = null; 
![]() byte[] xmlNodeByte = null;
  byte[] xmlNodeByte = null; 
![]() xmlNodeByte = Encoding.Unicode.GetBytes( xml.InnerXml );
  xmlNodeByte = Encoding.Unicode.GetBytes( xml.InnerXml ); 
![]() inSignature = Convert.FromBase64String( signature );
  inSignature = Convert.FromBase64String( signature );                
![]() KeyedHashAlgorithm kha = KeyedHashAlgorithm.Create();
  KeyedHashAlgorithm kha = KeyedHashAlgorithm.Create(); 
![]() kha.Key = _key;
  kha.Key = _key; 
![]() outSignature = kha.ComputeHash( xmlNodeByte );
  outSignature = kha.ComputeHash( xmlNodeByte ); 
![]() return compareKeys( outSignature, inSignature );
  return compareKeys( outSignature, inSignature ); 
![]() } 
   
这两个Validate的重载方法使用一个私有的compareKeys来确认签名匹配。compareKeys函数在下面的代码中实现:
} 
   
这两个Validate的重载方法使用一个私有的compareKeys来确认签名匹配。compareKeys函数在下面的代码中实现: 
[VB.NET]
   ![]() Private Function compareKeys(ByVal firstKey() As Byte, ByVal secondKey() As Byte) _
Private Function compareKeys(ByVal firstKey() As Byte, ByVal secondKey() As Byte) _ 
![]() As Boolean
    As Boolean 
![]() If firstKey.Length <> secondKey.Length Then
  If firstKey.Length <> secondKey.Length Then 
![]() Return False
    Return False 
![]() End If
  End If 
![]() Dim i As Integer
  Dim i As Integer 
![]() For i = 0 To firstKey.Length - 1
  For i = 0 To firstKey.Length - 1 
![]() If firstKey(i) <> secondKey(i) Then
    If firstKey(i) <> secondKey(i) Then 
![]() Return False
      Return False 
![]() End If
    End If 
![]() Next i
  Next i 
![]() Return True
  Return True 
![]() End Function 
   
[C#]
End Function 
   
[C#] 
   ![]() private bool compareKeys( byte[] firstKey, byte[] secondKey )
private bool compareKeys( byte[] firstKey, byte[] secondKey ) 
![]() {
{ 
![]() if( firstKey.Length != secondKey.Length ) return false;
  if( firstKey.Length != secondKey.Length ) return false; 
![]() for( int i = 0 ; i < firstKey.Length; i++ )
  for( int i = 0 ; i < firstKey.Length; i++ ) 
![]() {
  { 
![]() if( firstKey[ i ] != secondKey[ i ] ) return false;
    if( firstKey[ i ] != secondKey[ i ] ) return false; 
![]() }
  } 
![]() return true;
  return true; 
![]() }
} 
   
KeyValidator配置
为了使用KeyValidator,你必须在应用程序升级器配置文件中包含一个<validator>元素,指定KeyValidator集合和类型的全名,以及你要使用的base64加密密钥。一个<validator>配置元素的例子如下所示:
   ![]() <validator type="Microsoft.ApplicationBlocks.ApplicationUpdater.Validators.KeyValidator" assembly="Microsoft.ApplicationBlocks.ApplicationUpdater,Version=1.0.0.0, Culture=neutral,PublicKeyToken=null">
<validator type="Microsoft.ApplicationBlocks.ApplicationUpdater.Validators.KeyValidator" assembly="Microsoft.ApplicationBlocks.ApplicationUpdater,Version=1.0.0.0, Culture=neutral,PublicKeyToken=null"> 
![]() <key>ACQAAASAAACUAAAABgIAAAAkAABS[etc.]</key>
<key>ACQAAASAAACUAAAABgIAAAAkAABS[etc.]</key>    
![]() </validator>
</validator> 
   
译者:Tony Qu
KeyValidator类提供一个基于对称密钥的验证器,该章节将介绍KeyValidator设计的以下几个方面:
问题描述
设计目标、权衡和问题
解决方案描述
具体实现
问题描述
一个通常使用的验证方法是使用对称密钥进行签名和验证数据。为了支持这项技术,必须实现一个基于对称密钥的验证器。
设计目标、权衡和问题
1. KeyValidator应该支持由.net的KeyedHashAlgorithm类支持的对称密钥。
2. 开发人员应该能够在应用程序升级器的配置文件中指定密钥,该密钥应该用base64字符串存储。如果没有密钥被指定,KeyValidator会抛出一个异常。
解决方案描述
KeyValidator类派生自IValidator接口,它使用.net的KeyedHashAlgorithm类基于一个对称密钥生成和验证签名。
具体实现
KeyValidator类由Microsoft.ApplicationBlocks.ApplicationUpdater.Validators命名空间实现。
实现KeyValidator需要考虑四个方面:
1. 密钥初始化
2. 签名
3. 验证
4. KeyValidator配置
密钥初始化
1. Init方法用于从应用程序升级器配置文件传递<validator>元素给KeyValidator类。该元素应该包含<key>子元素,该元素中以base64字符串存储密钥。<key>元素用于初始化验证密钥,该初始化过程代码在下面的代码片断中。
[VB.NET]
 Sub Init (ByVal config As XmlNode) Implements IValidator.Init
Sub Init (ByVal config As XmlNode) Implements IValidator.Init 
 Dim keyNode As XmlNode = config.SelectSingleNode( "key" )
  Dim keyNode As XmlNode = config.SelectSingleNode( "key" ) 
 _key = ExtractKeyFromNode (keyNode)
  _key = ExtractKeyFromNode (keyNode) 
 If _key Is Nothing Then
  If _key Is Nothing Then 
 'Throw a cryptographic exception
    'Throw a cryptographic exception 
 End If
  End If 
 End Sub
End Sub 
    void IValidator.Init( XmlNode config )
void IValidator.Init( XmlNode config ) 
 {
{                     
 XmlNode keyNode = config.SelectSingleNode( "key" );
  XmlNode keyNode = config.SelectSingleNode( "key" ); 
 _key = ExtractKeyFromNode( keyNode );
  _key = ExtractKeyFromNode( keyNode ); 
 if ( null == _key )
  if ( null == _key ) 
 {
  { 
 // Throw a cryptographic exception
    // Throw a cryptographic exception 
 }
  } 
 }
} 
   [VB.NET]
 Private Function ExtractKeyFromNode(ByVal keyNode As XmlNode) As Byte()
Private Function ExtractKeyFromNode(ByVal keyNode As XmlNode) As Byte() 
 Dim key As Byte() = Nothing
  Dim key As Byte() = Nothing 
 If keyNode Is Nothing Then
  If keyNode Is Nothing Then 
 Return Nothing
     Return Nothing 
 End If
  End If 
 Try
  Try 
 key = Convert.FromBase64String(keyNode.InnerText)
    key = Convert.FromBase64String(keyNode.InnerText) 
 Catch e As Exception
  Catch e As Exception 
 'exception handling code
    'exception handling code 
 End Try
  End Try 
 Return key
  Return key 
 End Function
End Function 
    private byte[] ExtractKeyFromNode( XmlNode keyNode )
private byte[] ExtractKeyFromNode( XmlNode keyNode ) 
 {
{ 
 byte[] key = null;
  byte[] key = null; 
 if ( null == keyNode )
  if ( null == keyNode ) 
 {
  { 
 return null;
    return null; 
 }
  } 
 try
  try 
 {
  { 
 key = Convert.FromBase64String( keyNode.InnerText );
    key = Convert.FromBase64String( keyNode.InnerText ); 
 }
  } 
 catch( Exception e )
  catch( Exception e ) 
 {
  {                         
 // exception handling code
    // exception handling code 
 }
  } 
 return key;
  return key; 
 }
} 
   签名
重载的Sign方法使用KeyedHashAlgorithm类生成hashed签名,下面的代码片断展示了这一过程:
[VB.NET]
 Overloads Function Sign(ByVal filePath As String, ByVal key As String) As String _
Overloads Function Sign(ByVal filePath As String, ByVal key As String) As String _ 
 Implements IValidator.Sign
    Implements IValidator.Sign  
 Dim outSignature As Byte() = Nothing
  Dim outSignature As Byte() = Nothing 
 Dim fs As FileStream = Nothing
  Dim fs As FileStream = Nothing 
 Try
  Try 
 fs = New FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read)
    fs = New FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read) 
 Dim kha As KeyedHashAlgorithm = KeyedHashAlgorithm.Create()
    Dim kha As KeyedHashAlgorithm = KeyedHashAlgorithm.Create() 
 kha.Key = Convert.FromBase64String(key)
    kha.Key = Convert.FromBase64String(key) 
 outSignature = kha.ComputeHash(fs)
    outSignature = kha.ComputeHash(fs) 
 Catch e As Exception
  Catch e As Exception 
 ' exception handling code
    ' exception handling code 
 Finally
  Finally 
 If Not (fs Is Nothing) Then
    If Not (fs Is Nothing) Then 
 fs.Close()
      fs.Close() 
 End If
     End If 
 End Try
   End Try 
 Return Convert.ToBase64String(outSignature)
   Return Convert.ToBase64String(outSignature) 
 End Function
End Function 
 
  
 Overloads Function Sign(ByVal xml As XmlNode, ByVal key As String) As String _
Overloads Function Sign(ByVal xml As XmlNode, ByVal key As String) As String _ 
 Implements IValidator.Sign
    Implements IValidator.Sign 
 Dim outSignature As Byte() = Nothing
  Dim outSignature As Byte() = Nothing 
 Dim xmlNodeByte As Byte() = Nothing
  Dim xmlNodeByte As Byte() = Nothing 
 xmlNodeByte = Encoding.Unicode.GetBytes(Xml.InnerXml)
  xmlNodeByte = Encoding.Unicode.GetBytes(Xml.InnerXml) 
 Try
  Try 
 Dim kha As KeyedHashAlgorithm = KeyedHashAlgorithm.Create()
    Dim kha As KeyedHashAlgorithm = KeyedHashAlgorithm.Create() 
 kha.Key = Convert.FromBase64String(key)
    kha.Key = Convert.FromBase64String(key) 
 outSignature = kha.ComputeHash(xmlNodeByte)
    outSignature = kha.ComputeHash(xmlNodeByte) 
 Catch e As Exception
  Catch e As Exception 
 'exception handling code
    'exception handling code 
 End Try
  End Try 
 Return Convert.ToBase64String(outSignature)
  Return Convert.ToBase64String(outSignature) 
 End Function
End Function 
    string IValidator.Sign( string filePath, string key )
string IValidator.Sign( string filePath, string key ) 
 {
{ 
 byte[] outSignature = null;
  byte[] outSignature = null; 
 FileStream fs = null;
  FileStream fs = null; 
 try
  try 
 {
  { 
 fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
    fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); 
 KeyedHashAlgorithm kha = KeyedHashAlgorithm.Create();
    KeyedHashAlgorithm kha = KeyedHashAlgorithm.Create(); 
 kha.Key = Convert.FromBase64String( key );
    kha.Key = Convert.FromBase64String( key ); 
 outSignature = kha.ComputeHash( fs );
    outSignature = kha.ComputeHash( fs );        
 }
  } 
 catch( Exception e )
  catch( Exception e ) 
 {
  { 
 // exception handling code
    // exception handling code 
 }
  } 
 finally
  finally 
 if ( null != fs )
    if ( null != fs ) 
 {
    { 
 fs.Close();
      fs.Close(); 
 }
    } 
 }
  } 
 return Convert.ToBase64String( outSignature );
  return Convert.ToBase64String( outSignature ); 
 }
} 
 
 
 string IValidator.Sign( XmlNode xml, string key )
string IValidator.Sign( XmlNode xml, string key ) 
 {
{ 
 byte[] outSignature = null;
  byte[] outSignature = null; 
 byte[] xmlNodeByte = null;
  byte[] xmlNodeByte = null; 
 xmlNodeByte = Encoding.Unicode.GetBytes( xml.InnerXml );
  xmlNodeByte = Encoding.Unicode.GetBytes( xml.InnerXml ); 
 try
  try 
 {
  { 
 KeyedHashAlgorithm kha = KeyedHashAlgorithm.Create();
    KeyedHashAlgorithm kha = KeyedHashAlgorithm.Create(); 
 kha.Key = Convert.FromBase64String( key );
    kha.Key = Convert.FromBase64String( key ); 
 outSignature = kha.ComputeHash( xmlNodeByte );
    outSignature = kha.ComputeHash( xmlNodeByte ); 
 }
  } 
 catch( Exception e )
  catch( Exception e ) 
 {
  { 
 // exception handling code
    // exception handling code 
 }
  } 
 return Convert.ToBase64String( outSignature );
  return Convert.ToBase64String( outSignature ); 
 }
} 
   验证
Validate方法使用相同的KeyedHashAlgorithm验证签名和密钥,该密钥用于生成签名。Validate方法在下面的代码片断中实现:
[VB.NET]
 Overloads Function Validate(ByVal filePath As String, ByVal signature As String) _
Overloads Function Validate(ByVal filePath As String, ByVal signature As String) _ 
 As Boolean Implements IValidator.Validate
    As Boolean Implements IValidator.Validate 
 
 
 Dim inSignature As Byte() = Nothing
  Dim inSignature As Byte() = Nothing 
 Dim outSignature As Byte() = Nothing
  Dim outSignature As Byte() = Nothing 
 inSignature = Convert.FromBase64String(signature)
  inSignature = Convert.FromBase64String(signature) 
 Dim fs As New FileStream(filePath, FileMode.Open)
  Dim fs As New FileStream(filePath, FileMode.Open) 
 Try
  Try 
 Dim kha As KeyedHashAlgorithm = KeyedHashAlgorithm.Create()
    Dim kha As KeyedHashAlgorithm = KeyedHashAlgorithm.Create() 
 kha.Key = _key
    kha.Key = _key 
 outSignature = kha.ComputeHash(fs)
    outSignature = kha.ComputeHash(fs) 
 Finally
  Finally 
 fs.Close()
    fs.Close() 
 End Try
  End Try 
 Return compareKeys(outSignature, inSignature)
  Return compareKeys(outSignature, inSignature) 
 End Function
End Function 
 
 
 Overloads Function Validate(ByVal xml As XmlNode, ByVal signature As String) _
Overloads Function Validate(ByVal xml As XmlNode, ByVal signature As String) _ 
 As Boolean Implements IValidator.Validate
    As Boolean Implements IValidator.Validate 
 
 
 Dim inSignature As Byte() = Nothing
   Dim inSignature As Byte() = Nothing 
 Dim outSignature As Byte() = Nothing
  Dim outSignature As Byte() = Nothing 
 Dim xmlNodeByte As Byte() = Nothing
  Dim xmlNodeByte As Byte() = Nothing 
 xmlNodeByte = Encoding.Unicode.GetBytes(Xml.InnerXml)
  xmlNodeByte = Encoding.Unicode.GetBytes(Xml.InnerXml) 
 inSignature = Convert.FromBase64String(signature)
  inSignature = Convert.FromBase64String(signature) 
 Dim kha As KeyedHashAlgorithm = KeyedHashAlgorithm.Create()
  Dim kha As KeyedHashAlgorithm = KeyedHashAlgorithm.Create() 
 kha.Key = _key
  kha.Key = _key 
 outSignature = kha.ComputeHash(xmlNodeByte)
  outSignature = kha.ComputeHash(xmlNodeByte) 
 Return compareKeys(outSignature, inSignature)
  Return compareKeys(outSignature, inSignature) 
 End Function
End Function 
    bool IValidator.Validate( string filePath, string signature )
bool IValidator.Validate( string filePath, string signature ) 
 {
{ 
 byte[] inSignature = null;
  byte[] inSignature = null; 
 byte[] outSignature = null;
  byte[] outSignature = null; 
 inSignature = Convert.FromBase64String( signature );
  inSignature = Convert.FromBase64String( signature ); 
 using ( FileStream fs = new FileStream( filePath, FileMode.Open ) )
  using ( FileStream fs = new FileStream( filePath, FileMode.Open ) ) 
 {
  { 
 KeyedHashAlgorithm kha = KeyedHashAlgorithm.Create();
    KeyedHashAlgorithm kha = KeyedHashAlgorithm.Create(); 
 kha.Key = _key;
    kha.Key = _key; 
 outSignature = kha.ComputeHash( fs );
    outSignature = kha.ComputeHash( fs ); 
 }
  } 
 return compareKeys( outSignature, inSignature );
  return compareKeys( outSignature, inSignature ); 
 }
}    
 
 
 bool IValidator.Validate( XmlNode xml, string signature )
bool IValidator.Validate( XmlNode xml, string signature ) 
 {
{ 
 byte[] inSignature = null;
  byte[] inSignature = null; 
 byte[] outSignature = null;
  byte[] outSignature = null; 
 byte[] xmlNodeByte = null;
  byte[] xmlNodeByte = null; 
 xmlNodeByte = Encoding.Unicode.GetBytes( xml.InnerXml );
  xmlNodeByte = Encoding.Unicode.GetBytes( xml.InnerXml ); 
 inSignature = Convert.FromBase64String( signature );
  inSignature = Convert.FromBase64String( signature );                
 KeyedHashAlgorithm kha = KeyedHashAlgorithm.Create();
  KeyedHashAlgorithm kha = KeyedHashAlgorithm.Create(); 
 kha.Key = _key;
  kha.Key = _key; 
 outSignature = kha.ComputeHash( xmlNodeByte );
  outSignature = kha.ComputeHash( xmlNodeByte ); 
 return compareKeys( outSignature, inSignature );
  return compareKeys( outSignature, inSignature ); 
 }
} 
   [VB.NET]
 Private Function compareKeys(ByVal firstKey() As Byte, ByVal secondKey() As Byte) _
Private Function compareKeys(ByVal firstKey() As Byte, ByVal secondKey() As Byte) _ 
 As Boolean
    As Boolean 
 If firstKey.Length <> secondKey.Length Then
  If firstKey.Length <> secondKey.Length Then 
 Return False
    Return False 
 End If
  End If 
 Dim i As Integer
  Dim i As Integer 
 For i = 0 To firstKey.Length - 1
  For i = 0 To firstKey.Length - 1 
 If firstKey(i) <> secondKey(i) Then
    If firstKey(i) <> secondKey(i) Then 
 Return False
      Return False 
 End If
    End If 
 Next i
  Next i 
 Return True
  Return True 
 End Function
End Function 
    private bool compareKeys( byte[] firstKey, byte[] secondKey )
private bool compareKeys( byte[] firstKey, byte[] secondKey ) 
 {
{ 
 if( firstKey.Length != secondKey.Length ) return false;
  if( firstKey.Length != secondKey.Length ) return false; 
 for( int i = 0 ; i < firstKey.Length; i++ )
  for( int i = 0 ; i < firstKey.Length; i++ ) 
 {
  { 
 if( firstKey[ i ] != secondKey[ i ] ) return false;
    if( firstKey[ i ] != secondKey[ i ] ) return false; 
 }
  } 
 return true;
  return true; 
 }
} 
   KeyValidator配置
为了使用KeyValidator,你必须在应用程序升级器配置文件中包含一个<validator>元素,指定KeyValidator集合和类型的全名,以及你要使用的base64加密密钥。一个<validator>配置元素的例子如下所示:
 <validator type="Microsoft.ApplicationBlocks.ApplicationUpdater.Validators.KeyValidator" assembly="Microsoft.ApplicationBlocks.ApplicationUpdater,Version=1.0.0.0, Culture=neutral,PublicKeyToken=null">
<validator type="Microsoft.ApplicationBlocks.ApplicationUpdater.Validators.KeyValidator" assembly="Microsoft.ApplicationBlocks.ApplicationUpdater,Version=1.0.0.0, Culture=neutral,PublicKeyToken=null"> 
 <key>ACQAAASAAACUAAAABgIAAAAkAABS[etc.]</key>
<key>ACQAAASAAACUAAAABgIAAAAkAABS[etc.]</key>    
 </validator>
</validator> 
   版权声明:本文由作者Tony Qu原创, 未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则视为侵权。
 
                     
                    
                 
                    
                

 
   
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号