Reputation: 33
I'm having trouble decrypting a string that was encrypted in .NET. I saw a couple other solutions on here, mainly Decrypting a string in ColdFusion encrypted with 3DES in C# but I'm still having issues trying to decrypt the .NET encrypted string that is being passed to me. Here is the error:
"An error occurred while trying to encrypt or decrypt your input string: Given final block not properly padded."
In further testing, when starting out with the same decrypted text, I am getting a different encrypted string in CF than I am in .NET
Here is the .NET code that is being used to encrypt/decrypt - I replaced the Key and IV data with fill-in info:
Imports System.IO
Imports System.Text
Imports System.Security.Cryptography
Public Class TripleDES
' define the triple des provider
Private Shared m_des As New TripleDESCryptoServiceProvider
' define the string handler
Private m_utf8 As New UTF8Encoding
' define the local property arrays
Private m_key() As Byte
Private m_iv() As Byte
Private key As String = "48-digit hex key"
Private iv As String = "16-digit hex iv"
Public Sub New()
Me.m_key = convertHexStringToByteArray(key)
Me.m_iv = convertHexStringToByteArray(iv)
End Sub
Public Sub New(ByVal _key As String, ByVal _iv As String)
key = _key
iv = _iv
Me.m_key = convertHexStringToByteArray(key)
Me.m_iv = convertHexStringToByteArray(iv)
End Sub
Public Sub New(ByVal _key() As Byte, ByVal _iv() As Byte)
Me.m_key = _key
Me.m_iv = _iv
End Sub
Public Function Encryptfrombyte(ByVal input() As Byte) As Byte()
Return Transform(input, m_des.CreateEncryptor(m_key, m_iv))
End Function
Public Function EncryptBytes(ByVal text As String) As Byte()
Dim input() As Byte = m_utf8.GetBytes(text)
Dim DesEnc As ICryptoTransform = m_des.CreateEncryptor(m_key, m_iv)
Dim output() As Byte = Transform(input, DesEnc)
Return output 'convertByteArrayToHexString(output)
End Function
Public Function encrypt(ByVal key As Byte(), ByVal data As Byte()) As Byte()
Dim des As TripleDESCryptoServiceProvider = New TripleDESCryptoServiceProvider
des.Key = key
des.Mode = CipherMode.ECB
des.Padding = PaddingMode.PKCS7
Return des.CreateEncryptor.TransformFinalBlock(data, 0, data.Length)
End Function
Public Function Decrypt(ByVal input() As Byte) As String
Dim DesEnc As ICryptoTransform = m_des.CreateDecryptor(m_key, m_iv)
Dim output() As Byte = Transform(input, DesEnc)
Return m_utf8.GetString(output)
End Function
Public Function Decrypt(ByVal text As String) As String
Dim input() As Byte = m_utf8.GetBytes(text)
Dim output() As Byte = Transform(input, _
m_des.CreateDecryptor(m_key, m_iv))
Return m_utf8.GetString(output)
End Function
Private Function Transform(ByVal input() As Byte, _
ByVal CryptoTransform As ICryptoTransform) As Byte()
' create the necessary streams
Dim memStream As MemoryStream = New MemoryStream
Dim cryptStream As CryptoStream = New _
CryptoStream(memStream, CryptoTransform, _
CryptoStreamMode.Write)
' transform the bytes as requested
cryptStream.Write(input, 0, input.Length)
cryptStream.FlushFinalBlock()
' Read the memory stream and convert it back into byte array
memStream.Position = 0
Dim result(CType(memStream.Length - 1, System.Int32)) As Byte
memStream.Read(result, 0, CType(result.Length, System.Int32))
' close and release the streams
memStream.Close()
cryptStream.Close()
' hand back the encrypted buffer
Return result
End Function
Public Function convertHexStringToByteArray(ByVal str As String) As Byte()
'//String in Hex - 2 chars represet a byte.
Dim size As Integer = (str.Length() / 2) - 1
Dim b(size) As Byte
'ReDim b str.Length() / 2
Dim j As Integer = 0
Try
For i As Integer = 0 To str.Length() - 1 Step 2
Dim s As String = str.Substring(i, 2)
'//parse the substring as an integer, as the 8th bit may be set
Dim k As Integer = Convert.ToInt32(s, 16)
'//downcast integer to byte, this down casting does not do any
' //harm since memory footprint of first 8 bits remains same.
b(j) = New Byte
b(j) = CType(k, Byte)
j += 1
Next
Catch e As Exception
Dim ti As String = 1
'TraceLog.trace2(e)
End Try
Return b
End Function
Public Function convertByteArrayToHexString(ByVal b() As Byte) As String
Dim buffer As String
' Dim hexDigit() As String = Split("0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f", "', '")
For i As Integer = 0 To b.Length - 1
'dim array as char()= (hexDigit((b(i) >> 4) & chr(0x0f)), hexDigit(b(i) & 0x0f))
Dim tmp As String = Hex(b(i))
If tmp.Length = 1 Then
tmp = "0" & tmp
End If
buffer += (tmp)
Next
Return buffer.ToString()
End Function
Public Function bytetoHex(ByVal hextBt() As Byte) As String
Dim disc As Integer = 0
bytetoHex = HexEncoding.ToString(hextBt)
End Function
Public Function hexToByte(ByVal hex As String) As Byte()
Dim disc As Integer = 0
hexToByte = HexEncoding.hexidecimaltoByte(hex)
End Function
End Class
Here is the CF code that encrypts/decrypts:
<!--- Get The Key from Hex to base64 --->
<cfset theKeyHex = "48-digit hex key" />
<cfset theKeyBin = BinaryDecode(theKeyHex,"hex")>
<cfset theKeyB64 = BinaryEncode(theKeyBin,"base64")>
<!--- Get the IV to Binary --->
<cfset theIV = "16-digit hex iv" />
<cfset theIVBin = BinaryDecode(theIV,"hex")>
<!--- Define Encoding parameters --->
<cfset theAlgorithm = "DESede/ECB/PKCS5Padding">
<cfset theEncoding = "Base64">
<!--- Define string --->
<cfset str = "108644" >
<cfoutput>
<cfset enc = Encrypt(str, theKeyB64, theAlgorithm, theEncoding, theIVBin)>
encrypted = #enc#<br />
<cfset dec = Decrypt(enc, theKeyB64, theAlgorithm, theEncoding, theIVBin)>
decrypted = #dec#<br />
</cfoutput>
Just to be clear - while trying to test this code, I was running into errors decrypting the .NET encrypted string, so I tried encrypting the value in CF to see if I get the same encrypted string.
In CF, 108644 gets encrypted to 63Yp6O+8K+U=
In .NET, 108644 gets encrypted to 7loa00RCdZo=
I'm at an impasse. I have no idea where to go from here. Any help is greatly appreciated!
Upvotes: 2
Views: 2106
Reputation: 28873
ECB
mode does not use an initialization vector, so it is ignored. You need to change your mode to CBC
:
<cfset theAlgorithm = "DESede/CBC/PKCS5Padding">
Edit: To elaborate, the mode varies depending on which function the .NET code uses. The encrypt(key, data)
function uses ECB
mode. While EncryptBytes(text)
implicitly uses CBC
mode, due to the presence of an iv
. So you need to alter your CF code accordingly.
Upvotes: 2