如何生成密钥,私钥,签名
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何生成密钥,私钥,签名相关的知识,希望对你有一定的参考价值。
参考技术A 数字签名主要经过以下几个过程:信息发送者使用一单向散列函数(HASH函数)对信息生成信息摘要;信息发送者使用自己的私钥签名信息摘要;信息发送者把信息本身和已签名的信息摘要一起发送出去;信息接收者通过使用与信息发送者使用的同一个单向散列函数(HASH函数)对接收的信息本身生成新的信息摘要,再使用信息发送者的公钥对信息摘要进行验证,以确认信息发送者的身份和信息是否被修改过。数字加密主要经过以下几个过程:当信息发送者需要发送信息时,首先生成一个对称密钥,用该对称密钥加密要发送的报文;信息发送者用信息接收者的公钥加密上述对称密钥;信息发送者将第一步和第二步的结果结合在一起传给信息接收者,称为数字信封;信息接收者使用自己的私钥解密被加密的对称密钥,再用此对称密钥解密被发送方加密的密文,得到真正的原文。数字签名和数字加密的过程虽然都使用公开密钥体系,但实现的过程正好相反,使用的密钥对也不同。数字签名使用的是发送方的密钥对,发送方用自己的私有密钥进行加密,接收方用发送方的公开密钥进行解密,这是一个一对多的关系,任何拥有发送方公开密钥的人都可以验证数字签名的正确性。数字加密则使用的是接收方的密钥对,这是多对一的关系,任何知道接收方公开密钥的人都可以向接收方发送加密信息,只有唯一拥有接收方私有密钥的人才能对信息解密。另外,数字签名只采用了非对称密钥加密算法,它能保证发送信息的完整性、身份认证和不可否认性,而数字加密采用了对称密钥加密算法和非对称密钥加密算法相结合的方法,它能保证发送信息保密性。在服务器密钥交换中使用私钥计算签名
【中文标题】在服务器密钥交换中使用私钥计算签名【英文标题】:Compute a signature with private key in Server Key Exchange 【发布时间】:2022-01-05 22:59:28 【问题描述】:在https://tls.ulfheim.net/ 有一个示例显示如何在“服务器密钥交换”部分计算签名。
https://i.ibb.co/Y7fbkDw/1.jpg(这张图片显示了我所指网站上的服务器密钥交换部分。无法在这篇文章中嵌入图片。)
无论我尝试什么,我都没有得到与该网站上相同的输出,我不明白为什么。
我尝试以两种不同的方式存储相同的数据,然后使用他们在示例中使用的相同 openssl 命令。没有一种方法给出相同的输出。
方法一。
char hex[] = 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x20, 0x9f, 0xd7, 0xad, 0x6d, 0xcf, 0xf4, 0x29, 0x8d, 0xd3, 0xf9, 0x6d, 0x5b, 0x1b, 0x2a, 0xf9, 0x10, 0xa0, 0x53, 0x5b, 0x14, 0x88, 0xd7, 0xf8, 0xfa, 0xbb, 0x34, 0x9a, 0x98, 0x28, 0x80, 0xb6, 0x15 ;
ofstream myfile("c:/hex1.txt", ios::binary);
myfile.write(hex, sizeof hex);
然后:
openssl dgst -hex -sign server.key -sha256 hex1.txt
方法二。
我将这些数据存储在 hex2.txt(ASCII 格式)中:
\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x20\x9f\xd7\xad\x6d\xcf\xf4\x29\x8d\xd3\xf9\x6d\x5b\x1b\x2a\xf9\x10\xa0\x53\x5b\x14\x88\xd7\xf8\xfa\xbb\x34\x9a\x98\x28\x80\xb6\x15
然后:
openssl dgst -hex -sign server.key -sha256 hex2.txt
【问题讨论】:
【参考方案1】:方法一
你漏掉了curve_info
。 applicable RFC 4492 section 5.4 为 TLS1.2 更新的 RFC 5246 appendix A.7 实际上定义了要结束的签名 client_random + server_random + SKX_params 其中 SKX_params 类型为 ServerECDHParams
并由 ECParameters curve_params
和 ECPoint public
组成 - 这些是 ulfheim标签曲线信息和公钥。
有了正确的数据,我得到了正确的结果:
$ od -tx1 70148855.bin
0000000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
0000020 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
0000040 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f
0000060 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f
0000100 03 00 1d 20 9f d7 ad 6d cf f4 29 8d d3 f9 6d 5b
0000120 1b 2a f9 10 a0 53 5b 14 88 d7 f8 fa bb 34 9a 98
0000140 28 80 b6 15
$ openssl sha256 <70148855.bin -sign $privkey -hex
(stdin)= 0402b661f7c191ee59be45376639bdc3d4bb81e115ca73c8348b525b0d2338aa144667ed9431021412cd9b844cba29934aaacce873414ec11cb02e272d0ad81f767d33076721f13bf36020cf0b1fd0ecb078de1128beba0949ebece1a1f96e209dc36e4fffd36b673a7ddc1597ad4408e485c4adb2c873841249372523809e4312d0c7b3522ef983cac1e03935ff13a8e96ba681a62e40d3e70a7ff35866d3d9993f9e26a634c81b4e71380fcdd6f4e835f75a6409c7dc2c07410e6f87858c7b94c01c2e32f291769eacca71643b8b98a963df0a329bea4ed6397e8cd01a110ab361ac5bad1ccd840a6c8a6eaa001a9d7d87dc3318643571226c4dd2c2ac41fb
已添加: 顺便说一句,这仅适用于 TLS1.2 及更低版本中用于 RSA 的签名方案,即 PKCS1v1 中的“块类型 1”方案,现在是 RSASSA-PKCS1-v1_5在 PKCS1v2 中,是确定性的。大多数数字签名方案都不是,包括 TLS1.3 中使用的 RSA-PSS 方案,您无法通过将签名与另一个签名进行比较来检查或测试签名。只能使用方案提供的验证方式。
方法二
完全不正确。 \x00
等是用于 C 和 C++(如您在方法 1 中所做的那样)以及一些其他语言(如 Java、JS/ES 和 Python)以及某些工具的源代码中的符号就像 Unix 中的 printf
命令和 awk
程序一样。但它在其他地方不起作用,特别是在 OpenSSL 读取的文件中不起作用(至少对于数据;它可能在配置文件中起作用,我必须检查)。您的方法二(散列和)标记字节 0x5c 0x78 0x30 0x30 0x5c 0x78 0x30 0x31 代表字符 \ x 0 0 \ x 0 1
等,而不是字节 0x00 0x01 等,不出所料,这是完全不同和错误的。
【讨论】:
以上是关于如何生成密钥,私钥,签名的主要内容,如果未能解决你的问题,请参考以下文章