使用OpenSSL在C#和PHP之间进行Decrpyt数据

时间:2018-08-07 07:33:22

标签: c# php encryption openssl public-key-encryption

我们尝试通过加密的数据通信连接两个平台。当文本大小小于keysize时,我们俩都可以加密和解密数据。当密码大小增长时,C#端可以解密数据,而PHP端则不能。

下面我们用于加密和解密的代码

我们在C#上使用Bouncy Castle Crypto API

C#加密

    public static string Encrypt(string text, RSACryptoServiceProvider publicKeyRSAProvider)
    {
        if (publicKeyRSAProvider == null)
        {
            throw new Exception("_publicKeyRsaProvider is null");
        }

        var plaintextData = Encoding.UTF8.GetBytes(text);
        //var plaintextData = GZipCompress(Encoding.UTF8.GetBytes(text));
        var maxBlockSize = (publicKeyRSAProvider.KeySize / 8) - 11;

        if (plaintextData.Length <= maxBlockSize)
        {
            return Convert.ToBase64String(publicKeyRSAProvider.Encrypt(plaintextData, false));
        }

        using (var plaiStream = new MemoryStream(plaintextData))
        {
            using (var crypStream = new MemoryStream())
            {
                var buffer = new byte[maxBlockSize];
                var blockSize = plaiStream.Read(buffer, 0, maxBlockSize);

                while (blockSize > 0)
                {
                    var toEncrypt = new byte[blockSize];
                    Array.Copy(buffer, 0, toEncrypt, 0, blockSize);

                    var cryptograph = publicKeyRSAProvider.Encrypt(toEncrypt, false);
                    crypStream.Write(cryptograph, 0, cryptograph.Length);

                    blockSize = plaiStream.Read(buffer, 0, maxBlockSize);
                }

                return Convert.ToBase64String(crypStream.ToArray());
                //return Convert.ToBase64String(GZipCompress(crypStream.ToArray()));
            }
        }
    }

C#Decrpyt

       public static string Decrypt(string ciphertext, RSACryptoServiceProvider privateKeyRSAProvider)
    {
        if (privateKeyRSAProvider == null)
        {
            throw new Exception("_privateKeyRsaProvider is null");
        }

        var ciphertextData = Convert.FromBase64String(ciphertext);
        //var ciphertextData = GZipUncompress(Convert.FromBase64String(ciphertext));
        var maxBlockSize = privateKeyRSAProvider.KeySize / 8;

        if (ciphertextData.Length <= maxBlockSize)
            return Encoding.UTF8.GetString(privateKeyRSAProvider.Decrypt(ciphertextData, false));

        using (var crypStream = new MemoryStream(ciphertextData))
        {
            using (var plaiStream = new MemoryStream())
            {
                var buffer = new byte[maxBlockSize];
                var blockSize = crypStream.Read(buffer, 0, maxBlockSize);

                while (blockSize > 0)
                {
                    var toDecrypt = new byte[blockSize];
                    Array.Copy(buffer, 0, toDecrypt, 0, blockSize);

                    var plaintext = privateKeyRSAProvider.Decrypt(toDecrypt, false);
                    plaiStream.Write(plaintext, 0, plaintext.Length);

                    blockSize = crypStream.Read(buffer, 0, maxBlockSize);
                }

                return Encoding.UTF8.GetString(plaiStream.ToArray());
                //return Encoding.UTF8.GetString(GZipUncompress(plaiStream.ToArray()));
            }
        }
    }

PHP解密

        function DecryptLargeData($data,$privateKey,$compress=false){
        // Get the private Key
        // 
        $data = base64_decode($data);
        $pkImport = openssl_pkey_get_private($privateKey);
        $a_key = openssl_pkey_get_details($pkImport);

        // Decrypt the data in the small chunks
        $chunkSize = ceil($a_key['bits'] / 8);
        $output = '';

        while ($data)
        {
            $chunk = substr($data, 0, $chunkSize);
            $data = substr($data, $chunkSize);
            $decrypted = '';
            if (!openssl_private_decrypt($chunk, $decrypted, $privateKey))
            {
                die('Failed to decrypt data');
            }
            $output .= $decrypted;
        }
        openssl_free_key($privateKey);

        // Uncompress the unencrypted data.
        if($compress)
            return $data;
        else
            return gzcompress($data);
    }

PHP加密

        public function EncryptLargeData($data,$privatekey,$publickey,$compress=false){

        // Ref : https://www.virendrachandak.com/techtalk/encryption-using-php-openssl/

        $pkImport = openssl_pkey_get_private($privatekey); // import
        // Get the public Key of the recipient
        $a_key = openssl_pkey_get_details($pkImport);

        // Encrypt the data in small chunks and then combine and send it.
        $chunkSize = ceil($a_key['bits'] / 8) - 11;
        $output = '';

        if($compress)
            $plaintext = gzcompress($data);
        else
            $plaintext = $data;

        while ($plaintext)
        {
            $chunk = substr($plaintext, 0, $chunkSize);
            $plaintext = substr($plaintext, $chunkSize);
            $encrypted = '';
            if (!openssl_public_encrypt($chunk, $encrypted, $publickey))
            {
                die('Failed to encrypt data');
            }
            $output .= $encrypted;
        }
        openssl_free_key($publickey);
        // This is the final encrypted data to be sent to the recipient
        $encrypted = $output;
        return base64_encode($encrypted);
    }

0 个答案:

没有答案