Welcome! Use the login menu to access:
Customer Portal
SolarWinds customers can download purchased software, renew maintenance, & more in our updated Customer Portal!
Community
After logging in, community members can rate & review SolarWinds software & participate in forums on thwack.com.
Partner Portal
SolarWinds channel partners will find all the resources they need in the Partner Portal, including exclusive partner tools.
| More

SolarWinds Knowledge Base

Call .NET assemblies from Kiwi Syslog Daemon

Kiwi Syslog Daemon's scripting engine (and just about every other scripting engine, eg. Windows Script Host), does not natively support direct calls to .NET assemblies. This is because .NET assemblies are not normally COM-callable, and scripting engines like Kiwi Syslog's and Window Script Host require that any externally referenced libraries are fully COM-compliant.

Luckily, there are a set of tools available as part of the .NET framework SDK that allow for any .NET assembly to become fully COM-capable, through the implementation of a COM-Callable Wrapper, Strong-name assembly signing and Assembly registration.

Say for example, that you have a .NET Class Library (DLL) that implements a .NET Cryptographic Service Provider, to enable DES/RC2 style encryption/decryption of text, based upon a secret key that you provide. This Article explains how to make such a .NET assembly COM-callable from a Kiwi Syslog Daemon RunScript (VBScript). This type of functionality can be very useful inside Kiwi Syslog Daemon, if you or your company has sensitive information that needs to be protected (because of some policy or legislative requirement), and that any potentially sensitive data is being logged in a protected format.

There are three basic steps required in making a .NET Class Library (DLL) COM-callable:

1) Create a Strong Name Key for you assembly
2) Sign your assembly with the Strong name, and rebuild it
3) Register your signed, strongly-named assembly
 

Strong names are better than weak ones... Just ask the Assembly Registration Tool.

Although you can register an assembly without a "Strong name" the assembly registration tool (regasm) wisely warns you that:

"Registering an unsigned assembly with /codebase can cause your assembly to interfere with other applications that may be installed on the same computer. The /codebase switch is intended to be used only with signed assemblies. Please give your assembly a strong name and re-register"

Okay... seems like we should sign that assembly a Strong Name. But first, we need to think of a strong name...

A strong name consists of the assembly's identity €” its simple text name, version number, and culture information (if provided) €” plus a public key and a digital signature. It is generated from an assembly file (the file that contains the assembly manifest, which in turn contains the names and hashes of all the files that make up the assembly), using the corresponding private key. Microsoft ® Visual Studio ® .NET and other development tools provided in the .NET Framework SDK can assign strong names to an assembly. Assemblies with the same strong name are expected to be identical.

To create a strong name for your assembly, use the Strong Name Tool (Sn.exe from the .NET Framework SDK) as follows:

sn -k MyCryptoKeyPair.snk

This command creates a new, random key pair and stores it in a file named MyCryptoKeyPair.snk.

If you don't have the Strong Name Tool (Sn.exe), it's available as part of the .NET Framework SDK download.
The .NET Framework SDK (v2.0) is available for download from:
http://msdn.microsoft.com/netframework/downloads/updates/default.aspx
(Don't worry it's only 350MB)

For those of you on version 1.0 or 1.1, older versions of the .NET Framework SDK (Software Development Kit) (v1.0-) are available from:
http://msdn.microsoft.com/netframework/downloads/updates/version1/default.aspx
(v1.1 SDK ~106MB)

SN.exe can normally be found in the bin directory of your SDK install. (C:Program FilesMicrosoft.NETSDKBinSn.exe)
 

Sign your name... Across my assembly.

To sign your assembly with the Strong Name you have just created, add a reference to the key file (.snk) in your class library code.

You will need to add the following line of code, just after any IMPORTS you have, and just before your CLASS begins.


 

For Example...

 

The following piece of code, written in VB.net, uses the Data Encryption Standard (DES) symmetric cryptographic algorithm.   Implementators that require use of other symmetric CryptoServiceProviders, simply need to replace the DESCryptServiceProvider with one of the following .NET Symmetric Cryptographic Algorithm Implementations:

  • DESCryptoServiceProvider
  • RijndaelManaged
  • RC2CryptoServiceProvider
  • TripleDESCryptoServiceProvider
  • You will need to ensure that the project is NOT registered for COM interop at this point.
    To check that; go to Project Properties, Config Properties, Build, and make sure that the "Register for COM Interop" is UNCHECKED.

    Compiled .Net Class Library Name: DotNetCryptoCOM.dll 

    Imports System.Reflection
    Imports System.Text
    Imports System.Security.Cryptography
     
    ' Sign the assembly with a Strong Name Key created with the .net Framework SDK 
    ' Strong Name Tool (Sn.exe).   This is important - it ensures that your assembly identity
    ' is sufficiently strong; so that it will not confict with other assemblies.
    ' 
    ' Sn.exe -k DotNetCryptoCOM.snk
    '
    ' During Compilation and Build, VS.net will look for the strong name key in the same
    ' location as your solution (.sln) file.   You may have to move the .snk file there before build.
    '
    ' Note: If you see the 'Error creating assembly manifest' during compilation, 
    '            you may have copied in the .snk file while the solution was open. You should
    '            try closing and re-opening the solution before the DLL will build successfully.
    <Assembly: AssemblyKeyFileAttribute("DotNetCryptoCOM.snk")> 
     
    ' Note: You will also need to ensure that the project is not set to register for 
    '            COM interop at this point.   To check, go to Project Properties, 
    '            Config Properties, Build, and make sure that the "Register for COM Interop" 
    '            is UNCHECKED.
    '            We will manually register the signed assembly for COM interop using the RegAsm tool
    '            after the DLL has been built.
     
    Public Class CryptoClass
     
           ' m_CryptoServiceProvider Defines a wrapper object to access the cryptographic service provider
           ' This example uses the Data Encryption Standard (DES) symmetric cryptographic algorithm
           '
           ' Implementators that require use of other symmetric CryptoServiceProviders, 
           ' simply need to replace the DESCryptServiceProvider with one of the following
           ' .Net Symmetric Cryptographic Algorithm Implementations:
           '   DESCryptoServiceProvider
           '   RijndaelManaged 
           '   RC2CryptoServiceProvider
           '   TripleDESCryptoServiceProvider
     
           Private m_CryptoServiceProvider As DESCryptoServiceProvider
     
           ' Create the new CryptoServiceProvider
           Public Sub New()
                  ' Replace the DESCryptoServiceProvider with another symmetric algoritm implementation if desired
                  m_CryptoServiceProvider = New DESCryptoServiceProvider
           End Sub
     
           ' Destroy the CryptoServiceProvider
           Protected Overrides Sub Finalize()
                  m_CryptoServiceProvider = Nothing
                  MyBase.Finalize()
           End Sub
     
           Public Function Encrypt(ByVal Source As String, ByVal Key As String) As String
     
                  Dim bytIn As Byte() = System.Text.Encoding.ASCII.GetBytes(Source)
                  ' Create a MemoryStream
                  Dim ms As System.IO.MemoryStream = New System.IO.MemoryStream
     
                  ' Ensure that the key is of legal size for the crypto algorithm
                  Dim bytKey As Byte() = GetLegalKey(Key)
     
                  ' Set the private key
                  m_CryptoServiceProvider.Key = bytKey
                  m_CryptoServiceProvider.IV = bytKey
     
                  ' Create an Encryptor from the Provider Service instance
                  Dim encrypto As ICryptoTransform = m_CryptoServiceProvider.CreateEncryptor()
     
                  ' Create Crypto Stream that transforms a stream using the encryption
                  Dim cs As CryptoStream = New CryptoStream(ms, encrypto, CryptoStreamMode.Write)
     
                  ' Write out encrypted content into MemoryStream
                  cs.Write(bytIn, 0, bytIn.Length)
                  cs.Close()
     
                  ' Convert into Base64
                  Dim encrypted As Byte()
                  encrypted = ms.ToArray
                  Return System.Convert.ToBase64String(encrypted, 0, encrypted.Length)
     
           End Function
     
           Public Function Decrypt(ByVal Source As String, ByVal Key As String) As String
     
                  ' Convert from Base64 to binary
                  Dim bytIn As Byte() = System.Convert.FromBase64String(Source)
                  ' Create a MemoryStream with the input
                  Dim ms As System.IO.MemoryStream = New System.IO.MemoryStream(bytIn, 0, bytIn.Length)
     
                  Dim bytKey As Byte() = GetLegalKey(Key)
     
                  ' Set the private key
                  m_CryptoServiceProvider.Key = bytKey
                  m_CryptoServiceProvider.IV = bytKey
     
                  ' Create a Decryptor from the Provider Service instance
                  Dim encrypto As ICryptoTransform = m_CryptoServiceProvider.CreateDecryptor()
     
                  ' Create Crypto Stream that transforms a stream using the decryption
                  Dim cs As CryptoStream = New CryptoStream(ms, encrypto, CryptoStreamMode.Read)
     
                  ' Read out the result from the Crypto Stream
                  Dim sr As System.IO.StreamReader = New System.IO.StreamReader(cs)
                  Return sr.ReadToEnd()
           End Function
     
           ' Depending on the legal key size limitations of a specific CryptoService provider
           ' and length of the private key provided, padding the secret key with space character
           ' to meet the legal size of the algorithm.
           Private Function GetLegalKey(ByVal Key As String) As Byte()
                  Dim sTemp As String
                  If (m_CryptoServiceProvider.LegalKeySizes.Length > 0) Then
     
                         Dim minSize As Integer = m_CryptoServiceProvider.LegalKeySizes(0).MinSize
                         Dim maxsize As Integer = m_CryptoServiceProvider.LegalKeySizes(0).MaxSize
                         ' Key sizes are in bits
                         If ((Key.Length * 8) > maxsize) Then
                                ' Trim key to max-key size
                                sTemp = Key.Substring(0, (maxsize / 8))
                         Else
                                If ((Key.Length * 8) < minSize) Then
                                       ' Pad small key to minsize length with space
                                       sTemp = Key.PadRight((minSize / 8), " ")
                                Else
                                       Dim lesssize As Integer = 0
                                       Dim moresize As Integer = minSize
                                       ' Get nearest Skipsize increment between minsize and maxsize that
                                       ' corresponds with key length
                                       Do While ((Key.Length * 8) > moresize)
                                              lesssize = moresize
                                              moresize += m_CryptoServiceProvider.LegalKeySizes(0).SkipSize
                                       Loop
                                       ' Pad mid-range key if necessary
                                       sTemp = Key.PadRight((moresize / 8), " ")
                                End If
                         End If
                  Else
                                sTemp = Key
                  End If
                  ' Convert the secret key to byte array
                  Return ASCIIEncoding.ASCII.GetBytes(sTemp)
           End Function
    End Class

    Compile and Build the .net class library, DotNetCryptoCOM.dll

    During Compilation and Build, VS.net will look for the strong name key in the same location as your solution (.sln) file. You will have to move the .snk file there before re-building the assembly.

    Note: If you see the 'Error creating assembly manifest' during compilation, you may have copied in the .snk file while the solution was open. You should try closing and re-opening the solution before the DLL will build successfully. Your assembly should build without error after that.
     

    Register the Signed Assembly.

    The Assembly Registration tool reads the metadata within an assembly and adds the necessary entries to the registry, which allows COM clients to create .NET Framework classes transparently. Once a class is registered, any COM client can use it as though the class were a COM class. The class is registered only once, when the assembly is installed. Instances of classes within the assembly cannot be created from COM until they are actually registered.

    RegAsm.exe can normally be found in (C:WINDOWSMicrosoft.NETFramework)

    To register your assembly:

    regasm /nologo /codebase DotNetCryptoCOM.dll
     

     

    Testing... 1... 2... 3...

    Kiwi Syslog Daemon RunScript Example Usage:

     

    ' Create a new CryptoServiceProvider
    Set oCryptoProvider = CreateObject("DotNetCryptoCOM.CryptoClass")
     
    ' Note: That the default CryptoServiceProvider for this class (in this case DES)
    ' has a key-size of exactly 64 bits. Other symmetric algorithm implementations
    ' require keys of different sizes, and increments. 
    ' The CryptoClass caters for all of these different key sizes through the
    ' LegalKeySizes symmetric algorithm property. Keys provided to the class are checked
    ' against the known minimum, maximum and skip key sizes for each algorithm. 
    ' Long keys will be clipped, short keys will be padded with spaces.
     
    ' Data to encrypt:
    strRawData = "All your base are belong to us"
     
    ' Encrypt the data with key "SECRETKEY"
    strEncryptedData = oCryptoProvider.Encrypt(strRawData,"SECRETKEY")
     
    ' Decrypt the encrypted data with the same key
    strDecryptedData = oCryptoProvider.Decrypt(strEncryptedData,"SECRETKEY")
     
    ' Write the a custom message to Custom01 (Fields.VarCustom01)
    Fields.VarCustom01 = "Encrypted Data: " & strEncryptedData & vbCrLf & "Decrypted Data: " & strDecryptedData
     
    ' Destroy the CryptoServiceProvider
    Set oCryptoProvider = Nothing

    VBScript Example Usage:

    ' Create a new CryptoServiceProvider
    Set oCryptoProvider = CreateObject("DotNetCryptoCOM.CryptoClass")
     
    ' Note: That the default CryptoServiceProvider for this class (in this case DES)
    ' has a key-size of exactly 64 bits. Other symmetric algorithm implementations
    ' require keys of different sizes, and increments. 
    ' The CryptoClass caters for all of these different key sizes through the
    ' LegalKeySizes symmetric algorithm property. Keys provided to the class are checked
    ' against the known minimum, maximum and skip key sizes for each algorithm. 
    ' Long keys will be clipped, short keys will be padded with spaces.
     
    ' Data to encrypt:
    strRawData = "All your base are belong to us"
     
    ' Encrypt the data with key "SECRETKEY"
    strEncryptedData = oCryptoProvider.Encrypt(strRawData,"SECRETKEY")
     
    ' Decrypt the encrypted data with the same key
    strDecryptedData = oCryptoProvider.Decrypt(strEncryptedData,"SECRETKEY")
     
    ' Message Popup
    MsgBox "Encrypted Data: " & strEncryptedData & vbCrLf & "Decrypted Data: " & strDecryptedData
     
    ' Destroy the CryptoServiceProvider
    Set oCryptoProvider = Nothing
    "


    Related Articles

    No related articles were found.

    Attachments

    No attachments were found.

    Visitor Comments

    No visitor comments posted. Post a comment

    Post Comment for "Call .NET assemblies from Kiwi Syslog Daemon"

    If this article does not provide the solution you need, please consider visiting our community forums on thwack or contacting SolarWinds Support. Please use the following form to provide comments that help us improve this KB article. Fields marked with an asterisk are required.

       Name:
    * Email:
    * Comment:
    * Enter the code below:

     

    Article Details

    Last Updated
    27th of August, 2010

    Would you like to...

    Print this page  Print this page

    Email this page  Email this page

    Post a comment  Post a comment

     Subscribe me

    Subscribe me  Add to favorites

    Remove Highlighting Remove Highlighting

    Edit this Article

    Quick Edit

    Export to PDF


    User Opinions

    No users have voted.

    How would you rate this answer?




    Thank you for rating this answer.

    Continue