ASN.1编码解码

6
我正在开发一个客户端-服务器程序,客户端是Java/C语言编写的,服务器是C语言编写的。 我需要传输加密数据(例如,客户端要将数据传递给服务器进行加密/解密、计算摘要等),并且服务器必须将结果返回给客户端。
在这种情况下,我意识到使用一些传输协议来识别数据并有效地传递数据的重要性。
关于此,我的问题是:ASN.1协议是否是一个好的选择?我知道它被BC(Java上)和OpenSSL(C上)支持。因此,使用ASN.1符号将数据在客户端和服务器之间传输是否是一个好主意?
您能否为此提供一些入门指导?如果您有更好的现有协议的想法,请告诉我。
谢谢!!

2
ASN.1是一种编码方式,而不是协议。它为网络传输提供了数据序列化的标准。我不确定ASN.1的效率,但在关注其效率之前,我更关心您的实现的健壮性。 - this.josh
4个回答

9
BC和OpenSSL支持的只是ASN.1的一小部分。事实上,在很长时间内,至少对于公众而言,没有完整的ASN.1实现可用。电信公司和电话设备制造商可能拥有相当完整的ASN.1实现。目前,对于公众而言,最先进的ASN.1实现是作为OsmoCom项目的一部分开发的,Harald Welte在他的博客中提到了它:http://laforge.gnumonks.org/weblog/2011/04/12#20110412-mapv1_available 更糟糕的是,ASN.1,特别是其高度冗余的编码方案(ASN.1中至少有3种不同的字符串编码方式),在过去几年中曾导致多个安全问题,由于它在正确处理x509证书时引起的问题。 X509是另一个来自地狱的破损技术,我认为最好避免使用。当然,SSL依赖于它,但是获得由“可信”CA签名的证书并不意味着任何事情;任何CA都可以为任何域签名,并且在查看了您的浏览器默认信任的内容后,我不再信任我的浏览器。
因此,长话短说:ASN.1是有问题的,并且应该在新设计中避免使用。它仅在电话网络之外广泛使用的主要用途是x509,而x509也是有问题的。因此,我不会使用它。使用JSON、BSON、Protocol Buffers、Netstrings或其他合理的东西。

唯一的问题是我的C服务器是嵌入式系统,我不想使用一些额外的高开销库。我认为asn.1是openssl库的一部分,而我已经在服务器端使用了它 :( - pimmling
正如我所说,OpenSSL只实现ASN.1的非常有限的子集,即仅处理x509证书所需的部分。此外,BSON和Protocol Buffers非常轻量级:BSON的C实现仅有700行代码。 - datenwolf
谢谢你,datenwolf!我有一个小疑问。据我所知,这些协议有助于数据序列化。也就是说,它们可以帮助你将所有数据放入一个带有定义头的漂亮数组中,以便在另一端更容易地解包。那么,如果我自己编写这个协议呢?比如说,定义一个消息头,让我的服务器和客户端可以使用来通信。为什么这些序列化重要方案很重要?它们为什么很重要? - pimmling
如果不给你的数据一些结构,接收端就无法辨别什么是什么。首先,您需要验证接收到的数据是否实际上是您理解的某种格式,否则可能会意外或恶意发送的所有垃圾都会使您的进程崩溃。此外,如果您的数据具有某种结构,则需要以系统独立的方式传输和格式化它。绝对不要通过网络传递原始数据结构,否则将会出现严重问题。设计良好的传输容器很困难,编写强大的解析器也很难。最好使用一些经过验证的现有库。 - datenwolf
最先进的ASN.1实现对公众开放肯定不是OsmoCom使用的,他们使用了Lev Walkin修改过的ASN1C版本。ASN1C甚至不支持ASN1 2002。您可能将“公众”与“免费”混淆了。 - user172783
@lttlrck:公共意味着:“以源代码形式向公众提供。”如果有其他更高级的开放源代码ASN.1实现,我非常感兴趣。 - datenwolf

3
ASN.1目前仍然在广泛使用,被许多标准协议所采用,包括一些正在开发中的标准(例如3GPP和IEEE 802)。市场上有几款完善的商业ASN.1工具可供选择。典型的ASN.1工具包括ASN.1编译器,可以从ASN.1消息定义生成源代码,以及针对不同标准编码规则的编解码库。通常情况下,应用程序开发人员将编写使用ASN.1编译器生成的数据结构的代码,并调用作为ASN.1工具一部分提供的编解码函数。
如果您不想使用商业ASN.1工具(无论出于何种原因),并且如果您要编写自己的ASN.1消息定义(而不是实现现有的标准协议),也许您可以选择其中一款免费的ASN.1工具,并限制您使用该工具支持的语法特性。

2

ASN.1现在已经成为一种小众技术,仅用于处理与X.509相关的数据。

你可能会考虑使用Google Protocol Buffers。


ASN.1不能用于传输公钥或AES加密文本等吗? - pimmling
是的,但你会发现它很慢且难以使用。 - bmargulies
2
它在电信领域被广泛使用,包括四个关键的LTE接口,这并不是一个小众市场。它不慢,但使用起来确实有些困难。 - user172783
好的,ASN.1 本身并不慢,但是祝你好运能找到一个漂亮干净的开源/免费库。 - bmargulies

0

如果你真的想在Java中使用ASN.1:我查看了Java的开源ASN.1库,发现只有BinaryNotes是可用的。该工具不支持所有最新的ASN.1专业功能(扩展点等),但对于定义自己的基本ASN.1语法并生成能够编码/解码这些消息的Java类来说,只需要很少的努力就可以非常有用。

对于C部分,同事们使用ASN.1C编译了一个CODEC,用于ASN.1语法 - 但我不知道任何细节。


ASN.1在所提出的问题中是否是一个好的编码方式?为什么或为什么不是? - this.josh
它与GoogleProtocolBuffers一样好或不好——这是一种面向结构化数据的语言无关编码。ASN.1的重点在于效率,特别是带宽和解析器效率。如果您的嵌入式C客户端计算能力较低,ASN.1绝对值得一看。然而,openSSL的ASN.1部分不适用于自定义ASN.1语法的自定义消息——它用于解码和编码常见数据,如X.509,因此您的第一个起点应该是查看命令行openssl asn1parse ...是否可用于编码任何可能适合您的用例的数据。 - BertNase

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