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

15

我有一个用C#设计的应用程序。简单来说,应用程序会将数据和图像发送到我的Web服务器,该服务器接收所有$_POST数据并进行处理。我承认我不理解安全方面的工作方式。我将雇用具有相关经验的人员来处理这些问题,但是我甚至不知道在这一点上应该问他们什么,比如哪些被接受的技术。

我假设并不像只需要对数据进行base64编码/解码就足够了,还需要更高级别的加密。Web服务器将在未来几周内拥有HTTPS SSL(OV)认证,但我的有限理解是,在将数据从用户PC传输到我的Web服务器时,我仍然需要某种形式的保护/加密,以避免有人监听数据传输等情况发生。

简而言之,如果我想在用户和我的Web服务器之间保护数据安全,那么C#到PHP最常见或被接受的方法有哪些?

数据直接从用户PC上的应用程序发送到我的服务器,我控制两者的源代码,但我本人并不是开发人员,因此我在这个问题上缺乏技术知识。

我与一位C#开发人员交谈过,他建议使用对称/非对称算法,但他不是PHP开发人员,因此他不知道PHP是否可以接收并解密这些数据。


如果您担心在数据传输过程中有人会监听,HTTPS(SSL/TLS)将在数据传输期间处理加密。 如果您关心有人在数据传输之前/之后拦截数据,非对称加密是正确的选择。 在这种情况下,您可能会对此帖子感兴趣:https://dev59.com/CG855IYBdhLWcg3wMBTV - Irwene
2
作为一般规则,如果你在考虑是否要实现自己的加密算法,那么答案很可能是“不需要”。你最好的选择可能是TLS。 - wallenborn
2
谢谢大家的反馈。Wallenborn,你说TLS可能是我最好的选择,从我所读到的来看,TLS / SSL似乎是相同的东西,只是不同的术语,所以听起来两个建议都是为了SSL。由于我的知识有限,我不明白SSL在这种情况下如何工作。 我的理解仅限于要实施SSL,您必须在服务器上安装证书,但我不明白如果您想从桌面应用程序发送它,是否还需要在桌面应用程序中安装相同的证书。 - user1547410
还有一个问题,如果我想要为我的用户提供高保护和安心,我是否应该进行非对称加密,或者SSL也可以覆盖这一点? - user1547410
这就是 HTTPS 的作用。如果你非常担心,你可以使用应用程序和Web服务器之间共享的密钥加密数据。 - user1893702
很遗憾,楼主被踩了一个踩 :( - Ceeee
2个回答

11

看起来你关心客户端应用和服务器之间传输的数据安全性,反之亦然。正如评论中所提到的,使用HTTPS连接就足以达到这个目的。它会自动为您执行加密/解密操作。

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

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

我的一个个人项目是连接到我编写的Ruby Web服务器的客户端C#应用程序。我在Ruby Web服务器上安装了SSL证书,以便在传输过程中加密数据。在我的情况下,传输的数据不包含任何用户数据或PII(个人身份信息),因此如果外部方访问这些信息,它并不构成安全风险。因此,我认为在传输之前和之后使用加密不值得,也不会为最终用户提供任何好处。同样,这取决于您应用程序的性质和用户的期望。

编辑:

正如mine在评论中提到的,StartSSL提供免费的SSL证书。


1
你也可以看一下http://www.startssl.com/,他们提供免费的SSL证书。 - michaeln
@mine 太棒了,谢谢你提到那个网站!我之前不知道它的存在。 - Alexander
1
不用谢。还有一个名为https://letsencrypt.org/的倡议,旨在加密一切,但我认为这与此话题无关了。 - michaeln

4
为了回答你的更多问题,当服务器被发出并且用一张好的证书正确配置后,你就不需要做任何其他事情了。

使用HTTPS

HTTPS 的工作原理是在初始握手期间通过向证书颁发机构(CA)验证 SSL 证书来进行。证书颁发机构,也就是用于验证这些证书的签名列表,通常会由操作系统供应商预加载。

假设你的服务器已经有了 CA 颁发的证书,那么你所需要做的就是在建立连接时从 HTTP 切换到 HTTPS。如果你正在使用的库没有自动为你执行此项操作,则应该有一种方法可以对服务器的 SSL 证书进行验证。

只要证书被强加密,就没有必要对将要通过 HTTPS 发送的任何内容进行加密。

另外,如果你想更深入地了解 HTTPS 的内部工作原理,请看 Information Security 上的这篇非常好的文章

回答你最初的问题

为了完整起见。

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

编辑:我想指出,hash_pbkdf2 仅在 PHP 5.5 及以上版本中可用。可以通过这个巧妙的技巧来支持到 5.3 版本。

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();
                }
            }
        }
    }
}

1
这绝对是更完整的答案。是的,尝试编写自己的加密算法通常会使您的应用程序更不安全,但是,仅使用HTTPS并不足以保证某些应用程序的安全性,而且使用加密算法除了 HTTPS肯定不会使应用程序更不安全。客户端证书也可以帮助使仅使用HTTPS成为更可行的选择。 - Will

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接