weixin_39743511
weixin_39743511
2020-12-02 07:59

我在报文中获取 服务器 发送的签名值,然后调用SM2_verify 验证不正确

1:我用360访问国密服务器。抓包,双方使用了ECC_SM4_SM3。(我有那台服务器的私钥,服务器签名证书和加密证书是同一个) 2:报文中获取client random, server random, sign_cert。 3:报文中获取server key exchange 的签名值。 4:使用GMSSL 中 SM2_compute_message_digest 函数 对 (2) 计算hash值。 5:调用 SM2_verify 对(3) 进行 验证签名。

5 验证签名时 失败了。我也把ID改成了通用的 1234567812345678,依旧校验失败。不知道为什么。 是我 4 中缺少什么流程了吗? 由于2、3中的内容是直接从wireshark中拷贝出来的,不存在值被我弄错的情况。

/client random + server random + sign cert /

unsigned char msg_tmp[]= { /client random/ 0x76, 0x85, 0x03, 0x39, 0xfa, 0x85, 0x64, 0xf1, 0xd0, 0x00, 0x0f, 0xbe, 0x43, 0x61, 0xd6, 0x30, 0xaf, 0xcd, 0x69, 0xc1, 0x80, 0x04, 0xfc, 0xea, 0xe0, 0x2d, 0x36, 0x7d, 0xf3, 0x36, 0x0f, 0x71, /server random/ 0x57, 0x76, 0x0a, 0x46, 0x6d, 0xa5, 0x4f, 0x17, 0x13, 0xb3, 0xab, 0xd6, 0x6a, 0x81, 0x97, 0x1b, 0x77, 0x46, 0x8c, 0x85,0x84, 0xbd, 0x44, 0x8d, 0xa4, 0xd4, 0x48, 0xf8, 0x8b, 0xda, 0xe0, 0x05, /sign cert/ 0x30, 0x82, 0x02, 0xe9, 0x30, 0x82, 0x02, 0x8e, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00 , 0x96, 0xc0, 0x64, 0xd0, 0x86, 0x0c, 0xd4, 0xdb, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x81, 0x1c, 0xcf , 0x55, 0x01, 0x83, 0x75, 0x30, 0x81, 0x82, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06 , 0x13, 0x02, 0x43, 0x4e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x68 , 0x64, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x02, 0x62, 0x6a, 0x31, 0x0b , 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x02, 0x64, 0x70, 0x31, 0x14, 0x30, 0x12, 0x06 , 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x0b, 0x74, 0x65, 0x73, 0x74, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x64 , 0x70, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0d, 0x74, 0x65, 0x73, 0x74 , 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x09, 0x2a , 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x0f, 0x74, 0x65, 0x73, 0x74, 0x64, 0x69 , 0x6e, 0x67, 0x40, 0x64, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x36, 0x30 , 0x35, 0x31, 0x36, 0x30, 0x31, 0x34, 0x30, 0x34, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x31, 0x30, 0x35 , 0x31, 0x35, 0x30, 0x31, 0x34, 0x30, 0x34, 0x30, 0x5a, 0x30, 0x81, 0x82, 0x31, 0x0b, 0x30, 0x09 , 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x4e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55 , 0x04, 0x08, 0x0c, 0x02, 0x68, 0x64, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c , 0x02, 0x62, 0x6a, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x02, 0x64, 0x70 , 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x0b, 0x74, 0x65, 0x73, 0x74, 0x64 , 0x69, 0x6e, 0x67, 0x5f, 0x64, 0x70, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c , 0x0d, 0x74, 0x65, 0x73, 0x74, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x31, 0x1e , 0x30, 0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x0f, 0x74 , 0x65, 0x73, 0x74, 0x64, 0x69, 0x6e, 0x67, 0x40, 0x64, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x59 , 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x81, 0x1c , 0xcf, 0x55, 0x01, 0x82, 0x2d, 0x03, 0x42, 0x00, 0x04, 0x1b, 0xef, 0x7e, 0xef, 0x31, 0x61, 0xfa , 0xd8, 0x1c, 0x77, 0x0c, 0x1d, 0x98, 0xfe, 0x87, 0x5f, 0x24, 0xb6, 0xf6, 0x9e, 0xbe, 0xc5, 0xfa , 0x75, 0x5a, 0xe8, 0x0e, 0x0f, 0x8b, 0x86, 0x54, 0x28, 0x29, 0x38, 0xc9, 0xae, 0xbc, 0x6a, 0xac , 0x0f, 0x5d, 0xda, 0x19, 0xb2, 0x8d, 0xc2, 0x13, 0x4b, 0x5f, 0xec, 0x83, 0xae, 0x17, 0x52, 0x6e , 0x51, 0xd7, 0xd6, 0x74, 0x32, 0x15, 0x47, 0x3e, 0xc8, 0xa3, 0x81, 0xea, 0x30, 0x81, 0xe7, 0x30 , 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x6c, 0xa7, 0x21, 0x73, 0x03, 0x91 , 0x95, 0x1e, 0x62, 0xb1, 0x7b, 0x1b, 0x86, 0x50, 0xe2, 0x41, 0x28, 0x9d, 0x91, 0xc9, 0x30, 0x81 , 0xb7, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x81, 0xaf, 0x30, 0x81, 0xac, 0x80, 0x14, 0x6c, 0xa7 , 0x21, 0x73, 0x03, 0x91, 0x95, 0x1e, 0x62, 0xb1, 0x7b, 0x1b, 0x86, 0x50, 0xe2, 0x41, 0x28, 0x9d , 0x91, 0xc9, 0xa1, 0x81, 0x88, 0xa4, 0x81, 0x85, 0x30, 0x81, 0x82, 0x31, 0x0b, 0x30, 0x09, 0x06 , 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x43, 0x4e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04 , 0x08, 0x0c, 0x02, 0x68, 0x64, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x02 , 0x62, 0x6a, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x02, 0x64, 0x70, 0x31 , 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x0b, 0x74, 0x65, 0x73, 0x74, 0x64, 0x69 , 0x6e, 0x67, 0x5f, 0x64, 0x70, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0d , 0x74, 0x65, 0x73, 0x74, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x31, 0x1e, 0x30 , 0x1c, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x0f, 0x74, 0x65 , 0x73, 0x74, 0x64, 0x69, 0x6e, 0x67, 0x40, 0x64, 0x70, 0x2e, 0x63, 0x6f, 0x6d, 0x82, 0x09, 0x00 , 0x96, 0xc0, 0x64, 0xd0, 0x86, 0x0c, 0xd4, 0xdb, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04 , 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x81, 0x1c, 0xcf, 0x55, 0x01 , 0x83, 0x75, 0x03, 0x49, 0x00, 0x30, 0x46, 0x02, 0x21, 0x00, 0xed, 0x00, 0xc4, 0x43, 0xfc, 0x39 , 0x12, 0x13, 0xf3, 0x5c, 0x09, 0x8e, 0xe5, 0xfb, 0xcd, 0x97, 0x7f, 0x87, 0xa1, 0x76, 0xf4, 0x1d , 0x9d, 0x96, 0xa5, 0x2c, 0x4f, 0x8f, 0x20, 0x19, 0xca, 0x2c, 0x02, 0x21, 0x00, 0x91, 0x5e, 0x44 , 0x60, 0xfd, 0x59, 0x1e, 0x5d, 0xd8, 0x92, 0x91, 0x16, 0x1c, 0xe7, 0x43, 0xed, 0x60, 0xa6, 0x6c , 0x3e, 0x1f, 0xa6, 0x3b, 0x0f, 0x5e, 0x7a, 0x60, 0x53, 0x76, 0x7d, 0x0f, 0x50 };

/服务器发送的server key exchange/ unsigned char sig_real[]= { 0x30,0x45,0x02,0x20,0x51,0x57,0x16,0xc4,0x1c,0xd7, 0xe5,0x34,0x18,0xfc,0x71,0xde,0xb9,0xd6,0xe5,0x02,0x44,0x0a,0x09,0x7f,0x04,0xf2, 0x18,0xa8,0x66,0xb2,0x3d,0x80,0x94,0x9b,0xaf,0x15,0x02,0x21,0x00,0x8c,0x04,0xed, 0xc2,0x8e,0x27,0xb1,0x52,0x67,0x32,0xd8,0x27,0x26,0xf2,0x1d,0xb3,0x36,0x0f,0x38, 0x23,0x6f,0x01,0xab,0x07,0x4d,0x06,0x2c,0xf0,0x9d,0xcb,0x79,0x97

};

unsigned char dig_out[64]; int dig_out_len; unsigned char sig_out[100]; int sig_out_len;

int main(int argc, char argv) { BIO in; int j; EC_KEY ec_key; int ret = -1; ERR_load_crypto_strings();


/*加载私钥文件,私钥文件见后文*/
in = BIO_new(BIO_s_file());
if (BIO_read_filename(in, "/studio/test_ding_gm.key") <= 0) 
{
    printf("load pri key err\n");
    return 0;
}

/*私钥文件中包含公钥,故ec_key 中存在公钥*/
ec_key = PEM_read_bio_ECPrivateKey(in, NULL, NULL, NULL);
if (ec_key == NULL)
{
    printf("load ECPrivateKey err\n");
    return 0;
}

/*对msg_tmp 进行digest,理论上ec_key应该是签名证书的公钥,但是私钥中也包含了签名证书的公钥,故可以直接使用*/
ret = SM2_compute_message_digest(EVP_sm3() , EVP_sm3(), msg_tmp, sizeof(msg_tmp), dig_out, &dig_out_len, ec_key);
printf("compute_message_digest dig_out_len:%d,ret:%d\n",dig_out_len, ret);

/*验证签名结果*/
ret = SM2_verify(EVP_PKEY_EC, dig_out, dig_out_len, sig_real, sizeof(sig_real), ec_key);
printf("sm2 verify:%d\n",ret);
BIO_free(in);

return ret;

}

/* 私钥*/ -----BEGIN EC PRIVATE KEY----- MHcCAQEEIFrEsU1dz/sHEbQoFFCFAoEfyHTFAlNYjinPLjmcMsF3oAoGCCqBHM9V AYItoUQDQgAEG+9+7zFh+tgcdwwdmP6HXyS29p6+xfp1WugOD4uGVCgpOMmuvGqs D13aGbKNwhNLX+yDrhdSblHX1nQyFUc+yA== -----END EC PRIVATE KEY-----

/签名证书、加密证书/ -----BEGIN CERTIFICATE----- MIIC6TCCAo6gAwIBAgIJAJbAZNCGDNTbMAoGCCqBHM9VAYN1MIGCMQswCQYDVQQG EwJDTjELMAkGA1UECAwCaGQxCzAJBgNVBAcMAmJqMQswCQYDVQQKDAJkcDEUMBIG A1UECwwLdGVzdGRpbmdfZHAxFjAUBgNVBAMMDXRlc3RkaW5nX3Jvb3QxHjAcBgkq hkiG9w0BCQEWD3Rlc3RkaW5nQGRwLmNvbTAeFw0xNjA1MTYwMTQwNDBaFw0yMTA1 MTUwMTQwNDBaMIGCMQswCQYDVQQGEwJDTjELMAkGA1UECAwCaGQxCzAJBgNVBAcM AmJqMQswCQYDVQQKDAJkcDEUMBIGA1UECwwLdGVzdGRpbmdfZHAxFjAUBgNVBAMM DXRlc3RkaW5nX3Jvb3QxHjAcBgkqhkiG9w0BCQEWD3Rlc3RkaW5nQGRwLmNvbTBZ MBMGByqGSM49AgEGCCqBHM9VAYItA0IABBvvfu8xYfrYHHcMHZj+h18ktvaevsX6 dVroDg+LhlQoKTjJrrxqrA9d2hmyjcITS1/sg64XUm5R19Z0MhVHPsijgeowgecw HQYDVR0OBBYEFGynIXMDkZUeYrF7G4ZQ4kEonZHJMIG3BgNVHSMEga8wgayAFGyn IXMDkZUeYrF7G4ZQ4kEonZHJoYGIpIGFMIGCMQswCQYDVQQGEwJDTjELMAkGA1UE CAwCaGQxCzAJBgNVBAcMAmJqMQswCQYDVQQKDAJkcDEUMBIGA1UECwwLdGVzdGRp bmdfZHAxFjAUBgNVBAMMDXRlc3RkaW5nX3Jvb3QxHjAcBgkqhkiG9w0BCQEWD3Rl c3RkaW5nQGRwLmNvbYIJAJbAZNCGDNTbMAwGA1UdEwQFMAMBAf8wCgYIKoEcz1UB g3UDSQAwRgIhAO0AxEP8ORIT81wJjuX7zZd/h6F29B2dlqUsT48gGcosAiEAkV5E YP1ZHl3YkpEWHOdD7WCmbD4fpjsPXnpgU3Z9D1A= -----END CERTIFICATE-----

该提问来源于开源项目:guanzhi/GmSSL

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

10条回答

  • weixin_39527911 weixin_39527911 5月前

    请注意看国密规范0024-2014关于ServerKeyExchange的部分 image

    这里的加密证书表示是 opaque ASN.1Cert<1..2^24-1>,这是一个变长向量,因此在证书之前需要有3字节的长度(有关变长向量的定义,在国密规范中的6.2.2章节;在TLS中是4.3章节:https://tools.ietf.org/html/rfc5246#section-4.3 )

    这里的表示方法与Server Certificate中的证书表示是一样的, 你可以对比一下抓到的Server Certificate包,在每张证书之前,是不是有3字节的长度?

    这3字节的长度也需要参与ServerKeyExchange的签名计算。

    点赞 评论 复制链接分享
  • weixin_39743511 weixin_39743511 5月前

    多谢指教!验证成功了。

    点赞 评论 复制链接分享
  • weixin_39743511 weixin_39743511 5月前

    应该不是这个问题。

    应该是人行服务器 或者 360浏览器 约定了自己的ID值,导致我验证错误。

    有谁知道ECC算法发送server key exchange时, 1:被签名message data 是否 是 {client random + server random + sign cert}? 2:计算哈希值时,id是否用的是默认的"1234567812345678"?

    点赞 评论 复制链接分享
  • weixin_39996234 weixin_39996234 5月前

    1)message data 是:“双方随机数 + 加密证书”的签名值; 2 ) 默认 id是:"1234567812345678"。

    点赞 评论 复制链接分享
  • weixin_39743511 weixin_39743511 5月前

    想确认一下, message data 是:“双方随机数 + 加密证书”的签名值; 是否是 “32字节的客户端随机数 + 32字节的服务器端随机数 + 二进制(DER编码)加密证书的” 三者拼接起来的? 然后再拿 Z + message data 拼接起来,使用sm3哈希出结果,对结果进行签名?

    点赞 评论 复制链接分享
  • weixin_39996234 weixin_39996234 5月前

    利用SM3计算出 H值,再用签名私钥对 H 值进行签名。

    点赞 评论 复制链接分享
  • weixin_39743511 weixin_39743511 5月前

    H值??我在规范中没有找到H相关的啊。。 M = “32字节的客户端随机数 + 32字节的服务器端随机数 + 二进制(DER编码)加密证书” M' = Z || M (M' 总长度:32字节的Z + 32字节随机数 + 32 字节随机数 + 加密证书长度) 你说的H指的是 sm3(M')吗? 我也是这么发送server key exchange,可惜360不认。

    点赞 评论 复制链接分享
  • weixin_39633054 weixin_39633054 5月前

    目前GmSSL在签名时默认不加入Z值,因此无法验证国密标准的证书。

    点赞 评论 复制链接分享
  • weixin_39743511 weixin_39743511 5月前

    老师您好,不知道您说的Z值指的是什么? 在SM2算法规范中,看到了在计算签名时,首先需要将 id_len+id+a+b+xg+yg+xa+ya 计算出一个hash,您的Z值是否指的是这个?但是 我看GMSSL 代码,SM2_compute_message_digest 函数中 这个hash值加进去了的。

    点赞 评论 复制链接分享
  • weixin_39633054 weixin_39633054 5月前

    Z值是这个。证书所用的上层API没有将这个值加入计算。

    点赞 评论 复制链接分享

相关推荐