DES ECB Encryption cannot decrypt

From: Per Vestergaard-Laustsen (pvl_at_capto.dk)
Date: 05/08/03


Date: Thu, 8 May 2003 11:54:22 +0200


I am making an ActiveX component, and the application supposed to use it
only supports passing arguments as strings. Internally that particular
application only uses ASCII format for strings. I need to pass binary values
to and from the ActiveX component, where each byte can assume all values
from 0 to 255 (unsigned char).

By the way the crypto API still will not work.

I use DES, Mode=ECB. If I have the value to encrypt =
'01-47-11-00-00-00-00-00', the Key = 'EE-B7-55-E0-E7-35-B1-74' and IV =
'00-00-00-00-00-00-00-00'(since it should not be used when mode=ECB), then
when encrypting I get 'C0-30-76-FF-4D-2C-3C-C5-8B-03-5A-A1-96-FB-9C-3C'.

So far so good. But now when I try and decrypt that value, with the same Key
and IV, I get a bad data error. The Exception thrown has Hresult =
&HFFFFFFFF80131430 and _xcode = &HFFFFFFFFE0434F4D.

Best regards Per Vestergaard-Laustsen, Denmark

Code used :

Imports System

Imports System.Security.Cryptography 'in order to be able to en- / de- crypt

Imports System.IO 'in order to use streams or memorystreams

Imports System.Object 'in order to be able to create a BinaryReader

Imports System.NotSupportedException 'in order to troubleshoot not supported
exceptions

Imports System.Text.UTF8Encoding 'in order to be able to convert between
texts and bytearrays

<ComClass(Crypto.ClassId, Crypto.InterfaceId, Crypto.EventsId)> _

Public Class Crypto

#Region "COM GUIDs"

' These GUIDs provide the COM identity for this class

' and its COM interfaces. If you change them, existing

' clients will no longer be able to access the class.

Public Const ClassId As String = "E283E523-DDF6-41E5-99FD-D49BEA927F6B"

Public Const InterfaceId As String = "63468760-BECB-43D0-B001-D656E7D83519"

Public Const EventsId As String = "E42A8155-7740-4BE8-BB53-A845E0286A12"

#End Region

' A creatable COM class must have a Public Sub New()

' with no parameters, otherwise, the class will not be

' registered in the COM registry and cannot be created

' via CreateObject.

Public Sub New()

MyBase.New()

End Sub

Protected Overrides Sub Finalize()

MyBase.Finalize()

End Sub

Dim errPosition As String

Dim globalexception As CryptographicException

Public Sub test()

If "0655" <> decrypt(encrypt("0655", "09689036", "80682702"), "09689036",
"80682702") Then

Console.WriteLine("Decrypted : " + decrypt(encrypt("0655", "09689036",
"80682702"), "09689036", "80682702"))

Console.WriteLine("Unencrypted : " + "0655")

End If

End Sub

Public Function encrypt(ByRef textPIN As String, ByRef textKey As String,
ByRef textInitialValue As String) As String

On Error GoTo ErrorHandler

errPosition = "In encrypt function"

Dim PIN() As Byte

Dim Key() As Byte

Dim InitialValue() As Byte

PIN = GetEncryptKeyByteArray(textPIN)

Key = GetEncryptKeyByteArray(textKey)

InitialValue = GetEncryptKeyByteArray(textInitialValue)

Dim cryptPIN As MemoryStream

cryptPIN = New MemoryStream()

Dim encryption As ICryptoTransform

Dim cryptoService As New
System.Security.Cryptography.DESCryptoServiceProvider()

'cryptoService.Mode = CipherMode.ECB

encryption = cryptoService.CreateEncryptor(Key, InitialValue)

Dim encryptStream As New System.Security.Cryptography.CryptoStream(cryptPIN,
_

encryption, _

CryptoStreamMode.Write)

encryptStream.Write(PIN, 0, CInt(PIN.Length)) 'encrypt writing to the
encryptionstream

encryptStream.FlushFinalBlock() 'empty the temporary stream-buffer by force

encrypt = byte2str(cryptPIN.ToArray())

'close the streams that has been opened

encryptStream.Close()

cryptPIN.Close()

'destroy the objects that has been created and used

cryptPIN = Nothing

encryption = Nothing

cryptoService = Nothing

encryptStream = Nothing

Return encrypt

ErrorHandler:

textPIN = Err.Description

textKey = errPosition

End Function

Public Function decrypt(ByRef textPIN As String, ByRef textKey As String,
ByRef textInitialValue As String) As String

'On Error GoTo ErrorHandler

errPosition = "In decrypt function"

Dim i As Integer

Dim cryptPIN As MemoryStream

Dim PIN(15) As Byte

Dim Key(7) As Byte

Dim InitialValue(7) As Byte

PIN = GetDecryptKeyByteArray(textPIN)

Key = GetEncryptKeyByteArray(textKey)

InitialValue = GetEncryptKeyByteArray(textInitialValue)

cryptPIN = New MemoryStream()

Dim buffer(1024) As Byte

Dim decryption As ICryptoTransform

Dim cryptoService As New DESCryptoServiceProvider()

'cryptoService.Mode = CipherMode.ECB

decryption = cryptoService.CreateDecryptor(Key, InitialValue)

'the decryption takes place here

Dim decryptStream As New CryptoStream(cryptPIN, _

decryption, _

CryptoStreamMode.Write)

'temp TEST

Dim tempArrayOfByte(7) As Byte

For i = 0 To 7

tempArrayOfByte(i) = PIN(i)

Next

Try

decryptStream.Write(tempArrayOfByte, 0, CInt(tempArrayOfByte.Length))
'encrypt writing to the decryptionstream

Catch exception As CryptographicUnexpectedOperationException

globalexception = exception

GoTo errorhandler

End Try

Try

decryptStream.FlushFinalBlock() 'empty the temporary stream-buffer by force

Catch exception As CryptographicException

globalexception = exception

GoTo ErrorHandler

End Try

'end temp TEST

Try

decryptStream.Write(PIN, 0, CInt(PIN.Length)) 'encrypt writing to the
decryptionstream

Catch exception As CryptographicUnexpectedOperationException

globalexception = exception

GoTo errorhandler

End Try

Try

decryptStream.FlushFinalBlock() 'empty the temporary stream-buffer by force

Catch exception As CryptographicException

globalexception = exception

GoTo ErrorHandler

End Try

decrypt = byte2str(cryptPIN.ToArray())

'close the streams that has been opened

cryptPIN.Close()

decryptStream.Close()

'destroy all objects used

decryption = Nothing

globalexception = Nothing

cryptoService = Nothing

Return decrypt

ErrorHandler:

If globalexception.Message = "" Then

textPIN = Err.Description

textKey = errPosition

Else

Dim inner As Exception

textPIN = globalexception.Message

inner = globalexception.InnerException()

If Not inner Is Nothing Then

textKey = inner.Message

End If

textInitialValue = globalexception.Source

End If

End Function

Public Function calcXOR(ByVal Arg1 As Integer, ByVal Arg2 As Integer) As
Integer

calcXOR = Arg1 Xor Arg2

Return calcXOR

End Function

Private Function GetEncryptKeyByteArray(ByVal sPassword As String) As Byte()

Dim byteTemp(7) As Byte

'sPassword = sPassword.PadRight(8) ' make sure we have 8 chars

Dim a, b As String

Dim i, n As Integer

Dim bPW(7) As Byte

n = 0

For i = 1 To 22 Step 3

a = Asc(Mid(sPassword, i, 1)) - Asc("0")

If a > 9 Then a = a - 7

If a < 0 Or a > 15 Then

Err.Raise(vbObjectError + 513)

End If

b = Asc(Mid(sPassword, i + 1, 1)) - Asc("0")

If b > 9 Then b = b - 7

If b < 0 Or b > 15 Then

Err.Raise(vbObjectError + 513)

End If

bPW(n) = a * 16 + b

n += 1

Next i

'Dim iCharIndex As Integer

'For iCharIndex = 0 To sPassword.Length - 1

'byteTemp(iCharIndex) = Asc(Mid$(sPassword, iCharIndex + 1, 1))

'Next

'byteTemp = UTF8.GetBytes(sPassword)

Return bPW

End Function

Private Function GetDecryptKeyByteArray(ByVal sPassword As String) As Byte()

Dim byteTemp(15) As Byte

' sPassword = sPassword.PadRight(16) ' make sure we have 16 chars

Dim a, b As String

Dim i, n As Integer

Dim bPW(15) As Byte

n = 0

For i = 1 To 46 Step 3

a = Asc(Mid(sPassword, i, 1)) - Asc("0")

If a > 9 Then a = a - 7

If a < 0 Or a > 15 Then

Err.Raise(vbObjectError + 513)

End If

b = Asc(Mid(sPassword, i + 1, 1)) - Asc("0")

If b > 9 Then b = b - 7

If b < 0 Or b > 15 Then

Err.Raise(vbObjectError + 513)

End If

bPW(n) = a * 16 + b

n += 1

Next i

'Dim iCharIndex As Integer

'For iCharIndex = 0 To sPassword.Length - 1

'byteTemp(iCharIndex) = Asc(Mid$(sPassword, iCharIndex + 1, 1))

'Next

'byteTemp = UTF8.GetBytes(sPassword)

Return bPW

End Function

Private Function byte2str(ByRef bytes() As Byte) As String

errPosition = "In byte2str"

'Dim i As Integer

'Dim tmpString As String

'Dim tmpStringOneChar As String

'tmpString = ""

'errPosition = "Before for loop in byte2str"

'For i = 1 To bytes.Length - 1

'tmpStringOneChar = Chr(bytes(i))

'tmpString = tmpString + tmpStringOneChar

'errPosition = "In for loop in byte2str"

'Next

'errPosition = "After for loop in byte2str"

'byte2str = tmpString

byte2str = BitConverter.ToString(bytes)

errPosition = "Before return from byte2str"

Return byte2str

End Function

Public Function argtest(ByRef bytes As Byte()) As Object

Return bytes

End Function

End Class



Relevant Pages

  • RE: 2007 User Level Security
    ... encrypted string. ... the way I use it is to encrypt user names and passwords and store the ... Dim prp As Property ... Dim dbs As Object, prp As Variant ...
    (microsoft.public.access.modulesdaovba)
  • Re: Net.WebRequest/WebResponse ?s
    ... if the exception is a "WebExceptionStatus.ProtocolError" the exception variable will contain a pointer to an HTTPWebResponse object that can be used to get at the values I needed! ... Dim ErrResult As String = New ... Public Function GetResponsePWP(ByVal ReqURL As String, ByVal ReqTimeout As Integer, ByVal ReqType As String, ByVal PostData As String, ByVal UserName As String, ByVal Password As String) As String ... Dim nmsStatusCode As String = "" ...
    (microsoft.public.dotnet.languages.vb)
  • Search pattern
    ... Dim strfile As String ... Dim bAddressFound As Boolean ... Dim strCurrentChar As String ...
    (comp.databases.ms-access)
  • Auto Write Name and Merge across
    ... Dim Sheetname01 As String ... Dim WeekName01 As String ...
    (microsoft.public.excel.misc)
  • Re: multiplatform (pocketPC & desktopPC) (Daniel !!)
    ... Friend Versione As String ... Public Sub GetMyConnectionPalmare() ... Dim errorMessages As String ... Private Function GetDS_Desktop(ByVal SQL As String) As DataSet ...
    (microsoft.public.dotnet.framework.compactframework)