Sage Pay错误3045:缺少货币字段。异常

时间:2015-07-22 04:56:34

标签: vb.net encryption aes sagepay

我正在尝试将sage付费版本从2.22升级到3.00,我正在使用Form Intergration将值提交给Sage。编写的代码是asp.net(VB)。在2.2中,它使用“SimpleXor加密算法”,但在版本3.00中不允许这样做,因此,我收到以下错误消息:

此交易尝试失败。我们无法将您重定向回您购买的网上商店。失败的细节如下。

Status: INVALID
Status Detail: 5068 : The encryption method is not supported by this protocol version.

我发现,版本3.00仅允许AES加密,并且我在类文件中添加了以下代码以进行加密:

Public Shared Function AESEncrypt(ByVal clearText As String) As String
        Dim EncryptionKey As String = "MAKV2SPBNI99212"
        Dim clearBytes As Byte() = Encoding.Unicode.GetBytes(clearText)
        Using encryptor As Aes = Aes.Create()
            Dim pdb As New Rfc2898DeriveBytes(EncryptionKey, New Byte() {&H49, &H76, &H61, &H6E, &H20, &H4D, _
             &H65, &H64, &H76, &H65, &H64, &H65, _
             &H76})
            encryptor.Key = pdb.GetBytes(32)
            encryptor.IV = pdb.GetBytes(16)
            Using ms As New MemoryStream()
                Using cs As New CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write)
                    cs.Write(clearBytes, 0, clearBytes.Length)
                    cs.Close()
                End Using
                clearText = Convert.ToBase64String(ms.ToArray())
            End Using
        End Using
        Return clearText
    End Function

在主.vb文件中,我更改了以下代码:

Dim strXOR As String = simpleXor(strPost, strEncryptionPassword)
strCrypt = base64Encode(strXOR)

Dim aesEncrypt As String = AESEncrypt(strPost)
strCrypt = "@" & aesEncrypt

抱歉,我对此感到很沮丧。我在我的类文件或主vb文件中是否有任何错误?在加密后我需要base64encode吗?

提前谢谢。

1 个答案:

答案 0 :(得分:0)

行。竞争回答重写。

抛弃你拥有的代码 - 我在另一个网站上找到它并且它无法正常工作。

相反,请使用下面的内容(我已经从here稍微调整了一下):

 Public Shared Function AESEncryption(ByVal strCrypt As String, ByVal strEncryptionPassword As String) As String

        Dim keyAndIvBytes As Byte() = UTF8Encoding.UTF8.GetBytes(strEncryptionPassword)

        Using AES As New RijndaelManaged()
            ' Set the mode, padding and block size for the key
            AES.Padding = PaddingMode.PKCS7
            AES.Mode = CipherMode.CBC
            AES.KeySize = 128
            AES.BlockSize = 128

            ' Encrypt the string to an array of bytes. 
            Dim encrypted As Byte() = EncryptStringToBytes(strCrypt, keyAndIvBytes, keyAndIvBytes)

            AESEncryption = "@" & BitConverter.ToString(encrypted).Replace("-", "").ToUpper
            ' System.Console.WriteLine(AESEncryption)
        End Using
    End Function

    Public Shared Function AESDecryption(ByVal strCrypt As String, ByVal strEncryptionPassword As String) As String

        Dim keyAndIvBytes As [Byte]() = UTF8Encoding.UTF8.GetBytes(strEncryptionPassword)

        ' Create a new instance of the RijndaelManaged 
        ' class.  This generates a new key and initialization  
        ' vector (IV). 
        Using AES As New RijndaelManaged()
            ' Set the mode, padding and block size for the key
            AES.Padding = PaddingMode.PKCS7
            AES.Mode = CipherMode.CBC
            AES.KeySize = 128
            AES.BlockSize = 128

            Dim encryptedData As Byte() = StringToByteArray(strCrypt.Remove(0, 1))

            Dim roundtrip As String = DecryptStringFromBytes(encryptedData, keyAndIvBytes, keyAndIvBytes)

            AESDecryption = roundtrip
        End Using
    End Function
    Shared Function byteArrayToHexString(ByVal ba As Byte()) As String
        Return BitConverter.ToString(ba).Replace("-", "")
    End Function
    Shared Function StringToByteArray(ByVal hex As String) As Byte()
        Return Enumerable.Range(0, hex.Length).Where(Function(x) x Mod 2 = 0).[Select](Function(x) Convert.ToByte(hex.Substring(x, 2), 16)).ToArray()
    End Function

    Shared Function EncryptStringToBytes(ByVal plainText As String, ByVal Key() As Byte, ByVal IV() As Byte) As Byte()
        ' Check arguments. 
        If plainText Is Nothing OrElse plainText.Length <= 0 Then
            Throw New ArgumentNullException("plainText")
        End If
        If Key Is Nothing OrElse Key.Length <= 0 Then
            Throw New ArgumentNullException("Key")
        End If
        If IV Is Nothing OrElse IV.Length <= 0 Then
            Throw New ArgumentNullException("IV")
        End If
        Dim encrypted() As Byte
        ' Create an RijndaelManaged object 
        ' with the specified key and IV. 
        Using AES As New RijndaelManaged()
            AES.Padding = PaddingMode.PKCS7
            AES.Mode = CipherMode.CBC
            AES.KeySize = 128
            AES.BlockSize = 128

            AES.Key = Key
            AES.IV = IV

            ' Create a decrytor to perform the stream transform. 
            Dim encryptor As ICryptoTransform = AES.CreateEncryptor(AES.Key, AES.IV)
            ' Create the streams used for encryption. 
            Using msEncrypt As New MemoryStream()
                Using csEncrypt As New CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)
                    Using swEncrypt As New StreamWriter(csEncrypt)

                        'Write all data to the stream.
                        swEncrypt.Write(plainText)
                    End Using
                    encrypted = msEncrypt.ToArray()
                End Using
            End Using
        End Using

        ' Return the encrypted bytes from the memory stream. 
        Return encrypted

    End Function 'EncryptStringToBytes

    Shared Function DecryptStringFromBytes(ByVal cipherText() As Byte, ByVal Key() As Byte, ByVal IV() As Byte) As String

        ' Check arguments. 
        If cipherText Is Nothing OrElse cipherText.Length <= 0 Then
            Throw New ArgumentNullException("cipherText")
        End If
        If Key Is Nothing OrElse Key.Length <= 0 Then
            Throw New ArgumentNullException("Key")
        End If
        If IV Is Nothing OrElse IV.Length <= 0 Then
            Throw New ArgumentNullException("IV")
        End If
        ' Declare the string used to hold 
        ' the decrypted text. 
        Dim plaintext As String = Nothing

        ' Create an RijndaelManaged object 
        ' with the specified key and IV. 
        Using AES As New RijndaelManaged
            AES.Padding = PaddingMode.PKCS7
            AES.Mode = CipherMode.CBC
            AES.KeySize = 128
            AES.BlockSize = 128

            'AES.Key = Key
            'AES.IV = IV

            ' Create a decrytor to perform the stream transform. 
            Dim decryptor As ICryptoTransform = AES.CreateDecryptor(Key, IV)

            ' Create the streams used for decryption. 
            Using msDecrypt As New MemoryStream(cipherText)

                Using csDecrypt As New CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)

                    Using srDecrypt As New StreamReader(csDecrypt)


                        ' Read the decrypted bytes from the decrypting stream 
                        ' and place them in a string.
                        plaintext = srDecrypt.ReadToEnd()
                    End Using
                End Using
            End Using
        End Using

        Return plaintext

    End Function

在你的main.vb文件中更改:

Dim strXOR As String = simpleXor(strPost, strEncryptionPassword)
strCrypt = base64Encode(strXOR)

要:

strCrypt=AESEncryption(strPost, strEncryptionPassword)