2012-05-14 3 views
2

У меня возникла проблема с расшифровкой строки, зашифрованной в .NET. Я видел пару других решений здесь, в основном Decrypting a string in ColdFusion encrypted with 3DES in C#, но у меня все еще возникают проблемы с расшифровкой зашифрованной строки .NET, которая передается мне. Вот ошибка:Расшифровка строки в ColdFusion, зашифрованной с помощью 3DES в .NET.

«Произошла ошибка при попытке зашифровать или расшифровать вашу входную строку: если последний блок неправильно заполнен».

В дальнейших испытаниях, при запуске с тем же расшифрованным текстом, я получаю зашифрованную строку в CF, чем я в .NET

Вот код .NET, который используется для шифрования/дешифрование - Я заменил данные Key и IV с заполняющей информации:

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 

Здесь является CF-код, который шифрует/расшифровывает:

<!--- 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> 

Просто чтобы быть ясно - при попытке протестируйте этот код, я столкнулся с ошибками, расшифровывая зашифрованную строку .NET, поэтому я попробовал шифровать значение в CF, чтобы увидеть, получаю ли я одну и ту же зашифрованную строку.

В CF, 108644, кодируются в 63Yp6O + 8K + U =

В .NET, 108644, кодируются в 7loa00RCdZo =

Я в тупике. Я понятия не имею, куда идти отсюда. Любая помощь очень ценится!

ответ

2

ECB режим не использует вектор инициализации, поэтому он игнорируется. Вы должны изменить свой режим CBC:

<cfset theAlgorithm = "DESede/CBC/PKCS5Padding"> 

Edit: Разрабатывать, режим меняется в зависимости от того, какая функция кода .NET использует. Функция encrypt(key, data) использует режим ECB. В то время как EncryptBytes(text) неявно использует режим CBC, из-за наличия iv. Поэтому вам необходимо соответствующим образом изменить свой CF-код.

+0

Thanks Leigh - в функции Encrypt, он устанавливает Cyphermode в ECB, поэтому я думал, что должен был сделать то же самое. Ваше исправление работало (наряду с ними, давая мне правильный ключ и значения IV - по-видимому, те, которые они мне дали, были просто образцами). – Flavio

+0

Ли, я все время вижу эти вопросы - вопросы шифрования PHP или Java или .NET, связанные с CF. Я думаю, нам нужна серия статей wiki в теме. –

+0

Марк, ты читаешь мой разум. Я просто думал о наборе ресурсов, обсуждая общие вопросы, совместимость с gotchas и т. Д. Это была бы отличная идея. – Leigh