Encryption/Decryption on Pocket PC

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance

From: Haley (anonymous_at_discussions.microsoft.com)
Date: 03/22/04


Date: Mon, 22 Mar 2004 08:36:10 -0800

I need to be able to encrypt and decrypt sensitive strings on my VB.NET Pocket PC app. I copied code from the Microsoft
SignatureCapture application that uses the CryptoAPI. I can't get the Encrypt and Decrypt functions to work when I convert strings to byte arrays and pass them in the functions. The functions work fine with Byte arrays. Anyone have any ideas.

'My calling code

Dim byteEncrypted() As Byte
Dim strEncrypted As String

Dim strClearText As String = "somesensitivedata"
Dim byteClearText() As Byte

byteClearText = Encoding.ASCII.GetBytes(strClearText)
byteEncrypted = Crypto.Encrypt("212a658c-2edf-46e4-b550-ebe53b91e6b3", byteClearText)

strEncrypted = Encoding.ASCII.GetString(byteEncrypted, 0, byteEncrypted.GetUpperBound(0))

byteEncrypted = Encoding.ASCII.GetBytes(strEncrypted)
byteClearText = Crypto.Decrypt("212a658c-2edf-46e4-b550-ebe53b91e6b3", byteEncrypted)

strClearText = Encoding.ASCII.GetString(byteClearText, 0, byteClearText.GetUpperBound(0))

'***********************************************************************
' Crypto class imported from the SignatureCapture Microsoft app
' --
' Uses crypto API functions to encrypt and decrypt data. A passphrase
' string is used to create a 128-bit hash that is used to create a
' 40-bit crypto key. The same key is required to encrypt and decrypt
' the data.

Imports System.Runtime.InteropServices
Imports System.Text

' Encrypts and decrypts data using the crypto APIs.
Public Class Crypto

        ' API functions
        Private Class WinApi
#Region " Crypto API imports "

        Private Const ALG_CLASS_HASH As Integer = (4 << 13)
        Private Const ALG_TYPE_ANY As Integer = 0
        Private Const ALG_CLASS_DATA_ENCRYPT As Integer = (3 << 13)
        Private Const ALG_TYPE_STREAM As Integer = (4 << 9)
        Private Const ALG_TYPE_BLOCK As Integer = (3 << 9)

        Private Const ALG_SID_DES As Integer = 1
        Private Const ALG_SID_RC4 As Integer = 1
        Private Const ALG_SID_RC2 As Integer = 2
        Private Const ALG_SID_MD5 As Integer = 3

        Public Const MS_DEF_PROV As String = "Microsoft Base Cryptographic Provider v1.0"

        Public Const PROV_RSA_FULL As Integer = 1
        Public Const CRYPT_VERIFYCONTEXT As Integer = &HF0000000
        Public Const CRYPT_EXPORTABLE As Integer = &H1

        Public Shared ReadOnly CALG_MD5 As Integer = ALG_CLASS_HASH Or ALG_TYPE_ANY Or ALG_SID_MD5
        Public Shared ReadOnly CALG_DES As Integer = ALG_CLASS_DATA_ENCRYPT Or ALG_TYPE_BLOCK Or ALG_SID_DES
        Public Shared ReadOnly CALG_RC2 As Integer = ALG_CLASS_DATA_ENCRYPT Or ALG_TYPE_BLOCK Or ALG_SID_RC2
        Public Shared ReadOnly CALG_RC4 As Integer = ALG_CLASS_DATA_ENCRYPT Or ALG_TYPE_STREAM Or ALG_SID_RC4

#If COMPACT_FRAMEWORK Then
        Private Const CryptDll As String = "coredll.dll"
        Private Const KernelDll As String = "coredll.dll" '
#Else
        Private Const CryptDll As String = "advapi32.dll"
        Private Const KernelDll As String = "kernel32.dll" '
#End If

        <DllImport(CryptDll)> _
        Public Shared Function CryptAcquireContext( _
                ByRef phProv As IntPtr, ByVal pszContainer As String, _
                ByVal pszProvider As String, ByVal dwProvType As Integer, _
                ByVal dwFlags As Integer) As Boolean
        End Function

        <DllImport(CryptDll)> _
        Public Shared Function CryptReleaseContext( _
                ByVal hProv As IntPtr, ByVal dwFlags As Integer) As Boolean
        End Function

        <DllImport(CryptDll)> _
        Public Shared Function CryptDeriveKey( _
                ByVal hProv As IntPtr, ByVal Algid As Integer, _
                ByVal hBaseData As IntPtr, ByVal dwFlags As Integer, _
                ByRef phKey As IntPtr) As Boolean
        End Function

        <DllImport(CryptDll)> _
        Public Shared Function CryptCreateHash( _
                ByVal hProv As IntPtr, ByVal Algid As Integer, _
                ByVal hKey As IntPtr, ByVal dwFlags As Integer, _
                ByRef phHash As IntPtr) As Boolean
        End Function

        <DllImport(CryptDll)> _
        Public Shared Function CryptHashData( _
                ByVal hHash As IntPtr, ByVal pbData() As Byte, ByVal dwDataLen As Integer, _
                ByVal dwFlags As Integer) As Boolean
        End Function

        <DllImport(CryptDll)> _
        Public Shared Function CryptEncrypt( _
                ByVal hKey As IntPtr, ByVal hHash As IntPtr, _
                ByVal Final As Boolean, ByVal dwFlags As Integer, _
                ByVal pbData() As Byte, ByRef pdwDataLen As Integer, _
                ByVal dwBufLen As Integer) As Boolean
        End Function

        <DllImport(CryptDll)> _
        Public Shared Function CryptDecrypt( _
                ByVal hKey As IntPtr, ByVal hHash As IntPtr, _
                ByVal Final As Boolean, ByVal dwFlags As Integer, _
                ByVal pbData() As Byte, ByRef pdwDataLen As Integer) As Boolean
        End Function

        <DllImport(CryptDll)> _
        Public Shared Function CryptDestroyHash(ByVal hHash As IntPtr) As Boolean
        End Function

        <DllImport(CryptDll)> _
        Public Shared Function CryptDestroyKey(ByVal hKey As IntPtr) As Boolean
        End Function

#End Region

#Region " Error reporting imports "

        Public Const FORMAT_MESSAGE_FROM_SYSTEM As Integer = &H1000

        <DllImport(KernelDll)> _
        Public Shared Function GetLastError() As Integer
        End Function

        <DllImport(KernelDll)> _
        Public Shared Function FormatMessage( _
                ByVal dwFlags As Integer, ByVal lpSource As String, _
                ByVal dwMessageId As Integer, ByVal dwLanguageId As Integer, _
                ByVal lpBuffer As StringBuilder, ByVal nSize As Integer, _
                ByVal Arguments() As String) As Integer
        End Function

#End Region
        End Class

        ' all static methods
        Private Sub New()
        End Sub

        ' Encrypt data. Use passphrase to generate the encryption key.
        ' Returns a byte array that contains the encrypted data.
        Public Shared Function Encrypt(ByVal passphrase As String, ByVal data() As Byte) As Byte()
                ' holds encrypted data
                Dim buffer As Byte() = Nothing

                ' crypto handles
                Dim hProv As IntPtr = IntPtr.Zero
                Dim hKey As IntPtr = IntPtr.Zero

                Try
                        ' get crypto provider, specify the provider (3rd argument)
                        ' instead of using default to ensure the same provider is
                        ' used on client and server
                        If Not WinApi.CryptAcquireContext(hProv, Nothing, WinApi.MS_DEF_PROV, WinApi.PROV_RSA_FULL, WinApi.CRYPT_VERIFYCONTEXT) Then
                                Failed("CryptAcquireContext")
                        End If

                        ' generate encryption key from passphrase
                        hKey = GetCryptoKey(hProv, passphrase)

                        ' determine how large of a buffer is required
                        ' to hold the encrypted data
                        Dim dataLength As Integer = data.Length
                        Dim bufLength As Integer = data.Length

                        If Not WinApi.CryptEncrypt(hKey, IntPtr.Zero, True, 0, Nothing, dataLength, bufLength) Then
                                Failed("CryptEncrypt")
                        End If

                        ' allocate and fill buffer with encrypted data
                        buffer = New Byte(dataLength - 1) {}
                        System.Buffer.BlockCopy(data, 0, buffer, 0, data.Length)

                        dataLength = data.Length
                        bufLength = buffer.Length
                        If Not WinApi.CryptEncrypt(hKey, IntPtr.Zero, True, 0, buffer, dataLength, bufLength) Then
                                Failed("CryptEncrypt")
                        End If
                Finally
                        ' release crypto handles
                        If Not hKey.Equals(IntPtr.Zero) Then
                                WinApi.CryptDestroyKey(hKey)
                        End If

                        If Not hProv.Equals(IntPtr.Zero) Then
                                WinApi.CryptReleaseContext(hProv, 0)
                        End If
                End Try

                Return buffer
        End Function

        ' Decrypt data. Use passphrase to generate the encryption key.
        ' Returns a byte array that contains the decrypted data.
        Public Shared Function Decrypt(ByVal passphrase As String, ByVal data() As Byte) As Byte()
                ' make a copy of the encrypted data
                Dim dataCopy As Byte() = CType(data.Clone(), Byte())

                ' holds the decrypted data
                Dim buffer As Byte() = Nothing

                ' crypto handles
                Dim hProv As IntPtr = IntPtr.Zero
                Dim hKey As IntPtr = IntPtr.Zero

                Try
                        ' get crypto provider, specify the provider (3rd argument)
                        ' instead of using default to ensure the same provider is
                        ' used on client and server
                        If Not WinApi.CryptAcquireContext(hProv, Nothing, WinApi.MS_DEF_PROV, WinApi.PROV_RSA_FULL, WinApi.CRYPT_VERIFYCONTEXT) Then
                                Failed("CryptAcquireContext")
                        End If

                        ' generate encryption key from the passphrase
                        hKey = GetCryptoKey(hProv, passphrase)

                        ' decrypt the data
                        Dim dataLength As Integer = dataCopy.Length
                        If Not WinApi.CryptDecrypt(hKey, IntPtr.Zero, True, 0, dataCopy, dataLength) Then
                                Failed("CryptDecrypt")
                        End If

                        ' copy to a buffer that is returned to the caller
                        ' the decrypted data size might be less then
                        ' the encrypted size
                        buffer = New Byte(dataLength - 1) {}
                        System.Buffer.BlockCopy(dataCopy, 0, buffer, 0, dataLength)
                Finally
                        ' release crypto handles
                        If Not hKey.Equals(IntPtr.Zero) Then
                                WinApi.CryptDestroyKey(hKey)
                        End If

                        If Not hProv.Equals(IntPtr.Zero) Then
                                WinApi.CryptReleaseContext(hProv, 0)
                        End If
                End Try

                Return buffer
        End Function

.....



Relevant Pages

  • Key derivation in c++ and VB.NET
    ... I am trying to encrypt data in c++ and decrypt in VB.NET. ... System.Cryptography classes don't align exactly with the CryptoAPI ... Dim bHash As PasswordDeriveBytes ...
    (microsoft.public.dotnet.security)
  • Ugh, at my whits end and in desperate need of help.
    ... I can create and encrypt a message ... with the public key without a problem, but when I try to decrypt the message ... Dim privatecert As New X509Certificate2 ...
    (microsoft.public.security)
  • Re: Need help decrypting
    ... Just a brief look: in your encrypt function you ... > I'm wondering if somebody can help me figure out how to decrypt data. ... > Private Sub Encryptpwd() ... > Dim ms As New MemoryStream ...
    (microsoft.public.dotnet.security)
  • RSACryptoServiceProvider problem with bad Key
    ... I encrypt using the public key, but when I decrypt using the private key I ... Dim privatecert As New X509Certificates.X509Certificate2 ...
    (microsoft.public.dotnet.security)
  • RE: Cryptography, Encryption, Decryption Help
    ... I changed the Encrypt and Decrypt functions in the Crypto.vb class to take in strings instead of Byte arrays. ... Dim EncryptString As String ...
    (microsoft.public.pocketpc.developer)