解密ColdFusion中的一个字符串,用.NET中的3DES加密

时间:2012-05-14 15:39:09

标签: .net encryption coldfusion 3des

我无法解密在.NET中加密的字符串。我在这里看到了其他几个解决方案,主要是Decrypting a string in ColdFusion encrypted with 3DES in C#但是我仍然在尝试解密传递给我的.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 =

我陷入了僵局。我不知道从哪里开始。非常感谢任何帮助!

1 个答案:

答案 0 :(得分:2)

ECB模式不使用初始化向量,因此会被忽略。您需要将模式更改为CBC

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

编辑:详细说明,模式因.NET代码使用的功能而异。 encrypt(key, data)函数使用ECB模式。由于存在EncryptBytes(text)CBC隐式使用iv模式。因此,您需要相应地更改CF代码。