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
加密的字符串不同。有没有我缺少的参数?还是有另一个模块吗?
答案 0 :(得分:3)
正如评论中所指出的那样,SecureString
与Rijndael规范无关,而MCRYPT_RIJNDAEL_256
不与AES256(引用Rijndael-128)相同使用256位密钥)
因此,为了解决您的问题,我们只需要一个函数来使用块大小为256的Rijndael在ECB密码模式下加密明文。
为此,明显的选择是RijndaelManaged
类。幸运的是,MSDN文档提供了一个基本但功能齐全的示例,说明如何使用RijndaelManaged
类和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
}
解密过程几乎相同,虽然这次我们需要将其反转并通过MemoryStream中的CryptoStream读取密文:
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
}