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

Hash 在互联网上发布签名内容的最佳方式是什么?,hash,digital-signature,public-key,Hash,Digital Signature,Public Key,我目前正在开发一种体系结构,用户可以在任何服务器上发布内容。为了确保内容实际上已由某个用户发布(并且在发布后未被更改),将使用内容作者的私钥创建签名,其公钥可供集中存储库中的每个人访问 问题是,我无法控制内容在这些服务器上的实际存储方式。因此,我可能会传输内容,例如,作为一个JSON对象,所有数据都是base64编码的,签名是使用此内容的哈希创建的,base64编码的内容按一定顺序连接: { "a": "b", "c": "d", "signature": "xyz" }

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

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

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

现在,服务器可能会以另一种方式存储此内容,例如数据库。所以编码可能会改变。也许mysql\u real\u escape\u string()是用PHP完成的,所以东西会丢失。现在,如果要检查签名,可能会有问题

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


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

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

  • 只需存储消息的字节表示形式,以后不要更改它(如果消息是字符串,请首先使用定义良好的字符编码对其进行编码)
  • 定义消息的规范表示,可以将规范表示直接存储到消息中,也可以在更新签名中的哈希时将其转换到内存中
  • 消息的规范表示是数据的一种特殊、唯一的表示,它以某种方式将其与所有其他可能的消息区分开来;例如,这可能还包括对表的条目进行排序(只要顺序不改变表的含义)、删除空白等


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

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

    数据应该如何签名?

    我建议在可能的情况下使用标准数字签名数据格式,在其他时间使用“分离签名”。这在实践中意味着什么:PDF、Word、Excel和其他提供数字签名的文件格式应保持这些格式

    不提供数字签名的文件格式应使用分离的签名进行签名。分离签名的推荐标准是.p7b文件类型–一种没有数据的PKCS#7数字签名结构

    这意味着“依赖方”——下载/接收信息的人——将下载两个文件。第一个是原始数据文件,未更改。第二个文件将是第一个文件的分离签名

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

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

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

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

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


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

    您误解了m_r_e_s()。它不会“改变”正在插入数据库的内容。它只添加了一些转义,以便插入的字符串中的任何SQL元字符都被设置为“非元”,并且不会影响查询的语法。存储在实际磁盘DB文件中的内容与转义前的字符串完全相同。此问题包含一些特定于运行时的部分,但如果不是这样,最好在转义时询问这些内容。回答这个问题并不需要编程。如果没有更多的信息,就不可能回答得更详细。
    signature := sign(PrivKey, hash(b + d);