PHP相当于.NET AES加密 [英] PHP equivalent of .net AES encryption

查看:301
本文介绍了PHP相当于.NET AES加密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的工作和我的客户端和数据的数据交换集成他们送我的是用他们的C#加密方法(下)加密。



我的应用程序正在运行PHP 5.3,我需要一个等效代码解密它们发送的数据。我有PHP代码,但它会无法正确解密客户端的数据对我来说。



显然,我在我的加密/解密方法,IV密钥或东西做一些错误。任何人都可以看出错误?



感谢



C#代码(从我的客户端):

 使用系统; 
使用System.Security.Cryptography;
使用System.Text;
:使用System.IO;

公共类节目
{
公共静态无效的主要()
{
变种文字=这是一个简单的字符串;
VAR ENC = Program.Encrypt(文本);
Console.WriteLine(ENC);
Console.WriteLine(Program.Decrypt(ENC));
}

公共静态字符串加密(字符串明文)
{
VAR EncryptionKey设置=1234567890123456;
字节[] = clearBytes Encoding.Unicode.GetBytes(明文);
使用(AES加密= Aes.Create())
{
的byte [] IV =新的字节[15];
变种兰特=新的随机();
rand.NextBytes(IV);
Rfc2898DeriveBytes PDB =新Rfc2898DeriveBytes(EncryptionKey设置,IV);
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
使用(MemoryStream的毫秒=新的MemoryStream())
{使用
(CryptoStream的CS =新的CryptoStream(MS,encryptor.CreateEncryptor(),CryptoStreamMode.Write))
$ { b $ b cs.Write(clearBytes,0,clearBytes.Length);
cs.Close();
}

明文= Convert.ToBase64String(Ⅳ)+ Convert.ToBase64String(ms.ToArray());
}
}

返回明文;
}

公共静态字符串解密(字符串密文)
{
VAR EncryptionKey设置=1234567890123456;
的byte [] IV = Convert.FromBase64String(cipherText.Substring(0,20));
密文= cipherText.Substring(20).Replace(,+);
字节[] = cipherBytes Convert.FromBase64String(密文);
使用(AES加密= Aes.Create())
{
Rfc2898DeriveBytes PDB =新Rfc2898DeriveBytes(EncryptionKey设置,IV);
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
使用(MemoryStream的毫秒=新的MemoryStream())
{使用
(CryptoStream的CS =新的CryptoStream(MS,encryptor.CreateDecryptor(),CryptoStreamMode.Write))
$ { b $ b cs.Write(cipherBytes,0,cipherBytes.Length);
cs.Close();
}

密文= Encoding.Unicode.GetString(ms.ToArray());
}
}

返回密文;
}
}



PHP代码我有:

 公共功能加密($明文)
{
$ SecretKey的='1234567890123456';

返回RTRIM(
BASE64_ENCODE(
mcrypt_encrypt(
MCRYPT_RIJNDAEL_256,
$ SecretKey的,$明文,
MCRYPT_MODE_ECB,
mcrypt_create_iv (
mcrypt_get_iv_size(
MCRYPT_RIJNDAEL_256,
MCRYPT_MODE_ECB

MCRYPT_RAND)

),\0
);
}

公共职能解密($ encodedData)
{
$ SecretKey的='1234567890123456';

返回RTRIM(
mcrypt_decrypt(
MCRYPT_RIJNDAEL_256,
$ SecretKey的,
BASE64_DECODE($ encodedData),
MCRYPT_MODE_ECB,
mcrypt_create_iv(
mcrypt_get_iv_size(
MCRYPT_RIJNDAEL_256,
MCRYPT_MODE_ECB

MCRYPT_RAND

),\0
);
}


解决方案

任何人都可以看出错误




是的,大个是不是真的你的错:的mcrypt's混乱API罢工一次



这是说,实际上有多个错误在这里。

 返回RTRIM(//不必要的
BASE64_ENCODE(
mcrypt_encrypt(
MCRYPT_RIJNDAEL_256,//不是AES
$ SecretKey的,$明文,
MCRYPT_MODE_ECB,// BAD,使用MCRYPT_MODE_CBC或点击率,而不是
mcrypt_create_iv(
mcrypt_get_iv_size(//除非你打算让这个
MCRYPT_RIJNDAEL_256,//可配置的,你应该只
MCRYPT_MODE_ECB //硬编码此作为一个整数

MCRYPT_RAND)// BAD,使用MCRYPT_DEV_URANDOM

),\0
);

如果你要生成一个IV,它应该传达这样你的收件人可以解密相同成功的第一块。 C#代码执行此操作时,PHP不会。



从密码学工程的角度来看,你应该考虑,无论是在C#的土地,并在PHP,部署加密,然后验证协议。请参见加密和认证这个博客帖子。此外,你曾经写过加密代码可能打破


I am working on a data exchange integration with my client and the data they send me is encrypted using their C# encrypt method (below).

My app is running PHP 5.3 and I need an equivalent code to decrypt the data they send. I have the PHP code but it'd not decrypt the client data correctly for me.

Clearly I am making some mistake in my encryption/decryption methods, IV key or something. Can anyone spot the mistake?

Thanks.

C# Code (From my client):

using System;
using System.Security.Cryptography;
using System.Text;
using System.IO;

public class Program
{
    public static void Main()
    {
        var text = "this is a plain string";
        var enc = Program.Encrypt(text);
        Console.WriteLine(enc);
        Console.WriteLine(Program.Decrypt(enc));
    }

    public static string Encrypt(string clearText)
    {
        var EncryptionKey = "1234567890123456";
        byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
        using (Aes encryptor = Aes.Create())
        {
            byte[] IV = new byte[15];
            var rand = new Random();
            rand.NextBytes(IV);
            Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, IV);
            encryptor.Key = pdb.GetBytes(32);
            encryptor.IV = pdb.GetBytes(16);
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(clearBytes, 0, clearBytes.Length);
                    cs.Close();
                }

                clearText = Convert.ToBase64String(IV) + Convert.ToBase64String(ms.ToArray());
            }
        }

        return clearText;
    }

    public static string Decrypt(string cipherText)
    {
        var EncryptionKey = "1234567890123456";
        byte[] IV = Convert.FromBase64String(cipherText.Substring(0, 20));
        cipherText = cipherText.Substring(20).Replace(" ", "+");
        byte[] cipherBytes = Convert.FromBase64String(cipherText);
        using (Aes encryptor = Aes.Create())
        {
            Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, IV);
            encryptor.Key = pdb.GetBytes(32);
            encryptor.IV = pdb.GetBytes(16);
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(cipherBytes, 0, cipherBytes.Length);
                    cs.Close();
                }

                cipherText = Encoding.Unicode.GetString(ms.ToArray());
            }
        }

        return cipherText;
    }
}

PHP Code I have:

public function encrypt($plainText)
{
    $secretKey = '1234567890123456';

    return rtrim(
        base64_encode(
            mcrypt_encrypt(
                MCRYPT_RIJNDAEL_256,
                $secretKey, $plainText,
                MCRYPT_MODE_ECB,
                mcrypt_create_iv(
                    mcrypt_get_iv_size(
                        MCRYPT_RIJNDAEL_256,
                        MCRYPT_MODE_ECB
                    ),
                    MCRYPT_RAND)
            )
        ), "\0"
    );
}

public function decrypt($encodedData)
{
    $secretKey = '1234567890123456';

    return rtrim(
        mcrypt_decrypt(
            MCRYPT_RIJNDAEL_256,
            $secretKey,
            base64_decode($encodedData),
            MCRYPT_MODE_ECB,
            mcrypt_create_iv(
                mcrypt_get_iv_size(
                    MCRYPT_RIJNDAEL_256,
                    MCRYPT_MODE_ECB
                ),
                MCRYPT_RAND
            )
        ), "\0"
    );
}

解决方案

Can anyone spot the mistake?

Yes, and the big one isn't really your fault: mcrypt's confusing API strikes again.

That said, there are actually multiple mistakes here.

return rtrim( // unnecessary
    base64_encode(
        mcrypt_encrypt(
            MCRYPT_RIJNDAEL_256, // Not AES
            $secretKey, $plainText,
            MCRYPT_MODE_ECB, // BAD, use MCRYPT_MODE_CBC or 'ctr' instead
            mcrypt_create_iv(
                mcrypt_get_iv_size(      // unless you're going make this
                    MCRYPT_RIJNDAEL_256, // configurable, you should just
                    MCRYPT_MODE_ECB      // hard-code this as an integer
                ),
                MCRYPT_RAND) // BAD, use MCRYPT_DEV_URANDOM
        )
    ), "\0"
); 

If you're going to generate an IV, it should be communicated so your recipient can decrypt the same first block successfully. The C# code does this, the PHP does not.

From a cryptography engineering perspective, you should consider, both in C# land and in PHP, deploying an Encrypt then Authenticate protocol. See this blog post on encryption and authentication. Also, all the crypto code you've ever written is probably broken.

这篇关于PHP相当于.NET AES加密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆