[英]AES128 Encryption using PHP mcrypt is not outputting same as ASP.net
我有一个PHP应用程序,需要对ASP.net Web服务使用的质询字符串进行加密,但是.net无法正确解密我的PHP实现的输出。 正是在这个与iOS和.net有关的问题中: AES128位加密字符串与.net上的相似
为什么输出不同?我如何对PHP进行输出以使其与.net相同?
我的PHP代码如下所示:
$key = '128bit-16bytekey';
$value = '128bit-16byteval';
function fnEncrypt($value, $key)
{
$ivsize = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($ivsize);
return base64_encode(
mcrypt_encrypt(
MCRYPT_RIJNDAEL_128,
$key, $value,
MCRYPT_MODE_ECB,$iv
));
}
像这样的.net
public static string EncryptData(string plainText)
{
string encryptionKey = AppConstants.AES_ENCRYPTDECRYPT_KEY;
// Convert our plaintext into a byte array.
// Let us assume that plaintext contains UTF8-encoded characters.
byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
// Use the password to generate pseudo-random bytes for the encryption
// key. Specify the size of the key in bytes (instead of bits).
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] keyBytes = new byte[16];
byte[] tempKey = encoding.GetBytes(encryptionKey);
for (int i = 0; i < keyBytes.Length; i++)
{
if (i < tempKey.Length)
{
keyBytes[i] = tempKey[i];
}
else
{
keyBytes[i] = 0;
}
}
// Create uninitialized Rijndael encryption object.
RijndaelManaged symmetricKey = new RijndaelManaged();
//AesManaged symmetricKey = new AesManaged();
//symmetricKey.Padding = PaddingMode.PKCS7;
// It is reasonable to set encryption mode to Cipher Block Chaining
// (CBC). Use default options for other symmetric key parameters.
symmetricKey.Mode = CipherMode.ECB;
// Generate encryptor from the existing key bytes and initialization
// vector. Key size will be defined based on the number of the key
// bytes.
//ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes,initVectorBytes);
ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, null);
// Define memory stream which will be used to hold encrypted data.
MemoryStream memoryStream = new MemoryStream();
// Define cryptographic stream (always use Write mode for encryption).
CryptoStream cryptoStream = new CryptoStream(memoryStream,
encryptor,
CryptoStreamMode.Write);
// Start encrypting.
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
// Finish encrypting.
cryptoStream.FlushFinalBlock();
// Convert our encrypted data from a memory stream into a byte array.
byte[] cipherTextBytes = memoryStream.ToArray();
// Close both streams.
memoryStream.Close();
cryptoStream.Close();
// Convert encrypted data into a base64-encoded string.
string cipherText = Convert.ToBase64String(cipherTextBytes);
// Return encrypted string.
return cipherText;
}
样本输出
PHP的:Q54nP / tXq2rDTUwWw4ckkg ==
.net:Q54nP / tXq2rDTUwWw4ckkpSt9CQiIzsg2xsQEndcqc8 =
PHP的:DQZdAB / lABXVOOoCdNM6HQ = =
.net:DQZdAB / lABXVOOoCdNM6HZSt9CQiIzsg2xsQEndcqc8 =
就像上面提到的问题一样,.net输出的右侧始终是相同的,而这两个实现之间的左侧是一致的。 我很确定IV是无关紧要的,这与mcrypt中填充的处理方式有关。
如果我解密PHP中的任何输出,它将返回相同的正确结果。
谁能阐明任何想法? 我无法更改.net应用。 谢谢!
发生这种情况是由于.net中应用了填充。 您可以通过在.net代码中添加以下行来克服这一问题:
symmetricKey.Padding = PaddingMode.None;
或者,您可以更改PHP代码以获取相同的加密字符串:
// Add the lines below to your fnEncrypt function
$block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
$len = strlen($value);
$padding = $block - ($len % $block);
$value .= str_repeat(chr($padding),$padding);
PHP手册页中的注释之一描述了类似的问题: http : //www.php.net//manual/en/function.mcrypt-encrypt.php#47973
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.