桌面应用程序和服务器之间的加密 - C# to PHP

Encryption between desktop app and server - C# to PHP

我有一个用 C# 设计的应用程序。简单来说,应用程序将数据和图像发送到我的网络服务器,该服务器获取所有 $_POST 数据并对其进行处理。我承认我不明白事物的安全端是如何工作的。我会聘请有相关经验的人来做这件事,但是我什至不知道在这一点上问他们什么,因为一些公认的技术是什么。

我认为它不像 base64 encode/decode 数据那么简单,它需要更高级别的加密。网络服务器将在接下来的几周内获得 HTTPS SSL(OV) 认证,但我的有限理解是,在将数据从用户 PC 传输到我的网络服务器时,我仍然需要某种 protection/encryption,这样就不会有人在听了关于数据传输或类似的东西。

简单来说,如果我想保证用户和我的网络服务器之间的数据安全,C# 的一些最常见或可接受的方法是什么 PHP?

数据直接从用户 PC 上的应用程序传输到我的服务器,我控制着两者的源代码,但我自己而不是开发人员因此我缺乏关于这个问题的技术知识。

我与一位 C# 开发人员讨论了建议的 symmetric/asymmetric 算法,但他不是 PHP 开发人员,因此他不知道 php 是否可以获取该数据并对其进行解密。

您似乎担心数据从客户端应用程序传输到服务器时的安全性,反之亦然。正如评论中提到的,在这方面 HTTPS 连接就足够了。它会自动为您执行encryption/decryption。

要使 HTTPS 连接正常工作,您需要购买 SSL 证书(Namecheap 是一个可以购买的网站)并将其安装在您的 Web 服务器上。第一次 he/she 连接到服务器时,证书会自动安装在用户的本地计算机上,并且每个后续连接都会检查有效证书。所以基本上,您只需在服务器上安装证书,在必须更新证书之前不必担心。只需确保您的客户端应用尝试连接到 HTTPS 地址而不是 HTTP。

如果您实施symmetric/asymmetric加密,将有助于数据传输前后的加密和解密。如果您在客户端应用程序中加密数据,则必须在收到数据时在服务器端对其进行解密,反之亦然。这将为您提供更强的安全性;但是,根据您应用的性质,HTTPS 连接可能就足够了。

我的个人项目之一是连接到 Ruby Web 服务器的客户端 C# 应用程序,我也编写了该项目。我在我的 Ruby 网络服务器上安装了 SSL 证书,以便数据在传输过程中被加密。就我而言,传输的数据不包含任何用户数据或 PII(个人身份信息),因此如果外部方获得此信息的访问权限,则不会构成安全风险。因此,我觉得在传输前后使用加密是不值得的,也不会给最终用户带来任何好处。同样,这取决于您的应用的性质和用户的期望。

编辑:

因为 mine mentioned in the comments, StartSSL 提供免费的 SSL 证书。

为了回答您的进一步问题,当服务器发布并正确配置了良好的证书后,您不需要再做任何事情。

使用 HTTPS

HTTPS 的工作原理是在初始握手期间通过证书颁发机构 (CA) 验证 SSL 证书。证书颁发机构,本质上是用于验证所述证书的签名列表,通常由 OS 供应商预加载。

假设您的服务器有 CA 颁发的证书,您需要做的就是在建立连接时从使用 HTTP 更改为 HTTPS。您正在使用的库应该有一种验证服务器 SSL 证书的方法,如果它没有自动为您执行此操作的话。

没有任何技术原因要求您必须对通过 HTTPS 发送的任何内容进行加密,只要证书经过高度加密即可。

此外,如果您想更深入地了解 HTTPS 工作原理的具体细节,this very good post 信息安全部分对协议的内部工作原理做了一些介绍。

回答你原来的问题

为了完整起见。

PHP 具有密码学扩展 mcrypt,它支持各种算法和密码操作模式。我整理了一个使用 AES 256 / PBKDF-SHA1 密钥解密的简单示例(连同执行加密的 C# 代码)。

编辑:我想指出 hash_pbkdf2 is only available in PHP 5.5 and up. Support down to 5.3 can be added with this nifty trick

PHP

function decode_aes($data, $key) // Decrypt custom format data string
{
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
    $salt_size = 16;

    $iv = substr($data, 0, $iv_size); // Init vector
    $salt = substr($data, $iv_size, $salt_size); // The salt
    $extact = substr($data, $iv_size + $salt_size); // This is the encrypted data

    $key = hash_pbkdf2("sha1", $key, $salt, 1000, 32, true); // Sets to use PBKDF-SHA1

    return mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $extact, MCRYPT_MODE_CBC, $iv); // Perform the decryption with the extracted sections
}

// As an example, I've included this.
$encryped = "zgCp2sSDs32Y8SOn8MYFCEjOJDeM4E3Y8Wx52A+iTFRk/1TJwMzkqmrB06bFu8dK";
echo decode_aes(base64_decode($encryped), "password");

C#

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

namespace AESExample
{
    class Program
    {
        static void Main(string[] args)
        {
            byte[] toEncrypt = Encoding.UTF8.GetBytes("Encrypted Text");
            byte[] key = Encoding.UTF8.GetBytes("password");
            String encrypted = Convert.ToBase64String(EncryptAES(toEncrypt, key));
        }

        public static byte[] EncryptAES(byte[] data, byte[] key)
        {
            using(RijndaelManaged algo = new RijndaelManaged())
            {
                algo.GenerateIV();
                algo.Mode = CipherMode.CBC;
                algo.Padding = PaddingMode.Zeros;

                byte[] saltBuffer = new byte[16];
                RNGCryptoServiceProvider saltGenerator = new RNGCryptoServiceProvider();
                saltGenerator.GetBytes(saltBuffer);

                Rfc2898DeriveBytes PBKDF2 = new Rfc2898DeriveBytes(key, saltBuffer, 1000);
                key = PBKDF2.GetBytes(32);

                ICryptoTransform cipher = algo.CreateEncryptor(key, algo.IV);

                using(MemoryStream ms = new MemoryStream())
                {
                    ms.Write(algo.IV, 0, algo.IV.Length);
                    ms.Write(saltBuffer, 0, saltBuffer.Length);
                    using(CryptoStream cs = new CryptoStream(ms, cipher, CryptoStreamMode.Write))
                    {
                        using(StreamWriter sw = new StreamWriter(cs))
                        {
                            sw.Write(Encoding.UTF8.GetString(data).ToCharArray());
                        }
                    }
                    return ms.ToArray();
                }
            }
        }
    }
}