Customer area
2 big thumbs up to all of you and keep up the excellence.
Loading...
HOW TO: Call .NET assemblies from Kiwi Syslog Daemon

Kiwi Syslog Daemon's scripting engine (and just about every other scripting engine e.g. 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 un-signed 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.

<Assembly: AssemblyKeyFileAttribute("MyCryptoKeyPair.snk")>

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
    0 votes so far for this article. Did this article help you? YES NO