我已经提供了一个VB.NET脚本(我不是.NET程序员,所以我对其工作原理的理解有限),它旨在执行加密。我需要在PHP应用程序和.NET应用程序之间加密/解密数据。
我提供了VB.NET中提供的加密库的源代码。有人可以协助分析对Key + IV(填充)进行的操作类型,以帮助我在PHP应用程序中重现相同的加密吗?我相信我遇到的所有问题都来自编码/填充中的一些微妙之处。
VB脚本如下,我在PHP中使用mcrypt和TripleDES CBC密码。我符合16/24字节密钥和16字节IV
Option Strict On
Option Explicit On
Imports System.IO
Imports System.Security.Cryptography
Imports System.Text
Namespace Company.Tools
Public Class Crypto
'256 Bit IV Key that is truncated when a smaller keys are required
Public Property IV As Byte() = {0, 0, 0, 0, 0, 0, 0, 0}
' define the local property arrays
Public Property Key As Byte()
Public Property PaddingCharacter As Char = Chr(0)
'Supported .Net intrinsic SymmetricAlgorithm classes.
Public Enum Providers
DES
RC2
Rijndael
TripleDES
AES
End Enum
'Encryption/Decryption possible output formats
Public Enum TextFormat
Base64
UTF8
URL
Ascii
Hex
End Enum
Public CryptoService As SymmetricAlgorithm
Public Sub New(ByVal NetSelected As Providers)
'Constructor for using an intrinsic .Net SymmetricAlgorithm class.
Select Case NetSelected
Case Providers.DES
CryptoService = New DESCryptoServiceProvider
Case Providers.RC2
CryptoService = New RC2CryptoServiceProvider
Case Providers.Rijndael
CryptoService = New RijndaelManaged
Case Providers.TripleDES
CryptoService = New TripleDESCryptoServiceProvider
Case Providers.AES
CryptoService = New AesCryptoServiceProvider
CryptoService.Padding = PaddingMode.PKCS7
End Select
End Sub
Public Sub New(ByVal NetSelected As Providers, Key As String, Optional PaddingCharacter As Char = Chr(0))
Me.New(NetSelected)
Me.PaddingCharacter = PaddingCharacter
Me.Key = GetLegalKey(Key)
End Sub
Public Sub New(ByVal NetSelected As Providers, Key As String, IV As Byte(), Optional PaddingCharacter As Char = Chr(0))
Me.New(NetSelected)
Me.PaddingCharacter = PaddingCharacter
Me.Key = GetLegalKey(Key)
Me.IV = IV
End Sub
'Constructor for using a customized SymmetricAlgorithm class.
Public Sub New(ByVal ServiceProvider As SymmetricAlgorithm)
CryptoService = ServiceProvider
End Sub
'Depending on the legal key size limitations of a specific CryptoService provider
'and length of the private key provided, padding the secret key with a character
'or triming it to meet the legal size of the algorithm.
Private Function GetLegalKey(ByVal Key As String) As Byte()
'key sizes are in bits
Dim sTemp As String
If (CryptoService.LegalKeySizes.Length > 0) Then
Dim maxSize As Integer = CryptoService.LegalKeySizes(0).MaxSize
If Key.Length * 8 > maxSize Then
sTemp = Key.Substring(0, CInt((maxSize / 8)))
Else
Dim moreSize As Integer = CryptoService.LegalKeySizes(0).MinSize
Do While (Key.Length * 8 > moreSize)
moreSize += CryptoService.LegalKeySizes(0).SkipSize
Loop
sTemp = Key.PadRight(CInt(moreSize / 8), PaddingCharacter)
End If
Else
sTemp = Key
End If
'Ensure that the IV Block size is also correct for the specific CryptoService provider
If (CryptoService.LegalBlockSizes.Length > 0) Then
Dim maxSize As Integer = CryptoService.LegalBlockSizes(0).MaxSize
ReDim Preserve IV(sTemp.Length - 1)
If sTemp.Length * 8 > maxSize Then
ReDim Preserve IV(CInt(maxSize / 8) - 1)
End If
End If
'convert the secret key to byte array
Return System.Text.ASCIIEncoding.ASCII.GetBytes(sTemp)
End Function
Public Function Encrypt(ByVal input() As Byte) As Byte()
Return Transform(input, CryptoService.CreateEncryptor(Me.Key, Me.IV))
End Function
Public Function Decrypt(ByVal input() As Byte) As Byte()
Return Transform(input, CryptoService.CreateDecryptor(Me.Key, Me.IV))
End Function
Public Function Encrypt(ByVal text As String,
Optional InputFormat As TextFormat = TextFormat.UTF8,
Optional OutputFormat As TextFormat = TextFormat.UTF8) As String
Dim input() As Byte
Dim sResult As String = String.Empty
Select Case InputFormat
Case TextFormat.Base64
input = Convert.FromBase64String(text)
Case TextFormat.UTF8
input = System.Text.UTF8Encoding.UTF8.GetBytes(text)
Case TextFormat.URL
input = System.Web.HttpUtility.UrlDecodeToBytes(text)
Case TextFormat.Ascii
input = System.Text.ASCIIEncoding.ASCII.GetBytes(text)
Case TextFormat.Hex
input = DecryptFromHexa(text)
Case Else
input = System.Text.UTF8Encoding.UTF8.GetBytes(text)
End Select
Dim output() As Byte = Transform(input, _
CryptoService.CreateEncryptor(Me.Key, Me.IV))
Select Case OutputFormat
Case TextFormat.Base64
sResult = Convert.ToBase64String(output)
Case TextFormat.UTF8
sResult = System.Text.UTF8Encoding.UTF8.GetString(output)
Case TextFormat.URL
sResult = System.Web.HttpUtility.UrlEncode(output)
Case TextFormat.Ascii
sResult = Encoding.ASCII.GetString(output)
Case TextFormat.Hex
sResult = EncryptAsHexa(output)
Case Else
sResult = System.Text.UTF8Encoding.UTF8.GetString(output)
End Select
Return sResult
End Function
Public Overridable Function Decrypt(ByVal text As String,
Optional InputFormat As TextFormat = TextFormat.UTF8,
Optional OutputFormat As TextFormat = TextFormat.UTF8) As String
Dim input() As Byte
Dim sResult As String = String.Empty
Select Case InputFormat
Case TextFormat.Base64
input = Convert.FromBase64String(text)
Case TextFormat.UTF8
input = System.Text.UTF8Encoding.UTF8.GetBytes(text)
Case TextFormat.URL
input = System.Web.HttpUtility.UrlDecodeToBytes(text)
Case TextFormat.Ascii
input = System.Text.ASCIIEncoding.ASCII.GetBytes(text)
Case TextFormat.Hex
input = DecryptFromHexa(text)
Case Else
input = System.Text.UTF8Encoding.UTF8.GetBytes(text)
End Select
Dim output() As Byte = Transform(input, _
CryptoService.CreateDecryptor(Me.Key, Me.IV))
Select Case OutputFormat
Case TextFormat.Base64
sResult = Convert.ToBase64String(output)
Case TextFormat.UTF8
sResult = System.Text.UTF8Encoding.UTF8.GetString(output)
Case TextFormat.URL
sResult = System.Web.HttpUtility.UrlEncode(output)
Case TextFormat.Ascii
sResult = Encoding.ASCII.GetString(output)
Case TextFormat.Hex
sResult = EncryptAsHexa(output)
Case Else
sResult = System.Text.UTF8Encoding.UTF8.GetString(output)
End Select
Return sResult
End Function
Public 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 EncryptAsHexa(ByVal text As Byte()) As String
Dim oBuilder As New System.Text.StringBuilder()
For Each b As Byte In text
oBuilder.AppendFormat("{0:x2}", b)
Next
Return oBuilder.ToString()
End Function
Public Function DecryptFromHexa(ByVal text As String) As Byte()
Dim NumberChars As Integer = text.Length
Dim result As Byte() = New Byte(NumberChars \ 2 - 1) {}
For i As Integer = 0 To NumberChars - 1 Step 2
result(i \ 2) = Convert.ToByte(text.Substring(i, 2), 16)
Next
Return result
End Function
End Class
End Namespace