当前位置: 首页 > 知识库问答 >
问题:

验证openssl c中的签名,该签名由JAVA DSA签名?

仇和蔼
2023-03-14

我需要用c语言验证由JAVA签名API生成的签名。我有一套相同的公钥和私钥。我还验证了c语言的签名和验证工作。但是我在验证JAVA生成的签名时遇到了问题。我看了所有的文件,尝试了不同的方法,但我似乎还是不明白。我将使用用于验证的原始JAVA代码粘贴等效的c代码。

原始JAVA代码:

public static boolean verify(byte[] data, byte[] _signature, byte[] _publicKey) throws GeneralSecurityException {
        Signature signatureInstance = Signature.getInstance("DSA", "SUN");
        signatureInstance.initVerify(getPublicKey(_publicKey));
        signatureInstance.update(data);
        return signatureInstance.verify(_signature);
    }

C代码:

//sign_buffer contains the binary signature.

    int ret = DSA_verify(NID_dsa, data, sizeof(data), sign_buffer,
                          sign_length, pubkey);
if (ret != 1) {
            cerr << "verify failed" << endl;
            exit(-1);
        }

我有3个问题:

  • 这是验证签名的正确方法吗?
  • 我需要在验证数据之前对其进行散列吗?如果是,那么JAVA在签名之前是如何做的

共有1个答案

云鸿祯
2023-03-14

java代码生成的DSA签名编码为ASN.1。假设已将其存储在名为sig的文件中,则可以使用openssl asn1parse命令进行验证,如下所示:

$ openssl asn1parse -inform der -in sig -i
    0:d=0  hl=2 l=  44 cons: SEQUENCE          
    2:d=1  hl=2 l=  20 prim:  INTEGER           :64C91D32CC10D7B67A7994BE680FA2BB07C431E2
   24:d=1  hl=2 l=  20 prim:  INTEGER           :712F1C768CFFA704DA1BEFA5A36517CB4776E6FF

为了将这种格式化的签名加载到OpenSSLDSA_SIG结构中,您必须利用函数d2i_DSA_SIG()。重用变量的名称:

const unsigned char *ptr = sign_buffer;
DSA_SIG *dsasig = d2i_DSA_SIG(NULL, &ptr, sign_length);

ptr的值将被修改为超出读取的字节,如留档中所述。

事实上,在验证之前,您必须使用与签名时相同的哈希算法对数据字节进行哈希。似乎"DSA"是"SHA1with DSA"的同义词。我已经通过测试验证了这一点,但我建议在代码中尽可能明确,并使用全名来代替一些不清楚的别名。如何使用OpenSSL计算摘要的示例代码可以在维基条目EVP消息摘要中找到。

然后,您终于准备好进行验证了

verify_result = DSA_do_verify(mdvalue, mdlen, dsasig, dsapubkey);

返回代码1表示验证成功,0表示验证失败,-1是其他一些错误。

建议使用EVP级别的API,而不是较低级别的DSA-API,但是DSA\u do\u verify()似乎更接近您已经得到的位置,并且它也可以工作。

 类似资料:
  • 我想创建一个签名并使用openssl验证它。我想有我的签名的十六进制输出。 这是我的密码 我得到这个错误: 如果我在创建签名的过程中删除了-hex,它就可以工作了。

  • 问题内容: 我正在尝试以编程方式验证jar文件是否未被明显篡改。我有2个要防止的用例。1)修改现有类2)在罐子中添加新类 我使用jarsigner签名了罐子。当我用jarsigner验证以上两种情况之一时,它的工作方式就与我期望的一样。 当我尝试使用如何以编程方式验证用jarsigner签名的jar 或如何通过自签名的jar验证签名中的示例以编程方式进行操作时 ?但是,我没有任何SecurityE

  • 我正在编写一些代码,试图对一些数据进行签名。在将openssl生成的私钥转换为Java密钥库之后,我将Java签名类与SHA256withRSA一起使用。我试图确认openssl中Java类返回的签名,但由于某些原因,我无法让openssl进行验证。我最终需要在iOS Swift 3中实现这个签名验证,但在找到库之前,我想尝试根据openssl标准检查Java签名。 例如,我从我们的登录服务器得到

  • 概览 首先同步下项目概况: 上篇文章分享了,路由中间件 - Jaeger 链路追踪(实战篇),文章反响真是出乎意料, 「Go中国」 公众号也转发了,有很多朋友加我好友交流,直呼我大神,其实我哪是什么大神,只不过在本地实践了而已,对于 Go 语言的使用,我还是个新人,在这里感谢大家的厚爱! 这篇文章咱们分享:路由中间件 - 签名验证。 为什么使用签名验证? 这个就不用多说了吧,主要是为了保证接口安全

  • 我的手被https、ssl、PKI之类的东西弄得脏兮兮的。对于自签名证书,有一点我不太理解。假设我想创建一个自签名证书,并在我们想要建立安全连接时将其发送给我的朋友。 所以步骤是: 创建一个私钥。 创建一个公钥。 用我的公钥在证书上签名。 因此,当我的朋友得到我的证书时,他必须验证他得到的证书是我的,他需要解密数字签名。但为了解密和验证他必须拥有我的私钥。所以,我有点困惑。

  • 我正在尝试从外部远程服务对文档进行签名。签署过程分两个阶段进行。远程服务在第一阶段期待base64编码的散列,并在身份验证后发出令牌。在第二阶段,我们将使用接收到的令牌再次传递相同的散列并获得base64签名的散列。我在这里附上签名错误的文件。文件 如果有人可以分析它并指导我评估无效签名背后的原因。我正在使用执行与pdf相关的操作。 更新 根据反馈,我做了一些更正。文档现在正在更改。已更改的文档