在互联网上发布签名内容的最佳方式是什么?

时间:2014-11-13 14:52:20

标签: hash digital-signature public-key

我目前正在开发一种架构,用户可以在任何服务器上发布内容。为了确保某个用户实际发布了内容(并且在发布后没有被更改),使用内容作者的私钥创建签名,其公钥可供集中存储库中的每个人访问。

问题是,我无法控制内容在这些服务器上的实际存储方式。所以我可以传输内容,例如作为一个JSON对象,所有数据都是base64编码的,并且使用这个hash64以特定顺序连接的base64编码内容创建签名:

{
    "a": "b",
    "c": "d",
    "signature": "xyz"
}

signature := sign(PrivKey, hash(b + d);

现在服务器可能会以另一种方式存储此内容,例如一个数据库。也许编码会改变。也许mysql_real_escape_string()在PHP中完成,所以东西会丢失。现在,如果想检查签名,可能会有问题。

因此,通常在创建签名时,您有一个固定的编码和一个带有某种明确分隔符的字节序列(或字符串) - 这不是这里的情况。

因此问题:在这种情况下如何处理签名?

2 个答案:

答案 0 :(得分:1)

仍然需要以位或字节为特征的消息表示才能对其进行签名。有两种方法可以做到这一点:

  1. 只存储消息的字节表示,之后不要改变它(如果消息是字符串,首先用明确定义的字符编码对其进行编码);
  2. 定义消息的规范表示,您可以直接存储规范表示消息,也可以在更新签名中的散列时将其转换为内存。
  3. 消息的规范表示是数据的特殊,唯一表示,它以某种方式将其与所有其他可能的消息区分开来;例如,这可能还包括对表的条目进行排序(只要顺序没有改变表的含义),删除空格等。

    例如,XML加密包含用于XML编码的规范化方法。显然,不可能为没有内在结构的数据定义规范化。另一个(甚至)更复杂的规范表示是针对ASN.1消息的DER(例如,X509证书本身以及 RSA签名中的)。

答案 1 :(得分:1)

我认为你真的在问两个不同的问题:

如何签署数据?

我建议尽可能使用标准的数字签名数据格式,以及"分离的签名"在其他时间。这在实践中意味着什么:提供数字签名的PDF,Word,Excel和其他文件格式应保留为这些格式。

不应使用分离签名对不提供数字签名的文件格式进行签名。分离签名的推荐标准是.p7b文件类型 - 没有数据的PKCS#7数字签名结构。 Here is an example of signing data with a detached signature from my company.

这意味着"依赖方" - 下载/接收信息的人 - 将下载两个文件。第一个是原始数据文件,没有变化。第二个文件将是第一个文件的分离签名。

好处直接支持数字签名的签名文件格式可以使用该文件的常用软件应用程序验证其签名。即,免费的Adobe PDF Reader应用程序知道如何验证经过数字签名的PDF。同样,MS Word知道如何验证签名的Word文件。

对于其他文件类型,关联的分离签名文件将向收件人保证文件自签名后未被修改以及签名者是谁(取决于信任问题,请参阅下文)。

重新数据库存储 - 您不关心数据如何存储在不同的服务器(数据库,文件系统等)上。在任何或所有情况下,数据都应保持不变。

如何在签名者和收件人之间建立信任 我建议组织创建自己的根证书。然后,您可以将证书作为文件放在SSL网站上。 (您的网站的SSL证书应来自CA,例如Comodo,VeriSign等)。结果是,信任您网站的SSL证书的人可以信任您的组织证书。而你的签名者'证书应链接到您组织的证书,从而为收件人建立信任。

这种创建自签名组织证书的方法成本低,并且提供高级别的信任。但依赖方需要下载并安装您组织的证书。

如果这样做不好,您可以从公共证书颁发机构(CA)获得签名者的证书,但由于CA的收费,这将使成本增加至少一个数量级。我的公司CoSign支持所有这些配置。