gpt4 book ai didi

python - python ECDSA 和 C micro-ecc 库之间的 ECDSA 签名和验证问题

转载 作者:行者123 更新时间:2023-11-28 16:58:20 45 4
gpt4 key购买 nike

我在执行以下操作时遇到问题:

  1. 使用 Python 为 ECDSA SECP256k1 曲线创建公私钥对,并将其打印在终端上。
  2. 在 Python 脚本和 visual studio(使用 micro-ecc 库的 C 代码)中复制粘贴 key 对。这样每次运行代码时都不会生成新 key 。
  3. 使用私钥在 Python 中签署消息(“Hello”),并在终端上打印签名和消息。我知道必须先使用标准哈希算法(如 SHA256)对消息进行哈希处理,但在这种情况下,我直接使用消息进行签名。
  4. 将签名和相同的消息(哈希)复制到 Visual Studio。
  5. 当我在 visual studio 中调用验证 API 时,尽管它使用相同的公钥、消息、签名和曲线,但验证全部失败。

我正在使用的库:

  1. visual studio 中 C 语言的 micro-ecc https://github.com/kmackay/micro-ecc
  2. 用于 python 的 ECDSA https://github.com/warner/python-ecdsa

我已经测试并确保的其他事情:

  1. 在 python 中对相同的 key 对(例如(sk,vk))进行签名和验证都可以正常工作。
  2. 在 visual studio 中对相同的 key 对(例如 (sk,vk))进行签名和验证工作正常。
  3. 在 Visual Studio 中使用 microECC 签名并在 python 中使用 ECDSA 验证失败,在 Python 中使用 ECDSA 签名和使用 microECC 验证也失败。
  4. 我确信从终端粘贴的 key 副本实际上是预期的 key ,因为我已经从复制的签名 key 中交叉验证了验证 key 并且它是匹配的。

首先我通过运行这个脚本生成 key

生成 key .py

import ecdsa
from ecdsa import SigningKey, SECP256k1


sk = ecdsa.SigningKey.generate(curve=ecdsa.SECP256k1)
vk = sk.get_verifying_key()

sklst = []
for e in bytearray(sk.to_string()):
sklst.append(e)

vklst = []
for e in bytearray(vk.to_string()):
vklst.append(e)

print("Private Key is:")
print(sklst)

print("Public Key is:")
print(vklst)

GenerateKeys.py 的输出

Private Key is:
[38, 108, 90, 112, 230, 138, 62, 97, 107, 90, 227, 165, 207, 80, 251, 154, 17, 4, 73, 53, 33, 162, 33, 200, 243, 205, 116, 43, 36, 59, 201, 84]
Public Key is:
[163, 238, 83, 33, 229, 249, 105, 12, 141, 7, 214, 134, 148, 1, 198, 45, 13, 31, 9, 223, 85, 201, 98, 248, 73, 160, 40, 255, 64, 214, 250, 121, 234, 103, 212, 148, 197, 48, 210, 38, 166, 51, 30, 81, 119, 240, 125, 104, 237, 24, 3, 216, 229, 87, 45, 7, 115, 69, 94, 187, 236, 91, 142, 18]

将私钥复制粘贴到 Sign.py python 脚本中并生成签名和公钥我使用“你好”作为创建签名的消息

签名.py

import ecdsa
from ecdsa import SigningKey, SECP256k1


signinKey_lst = [38, 108, 90, 112, 230, 138, 62, 97, 107, 90, 227, 165, 207, 80, 251, 154, 17, 4, 73, 53, 33, 162, 33, 200, 243, 205, 116, 43, 36, 59, 201, 84]
signinKey_lst = bytearray(signinKey_lst)
signinKey = ecdsa.SigningKey.from_string(signinKey_lst, curve=ecdsa.SECP256k1)
verifyKey = signinKey.get_verifying_key()

signinKey_lst = []
for e in bytearray(signinKey.to_string()):
signinKey_lst.append(e)

verifyKey_lst = []
for e in bytearray(verifyKey.to_string()):
verifyKey_lst.append(e)

print("Public Key is:")
print(verifyKey_lst)

msg = "Hello"

sign = signinKey.sign(msg)
sign_lst = []

verifyKey_lst = []
for e in bytearray(sign):
sign_lst.append(e)

print("Signature is:")
print(sign_lst)

Sign.py 的输出:

Private Key is:
[38, 108, 90, 112, 230, 138, 62, 97, 107, 90, 227, 165, 207, 80, 251, 154, 17, 4, 73, 53, 33, 162, 33, 200, 243, 205, 116, 43, 36, 59, 201, 84]
Public Key is:
[163, 238, 83, 33, 229, 249, 105, 12, 141, 7, 214, 134, 148, 1, 198, 45, 13, 31, 9, 223, 85, 201, 98, 248, 73, 160, 40, 255, 64, 214, 250, 121, 234, 103, 212, 148, 197, 48, 210, 38, 166, 51, 30, 81, 119, 240, 125, 104, 237, 24, 3, 216, 229, 87, 45, 7, 115, 69, 94, 187, 236, 91, 142, 18]
Signature is:
[47, 107, 101, 228, 187, 209, 97, 180, 83, 149, 133, 71, 62, 15, 86, 186, 192, 222, 108, 221, 249, 128, 124, 7, 139, 110, 103, 108, 62, 89, 136, 152, 226, 43, 104, 166, 92, 247, 9, 201, 135, 96, 19, 75, 55, 229, 67, 198, 188, 90, 246, 17, 157, 1, 229, 71, 151, 206, 211, 95, 41, 51, 96, 42]

复制粘贴签名并在带有 micro ecc 库的 visual studio 中使用相同的消息:-

来源.c

#include "stdio.h"
#include <stdlib.h>
#include <string.h>
#include "uECC.h"
#include "constants.h"

uint8_t privateKey[32] = { 0 };
uint8_t publicKey[64] = { 163, 238, 83, 33, 229, 249, 105, 12, 141, 7, 214, 134, 148, 1, 198, 45, 13, 31, 9, 223, 85, 201, 98, 248, 73, 160, 40, 255, 64, 214, 250, 121, 234, 103, 212, 148, 197, 48, 210, 38, 166, 51, 30, 81, 119, 240, 125, 104, 237, 24, 3, 216, 229, 87, 45, 7, 115, 69, 94, 187, 236, 91, 142, 18 };
uint8_t msg[5] = { 'H','e','l','l','o' };
uint8_t sign[64] = { 47, 107, 101, 228, 187, 209, 97, 180, 83, 149, 133, 71, 62, 15, 86, 186, 192, 222, 108, 221, 249, 128, 124, 7, 139, 110, 103, 108, 62, 89, 136, 152, 226, 43, 104, 166, 92, 247, 9, 201, 135, 96, 19, 75, 55, 229, 67, 198, 188, 90, 246, 17, 157, 1, 229, 71, 151, 206, 211, 95, 41, 51, 96, 42 };

void printArray(uint8_t* pToArr, uint32_t u16ArrSize)
{
uint32_t c = 0;
printf("[ ");
for (c = 0; c < u16ArrSize; c++)
{
if (c != (u16ArrSize - 1))
{
printf(" %u,", *pToArr);
}
else
{
printf(" %u", *pToArr);
}
pToArr++;
}
printf(" ]");
return;
}

int main()
{
const struct uECC_Curve_t* curve;
#if uECC_SUPPORTS_secp256k1
curve = uECC_secp256k1();
#endif

const char* m = "Hello World"; //{0xff, 0xff, 0xff, 0xff, 0xff,0xff }

printf("\n/*************************************************************************************************\n");
printf("Validating the Encrypted hash with the public key and the hash used\n");

printf("\n\nPublic Key:\n");
printArray(publicKey, sizeof(publicKey));

printf("\n\nMsg:\n");
printArray(msg, sizeof(msg));

printf("\n\nsignature:\n");
printArray(sign, sizeof(sign));

printf("\n");
if (!uECC_verify(publicKey, msg, sizeof(msg), sign, curve))
{
printf("\nuECC_verify() failed\n");
}
else
{
printf("\nuECC_verify() succeeded\n");

}
printf("\n/*************************************************************************************************/\n");
return 0;
}

visual studio 运行 source.c 的输出:-

/*************************************************************************************************
Validating the Encrypted hash with the public key and the hash used


Public Key:
[ 148, 49, 144, 80, 185, 77, 185, 14, 186, 168, 164, 110, 123, 192, 55, 219, 184, 133, 153, 65, 144, 169, 175, 171, 203, 225, 88, 134, 51, 199, 254, 215, 237, 144, 141, 137, 80, 190, 25, 35, 33, 136, 248, 190, 114, 60, 128, 34, 155, 157, 83, 68, 187, 154, 137, 9, 51, 112, 155, 54, 88, 104, 82, 138 ]

Msg:
[ 72, 101, 108, 108, 111 ]

signature:
[ 186, 247, 43, 62, 152, 84, 40, 197, 74, 135, 80, 18, 152, 150, 121, 177, 155, 242, 1, 11, 171, 155, 45, 19, 174, 171, 190, 66, 31, 125, 214, 136, 41, 116, 139, 82, 71, 208, 4, 80, 47, 154, 100, 173, 110, 164, 25, 19, 7, 253, 175, 123, 34, 1, 99, 86, 241, 241, 211, 45, 15, 35, 210, 69 ]

uECC_verify() failed

/*************************************************************************************************/

C:\Users\prajwal.bv\source\repos\Crypt_sample1\x64\Debug\Crypt_sample1.exe (process 17160) exited with code 0.
To automatically close the console when debugging stops, enable Tools->Options->Debugging->Automatically close the console when debugging stops.
Press any key to close this window . . .

我预计运行 source.c 的输出是 uECC_verify() 成功。但它打印 uECC_verify() 失败。

最佳答案

ECDSA 签名过程分为两个阶段:

  • 根据消息计算哈希摘要
  • 然后对该摘要进行签名。

除非另有说明,否则 Python ECDSA 默认使用 SHA-1。

消息“Hello”的 SHA-1 摘要是十六进制编码的:f7ff9e8b7bb2e09b70935a5d785e0cc5d9d0abf0

这意味着您需要在调用 uECC_verify 函数时使用此摘要。

验证

用以下代码行替换您的 .c 代码中的 msg 数组:

uint8_t msg[] = { 0xf7, 0xff, 0x9e, 0x8b, 0x7b, 0xb2, 0xe0, 0x9b, 0x70, 0x93, 0x5a, 0x5d, 0x78, 0x5e, 0x0c, 0xc5, 0xd9, 0xd0, 0xab, 0xf0};

然后verfiy函数就成功了。

输出

调试控制台中的输出如下所示:

uECC_verify output

关于python - python ECDSA 和 C micro-ecc 库之间的 ECDSA 签名和验证问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56142232/

45 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com