0

目前正在编写我自己的 AMF TcpSocketServer。到目前为止一切正常,我可以发送和接收对象,并且我使用了一些序列化/反序列化代码。现在我开始研究加密代码,我对这些东西不太熟悉。

  • 我使用 bytes ,DES-CBC 是加密这些东西的好方法吗?还是有其他更高效/更安全的方式来发送我的数据?请注意,性能是必须的:)。
  • 当我调用:指定解密器的ReadAmf3Object时,我得到一个:当我读出未指定 Amf3TypeCode 的第一个字节时,我的 ReadAmf3Object 函数抛出的 InvalidOperationException(我相信它们的范围从 0 到 16(Bool,String,Int,DateTime, ETC) )。我的类型代码从 97 到 254 不等?有谁知道出了什么问题?我认为这与加密部分有关。由于解串器在没有加密的情况下工作正常。我正在使用正确的填充/模式/键?

我使用:http ://code.google.com/p/as3crypto/作为 as3 加密/解密库。我写了一个异步 tcp 服务器,滥用了线程池;)

无论如何这里有一些代码:

C#密码器初始化代码

System.Security.Cryptography.DESCryptoServiceProvider crypter = new DESCryptoServiceProvider();

crypter.Padding = PaddingMode.Zeros;
crypter.Mode = CipherMode.CBC;
crypter.Key = Encoding.ASCII.GetBytes("TESTTEST");

AS3

private static var _KEY:ByteArray = Hex.toArray(Hex.fromString("TESTTEST"));
private static var _TYPE:String = "des-cbc";

public static function encrypt(array:ByteArray):ByteArray
{
 var pad:IPad = new NullPad;
 var mode:ICipher = Crypto.getCipher(_TYPE, _KEY, pad);

 pad.setBlockSize(mode.getBlockSize());
 mode.encrypt(array);

 return array;
}

public static function decrypt(array:ByteArray):ByteArray
{
 var pad:IPad = new NullPad;
 var mode:ICipher = Crypto.getCipher(_TYPE, _KEY, pad);

 pad.setBlockSize(mode.getBlockSize());
 mode.decrypt(array);

 return array;
}

C#读取/反序列化/解密代码

public override object Read(int length)
{
    object d;

    using (MemoryStream stream = new MemoryStream())
    {
    stream.Write(this._readBuffer, 0, length);
    stream.Position = 0;

    if (this.Decrypter != null)
    {
        using (CryptoStream c = new CryptoStream(stream, this.Decrypter, CryptoStreamMode.Read))
        using (AmfReader reader = new AmfReader(c))
        {
        d = reader.ReadAmf3Object();
        }
    }
    else
    {
        using (AmfReader reader = new AmfReader(stream))
        {
        d = reader.ReadAmf3Object();
        }
    }           
    }

    return d;
}
4

2 回答 2

1

定义“安全”。

DES 比纯文本更安全,但由于它的密钥大小为 56 位,因此通常不再使用它。如果您要保护数据免受家人或随意轻松的滴管的侵害,这可能没问题。

如果现在人们在使用 DES,那就是三重 DES,它本质上是在每个数据块上运行 DES 三次。

现在选择的对称加密算法(DES 就是)是 AES,它就像 DES 的精神继承者。

具有足够大的 256 密钥(现在实际上是 512 或更高)的 AES 对于大多数应用程序来说是加密安全的。

AES 的一些注意事项是:

  1. 它仍然仅限于美国出口管制
  2. 如果 NSA 愿意,他们可以解密您的信息(是的,这是锡帽子的想法)

关于您的错误,首先尝试切换到 AES,看看您是否仍然遇到问题。

关于AES:

密钥选择很重要,密钥保护也很重要。

键选择

如果您想“密码”保护您的数据,使用 AES,那么您需要将您的密码转换为 AES 密钥。对于许多业余计算机安全开发人员来说,这是一个常见的陷阱。Adobe 通过使用用户密码的 MD5 哈希作为密钥,基本上破坏了其 PDF 中的所有 AES 保护。不用说,你比 Adob​​e 的所有工程师加起来还要聪明,所以你不会犯这个错误。

从密码生成密钥的正确方法是使用 RFC2898 aka PBKD2(基于密码的密钥派生函数)。.NET 有一个很容易做到这一点的方法:Rfc2898DeriveBytes()。本质上,它的作用是对您的密码进行加密安全地散列,并使用用户提供的盐(稍后会详细介绍)多次。这提供了几个层来防止对您的密码进行暴力攻击(假设您的密钥足够大以防止对其进行暴力攻击!)

  1. PBKD2 的每次迭代都需要很短的时间来运行。您运行的交互越多(我认为推荐数字> 1000),所需的计算机时间就越多。这个时间仍然比人类认识的要少,但在计算机时代它就像一个世纪。因此,在不知道确切的迭代次数的情况下,暴力破解密码是一个非常漫长的过程。

  2. 盐。盐不是直接对您的密码进行哈希处理,而是在您的输入密码中添加额外的信息,从而创建一个唯一的哈希。这可以防止彩虹表攻击,假设您保护您的盐值。

密钥存储

密码学的另一面是密钥存储。如果您使用密码保护您的数据,那么您需要安全地存储密码。最简单的方法是使用操作系统的内置安全性。在 Windows 上,在注册表中使用 DPAPI,在 Unix 上,文件权限。

AES 作为会话密钥

如果您希望通过非安全通道安全地传输数据(或者甚至在 SSL 之上添加您自己的额外安全性),您可能希望将 AES 用作会话加密。

本质上,这是两种方案加密系统,其工作原理如下:

您使用您最喜欢的非对称加密 (RSA!) 为您的服务器生成一个公钥/私钥对。每个受信任的客户端都被赋予了公钥。在会话期间,客户端会生成一个 256 位或更高位的新随机 AES 密钥。此 AES 会话密钥使用公共 RSA 密钥加密。这个包含 AES 会话密钥的加密数据被发送到服务器。服务器使用其私有 RSA 密钥解密数据,并保留 AES 会话密钥。在会话的其余部分,所有数据都使用会话 AES 密钥加密。在会话结束时,AES 密钥被丢弃。

虽然这确实需要更多的握手,但这为您提供了限制曝光的额外保护。由于 AES 密钥仅对会话有效,因此如果被发现,损坏仅限于单个会话。

于 2010-04-04T20:21:31.977 回答
0

DES 是一种分组密码,因此通常它使处理字节变得更加乏味。AS3 是一种主要用于 GSM 电话系统的流密码,因为它是一种流密码,它可以很好地处理字节。

就个人而言,如果您真的需要使用流密码,我会使用 RC4 ;它非常快。这里有一个很好的实现http://dotnet-snippets.com/dns/rc4-encryption-SID577.aspx

在使用流密码时,您应该注意一些非常重要的警告:

1)切勿将加密密钥与流密码一起使用。

2)因为您一次加密一个字节,所以很难确定数据是否被篡改,因此您需要在流中添加数字签名或 HMAC。

于 2010-04-04T20:20:21.307 回答