Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
mrpre opened this issue Aug 31, 2016 · 10 comments

Comments

@mrpre
Copy link

mrpre commented Aug 31, 2016

@Jkinglyf @conezxy @guanzhi

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
Copy link
Owner

guanzhi commented Aug 31, 2016

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

@mrpre
Copy link
Author

mrpre commented Aug 31, 2016

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

@guanzhi
Copy link
Owner

guanzhi commented Aug 31, 2016

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

@mrpre
Copy link
Author

mrpre commented Sep 1, 2016

应该不是这个问题。

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

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

@Jkinglyf
Copy link

Jkinglyf commented Sep 1, 2016

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

@mrpre
Copy link
Author

mrpre commented Sep 1, 2016

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

@Jkinglyf
Copy link

Jkinglyf commented Sep 2, 2016

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

@mrpre
Copy link
Author

mrpre commented Sep 2, 2016

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

@conezxy
Copy link

conezxy commented Sep 2, 2016

请注意看国密规范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的签名计算。

@mrpre
Copy link
Author

mrpre commented Sep 2, 2016

@conezxy 多谢指教!验证成功了。

@mrpre mrpre closed this as completed Sep 2, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants