字节加密(DES-CBC 零填充)
目前正在编写我自己的 AMF TcpSocketServer。到目前为止,一切正常,我可以发送和接收对象,并且使用一些序列化/反序列化代码。现在我开始研究加密代码,我对这些东西不太熟悉。
- 我使用 bytes ,DES-CBC 好吗? 加密这个东西的方法?或者是 还有其他更高性能/更安全的 如何发送我的数据?注意 性能是必须的:)。
- 当我调用:ReadAmf3Object并指定解密器时,我得到一个:当我读出第一个字节时,我的ReadAmf3Object函数抛出InvalidOperationException,未指定Amf3TypeCode(我相信它们的范围从0到16(Bool) 、字符串、整数、日期时间等))。我的类型代码从 97 到 254 不等?有人知道出了什么问题吗?我认为这与加密部分有关。由于解串器在没有加密的情况下工作正常。我使用了正确的填充/模式/键?
我使用: http://code.google.com/p/as3crypto/ 作为 as3加密/解密库。我编写了一个异步 TCP 服务器,但滥用了线程池;)
无论如何,这里有一些代码:
C# crypter 初始化代码
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;
}
Currently writing my own AMF TcpSocketServer. Everything works good so far i can send and recieve objects and i use some serialization/deserialization code. Now i started working on the encryption code and i am not so familiar with this stuff.
- I work with bytes , is DES-CBC a good
way to encrypt this stuff? Or are
there other more performant/secure
ways to send my data? Note that
performance is a must :). - When i call: ReadAmf3Object with the decrypter specified i get an: InvalidOperationException thrown by my ReadAmf3Object function when i read out the first byte the Amf3TypeCode isn't specified ( they range from 0 to 16 i believe (Bool, String, Int, DateTime, etc) ). I got Typecodes varying from 97 to 254? Anyone knows whats going wrong? I think it has something to do with the encryption part. Since the deserializer works fine w/o the encryption. I am using the right padding/mode/key?
I used: http://code.google.com/p/as3crypto/ as as3 encryption/decryption library. And i wrote an Async tcp server with some abuse of the threadpool ;)
Anyway here some code:
C# crypter initalization code
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# read/unserialize/decrypt code
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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
定义“安全”。
DES 比纯文本更安全,但由于其密钥大小为 56 位,因此通常不再使用。如果您要保护您的家人或随意的轻松删除者的数据,这可能没问题。
如果人们现在使用 DES,那就是 Triple DES,它本质上是在每个数据块上运行 DES 三次。
如今,选择的对称加密算法(DES 就是 DES)是 AES,它就像 DES 的精神继承者。
对于大多数应用程序来说,具有足够大密钥 256(现在实际上是 512 或更高)的 AES 在加密上是安全的。
AES 的一些注意事项是:
这是天方夜谭的想法)
关于你的错误,首先尝试切换到 AES,看看你是否仍然遇到问题。
关于 AES:
密钥选择和密钥保护都很重要。
密钥选择
如果您想使用 AES “密码”保护您的数据,那么您需要将密码转换为 AES 密钥。这是许多业余计算机安全开发人员的常见陷阱。 Adobe 通过使用用户密码的 MD5 哈希值作为密钥,基本上破坏了 PDF 中 AES 的所有保护。不用说,您比所有 Adobe 工程师加起来还要聪明,所以您不会犯这样的错误。
从密码生成密钥的正确方法是使用 RFC2898 又名 PBKD2(基于密码的密钥派生函数)。 .NET 有一个方法可以轻松实现此目的:Rfc2898DeriveBytes()。本质上,它的作用是使用用户提供的盐(稍后会详细介绍)以加密方式安全地散列您的密码多次。这提供了多个层来防止针对您的密码的暴力攻击(假设您的密钥足够大,可以防止针对它的暴力攻击!)
PBKD2 的每次迭代都需要极短的运行时间。你运行的交互越多(我认为推荐的数字是> 1000),花费的计算机时间就越多。这个时间仍然比人类认识的要短,但在计算机时间里就像一个世纪一样。因此,在不知道确切的迭代次数的情况下,暴力破解密码的过程会非常漫长。
盐。盐不是直接对密码进行哈希处理,而是向您的输入密码添加额外的信息,从而创建一个唯一的哈希值。假设您保护盐值,这可以防止彩虹表攻击。盐
密钥存储
密码学的另一面是密钥存储。如果您使用密码保护您的数据,那么您需要安全地存储密码。最简单的方法是使用操作系统的内置安全性。在 Windows 上,在注册表中使用 DPAPI,在 Unix 上,使用文件权限。
AES 作为会话密钥
如果您希望通过非安全通道安全地传输数据(或者甚至在 SSL 之上添加您自己的额外安全性),您可能需要考虑使用 AES 作为会话加密。
本质上,这是两种方案的加密系统,其工作原理如下:
您使用您最喜欢的非对称加密(RSA!)为您的服务器生成公钥/私钥对。
每个受信任的客户端都会获得公钥。
在会话期间,客户端生成 256 位或更高位的新随机 AES 密钥。
此 AES 会话密钥使用公共 RSA 密钥进行加密。
包含 AES 会话密钥的加密数据被发送到服务器。
服务器使用其私有 RSA 密钥解密数据,并保留 AES 会话密钥。
在会话的剩余时间内,所有数据均使用会话 AES 密钥进行加密。
会话结束时,AES 密钥将被丢弃。
虽然这确实需要更多的握手,但这为您提供了限制暴露的额外保护。由于 AES 密钥仅对会话有效,因此如果被发现,损害仅限于单个会话。
Define "secure."
DES is more secure than plain text, but due to it's 56-bit keysize, it's not usually used anymore. If you're protecting data against your family, or the casual ease dropper this might be okay.
If people are using DES these days, it's Triple DES which essentially runs DES, three times, on each datablock.
Now a days the symmetric encryption algorithm (which DES is) of choice is AES, which is like the spiritual successor to DES.
AES with a sufficiently large key of 256 (really 512 or higher now a days) is cryptographically secure for most applications.
The few caveats of AES are:
this is tin hat thinking)
Regarding your error, first try switching to AES, and see if you still get a problem.
Regarding AES:
Key selection is important, as well as key protection.
Key Selection
If you want to "password" protect your data, using AES, then you need to convert your password into an AES key. This is a common pitfall for many amateur computer security developers. Adobe essentially destroyed all the protection of AES in their PDF's by using an MD5 hash of the users password as the key. Needless to say, you're smarter than all of Adobe's engineers combined, so you won't make that mistake.
The proper way to generate a key from a password is using RFC2898 aka PBKD2 (password based key derivation function). .NET handily has a method that does this: Rfc2898DeriveBytes(). Essentially what this does is cryptographically securely hashes your password, with a supplied salt (more on this in a bit), a number of times, supplied by the user. This provides several layers to protect against brute force attacks against your password (assuming your key is large enough to prevent brute force attacks against it!)
Each iteration of PBKD2 takes a minuscule amount of time to run. The more interation you run (i think the recommend number is > 1000), the more computer time it takes. This time is still less than a human would recognize, but in computer time it's like a century. Thus without knowing the exact iteration count, it makes it a very lengthy process to brute force attack a password.
Salt. Rather than taking a direct hash of your password, a salt adds extra information to your input password, creating a unique hash. This prevents rainbow table attacks, assuming you keep your salt value protected.
Key Storage
The other side to cryptography is key storage. If you are password protecting your data, then you need to securely store the password. The easiest way is to use the OS's built in security. On Windows thats using DPAPI in the registry, and Unix, filepermissions.
AES as a Session Key
If you are looking to securely transmit data across a nonsecure channel (or even adding your own extra security ontop of SSL), you may want to looking at using AES as a session encryption.
Essentially this is two scheme encryption system that works as follows:
You generate a public/private key pair using your favorite assymetric encryption (RSA!) for your server.
Each trusted client is given the public key.
During a session, the client generates a new random AES key of 256 bit or higher.
This AES Session key is encrypted using the public RSA key.
This encrypted data containing the AES session key is sent to the server.
The server decrypts the data using it's private RSA key, and keeps the AES Session key.
During the rest of the session, all data is encrypted with the session AES key.
At the end of the session, the AES key is discarded.
While this does require more handshaking, this gives you the added protection of limiting exposure. Since the AES key is only good for a session, if it's discovered, the damage is only limited to a single session.
DES 是一种分组密码,因此一般来说它使字节处理变得更加乏味。 AS3 是一种流密码,主要用于 GSM 电话系统,因为它是一种流密码,因此可以很好地处理字节。
就我个人而言,如果您确实需要使用流密码,我会使用 RC4;非常快。这里有一个很好的实现 http://dotnet-snippets.com/dns/rc4 -encryption-SID577.aspx
在使用流密码时,您应该注意一些非常重要的警告:
1) 永远不要在流密码中重复使用加密密钥。
2) 因为您一次加密一个字节,所以很难确定数据是否已被篡改,因此您需要向流添加数字签名或 HMAC。
DES is a block cipher, so in general it makes working with bytes more tedious. AS3 is a stream cipher used primarily with GSM phone systems, because it's a stream cipher it'll work nicely with bytes.
Personally, I would use RC4 if you really need to use a stream cipher; it's very quick. There's a good implementation here http://dotnet-snippets.com/dns/rc4-encryption-SID577.aspx
There are some very important caveats you should be aware of when using stream ciphers:
1) NEVER re-use an encryption key with a stream cipher.
2) Because you're encrypting one byte at a time, it's hard to determine if the data has been tampered with, so you'll need add a digital signature or HMAC to the stream.