php使用ecc算法进行签名,ECDSA签名算法(ECC椭圆曲线算法3)

现在有一个场景:

Alice想要用私钥签名一个数据,Bob想要使用Alice的公钥验证这个签名;只有Alice能够进行计算签名然后得到签名,每个人都能验证签名值。

首先Alice和Bob拥有相同的椭圆曲线参数,算法被签名称之为ECDSA,是DSA算法的一个变体。

ECDSA签名算法的输入是数据的哈希值,而不是数据的本身,至于哈希算法选用哪一个就取决于自己了。为了使得ECDSA的输入值的比特数和子群的阶n的比特数一样,哈希值可能会被截断。我们把ECDSA输入称之为Z。

算法工作流程如下:

(1)取一个范围在[1, n - 1]的随机数k

(2)计算点P=kG

(3)计算r = xp mod n

(4)如果 r == 0,执行第一步

(5)计算s = k^-1 (z + r*da) mod n (da是Alice的公钥,k^-1 是 k 对n的逆元)

(6)如果s==0,执行第一步

(7)二元组(r, s)就是签名值

(一般情况,最后的结果r和s是用asn1格式封装的,至少的TLS签名和数字证书签名中是这样的,不是简单的r+s这样字节直接拼接)

9df90a3ff5eb1e4dda3b9a586038fedb.png

上图中,Alice使用私钥da对z进行签名,生成二元组(r, s)。

Bob使用A

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用 OpenSSL 库实现 ECC 椭圆曲线加密算法的示例代码: ```cpp #include <iostream> #include <openssl/ec.h> #include <openssl/ecdsa.h> #include <openssl/obj_mac.h> #include <openssl/rand.h> using namespace std; int main() { EC_KEY *ec_key; EC_GROUP *ec_group; EC_POINT *ec_point; ECDSA_SIG *ecdsa_sig; const BIGNUM *priv_key, *order; BIGNUM *x, *y, *k; unsigned char hash[SHA256_DIGEST_LENGTH]; unsigned char *sig_buf; int sig_len; // 初始化 OpenSSL 库 OpenSSL_add_all_algorithms(); // 创建椭圆曲线密钥对 ec_group = EC_GROUP_new_by_curve_name(NID_secp256k1); ec_key = EC_KEY_new_by_curve_name(NID_secp256k1); EC_KEY_generate_key(ec_key); priv_key = EC_KEY_get0_private_key(ec_key); ec_point = EC_KEY_get0_public_key(ec_key); x = BN_new(); y = BN_new(); EC_POINT_get_affine_coordinates_GFp(ec_group, ec_point, x, y, NULL); cout << "私钥:" << BN_bn2hex(priv_key) << endl; cout << "公钥:" << BN_bn2hex(x) << ", " << BN_bn2hex(y) << endl; // 生成随机数 k order = EC_GROUP_get0_order(ec_group); k = BN_new(); BN_rand_range(k, order); // 计算消息的 SHA256 哈希值 SHA256("hello world", 11, hash); // 签名消息 ecdsa_sig = ECDSA_do_sign(hash, SHA256_DIGEST_LENGTH, ec_key); sig_len = i2d_ECDSA_SIG(ecdsa_sig, NULL); sig_buf = new unsigned char[sig_len]; unsigned char *p = sig_buf; i2d_ECDSA_SIG(ecdsa_sig, &p); cout << "签名:" << endl; for (int i = 0; i < sig_len; i++) { printf("%02x", sig_buf[i]); } cout << endl; // 验证签名 int ret = ECDSA_do_verify(hash, SHA256_DIGEST_LENGTH, ecdsa_sig, ec_key); if (ret == 1) { cout << "签名验证成功" << endl; } else { cout << "签名验证失败" << endl; } // 释放资源 delete[] sig_buf; ECDSA_SIG_free(ecdsa_sig); BN_free(k); BN_free(y); BN_free(x); EC_POINT_free(ec_point); EC_KEY_free(ec_key); EC_GROUP_free(ec_group); EVP_cleanup(); return 0; } ``` 该示例代码使用 secp256k1 椭圆曲线,生成随机数 k,计算消息的 SHA256 哈希值,使用私钥对消息进行签名,并验证签名的正确性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值