使用MCRYPT_RIJNDAEL_256的PHP加密库对应的Powershell模块是什么?

What is the corresponding Powershell module for the PHP encryption library using MCRYPT_RIJNDAEL_256?

PHP代码:

mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $to_encrypt, MCRYPT_MODE_ECB);

我需要可以产生相同结果的相应powershell代码。

我已经尝试过 ConvertTo-SecureString/ConvertFrom-SecureString。

Powershell 代码(未生成正确的加密):

$api_code = "214e3854a1ec5433ae986d1e5d40c436"
$params = @{"controller" = $controller; "action"= $action;  "all"= $TRUE; }
[Byte[]] $key = $api_code[0..$api_code.length]
$param_object = $params | ConvertTo-SecureString -AsPlainText -Force
$param_aes = $param_object | ConvertFrom-SecureString -key $key

加密后的字符串不一样了。有没有我缺少的参数?或者还有其他模块吗?

正如评论中指出的那样,SecureStrings与Rijndael规范无关,MCRYPT_RIJNDAEL_256与AES256相同(用 256 位密钥引用 Rijndael-128)

因此,为了解决您的问题,我们只需要一个函数来使用块大小为 256 的 Rijndael 在 ECB 密码模式下加密明文。

为此,显而易见的选择是 RijndaelManaged class. Fortunately, the MSDN documentation provides a basic but fully functional example of how to use the RijndaelManaged class and a CryptoStream 来加密和解密字符串 - 我们需要做的就是在 PowerShell 中重写它并更改块大小和密码模式:

function Encrypt-Rijndael256ECB {
    param(
        [byte[]]$Key,
        [string]$Plaintext
    )

    $RijndaelProvider = New-Object -TypeName System.Security.Cryptography.RijndaelManaged

    # Set block size to 256 to imitate MCRYPT_RIJNDAEL_256
    $RijndaelProvider.BlockSize = 256
    # Make sure we use ECB mode, or the generated IV will fuck up the first block upon decryption
    $RijndaelProvider.Mode      = [System.Security.Cryptography.CipherMode]::ECB
    $RijndaelProvider.Key       = $key

    # This object will take care of the actual cryptographic transformation
    $Encryptor = $RijndaelProvider.CreateEncryptor()

    # Set up a memorystream that we can write encrypted data back to
    $EncMemoryStream = New-Object System.IO.MemoryStream
    $EncCryptoStream = New-Object System.Security.Cryptography.CryptoStream -ArgumentList $EncMemoryStream,$Encryptor,"Write"
    $EncStreamWriter = New-Object System.IO.StreamWriter -ArgumentList $EncCryptoStream

    # When we write data back to the CryptoStream, it'll get encrypted and written back to the MemoryStream
    $EncStreamWriter.Write($Plaintext)

    # Close the writer
    $EncStreamWriter.Close()
    # Close the CryptoStream (pads and flushes any data still left in the buffer)
    $EncCryptoStream.Close()
    $EncMemoryStream.Close()

    # Read the encrypted message from the memory stream
    $Cipher     = $EncMemoryStream.ToArray() -as [byte[]]
    $CipherText = [convert]::ToBase64String($Cipher)

    # return base64 encoded encrypted string
    return $CipherText
}

解密过程几乎是一样的,虽然这次我们需要逆向它并通过CryptoStream从MemoryStream中读回密文:

function Decrypt-Rijndael256ECB {
    param(
        [byte[]]$Key,
        [string]$CipherText
    )

    $RijndaelProvider = New-Object -TypeName System.Security.Cryptography.RijndaelManaged

    $RijndaelProvider.BlockSize = 256
    $RijndaelProvider.Mode      = [System.Security.Cryptography.CipherMode]::ECB
    $RijndaelProvider.Key       = $key

    $Decryptor = $RijndaelProvider.CreateDecryptor()

    # Reverse process: Base64Decode first, then populate memory stream with ciphertext and lastly read decrypted data through cryptostream
    $Cipher = [convert]::FromBase64String($CipherText) -as [byte[]]

    $DecMemoryStream = New-Object System.IO.MemoryStream -ArgumentList @(,$Cipher)
    $DecCryptoStream = New-Object System.Security.Cryptography.CryptoStream -ArgumentList $DecMemoryStream,$Decryptor,$([System.Security.Cryptography.CryptoStreamMode]::Read)
    $DecStreamWriter = New-Object System.IO.StreamReader -ArgumentList $DecCryptoStream

    $NewPlainText = $DecStreamWriter.ReadToEnd()

    $DecStreamWriter.Close()
    $DecCryptoStream.Close()
    $DecMemoryStream.Close()

    return $NewPlainText
}