【发布时间】:2021-11-07 22:39:52
【问题描述】:
如何使用secp256k1 (ECDSA) 密钥对包括ETH Keccak256 哈希地址签名的Tx 数据进行签名,并以十六进制编码为DER 格式并在php 中验证?
我只想使用附带的 php 库、openssl 和其他库来制作secp256k1 私钥和公钥、签名并转换为hex 中的DER 格式,以制作我的cryptcoin 样本。
以太坊地址由secp256k1 EDSA 密钥生成,用Keccak256 (sha-3-256) 哈希算法对由私钥生成的256 bits/64 character 公钥进行哈希计算以计算哈希,然后从哈希中取出最后40 个字符十六进制字符串,添加校验和,并将 x0 前缀添加到哈希字符串。
该示例在github.com/simplito/elliptic-php repo 中显示为toDER() 函数在elliptic-php/lib/EC/Signature.php。该库正在使用BN-php,但我只想使用php库,openssl等。
// https://github.com/simplito/elliptic-php ECDSA sample
<?php
use Elliptic\EC;
// Create and initialize EC context
// (better do it once and reuse it)
$ec = new EC('secp256k1');
// Generate keys
$key = $ec->genKeyPair();
// Sign message (can be hex sequence or array)
$msg = 'ab4c3451';
$signature = $key->sign($msg);
// Export DER encoded signature to hex string
$derSign = $signature->toDER('hex');
openssl_pkey_new() 和openssl_sign() 函数可以生成新的secp256k1 私钥和公钥并签名,但不能将hex 中的公钥转换为DER 格式以通过散列@987654351 生成地址@算法。
签署 Tx 哈希需要 JSON 字符串中的来自/到 ETH 地址 Tx 数据 {address:{to:address1,from:address2},amount:0,timestamp:timestamp tx, hash:sha256hash, previousHash:hash, difficulty:2...} 和 openssl_pkey_new() openssl_pkey_export() 需要制作私钥和公钥才能制作 ETH 地址。
由于openssl_pkey_new() openssl_pkey_export() 用于OPENSSL_KEYTYPE_EC 返回DER bin 键,我需要将它们转换为十六进制。
我尝试过openssl_pkey_new() 和openssl_sign() 函数,但我无法通过简单函数转换为hex 中的DER 格式。
openssl_pkey_new()函数创建新的secp256k1密钥对,只需 显示在Generating the 256bit ECDSA private key question。
$config = [
"config" => getenv('OPENSSL_CONF'),
'private_key_type' => OPENSSL_KEYTYPE_EC,
'curve_name' => 'secp256k1'
];
$res = openssl_pkey_new($config);
if (!$res) {
echo 'ERROR: Fail to generate private key. -> ' . openssl_error_string();
exit;
}
// Generate Private Key
openssl_pkey_export($res, $priv_key, NULL, $config);
// Get The Public Key
$key_detail = openssl_pkey_get_details($res);
$pub_key = $key_detail["key"];
echo "priv_key:<br>".$priv_key;
echo "<br><br>pub_key:<br>".$pub_key;
并用钥匙签名。
openssl_sign($hashdata, $signature, $private_key);
有什么办法可以通过 php 库将密钥转换为十六进制的DER?
【问题讨论】:
-
openssl_signfor EC 创建 DER binary;要将二进制转换为十六进制,请参见 stackoverflow.com/questions/14674834/… 。我不知道您所说的用 \n 分割块或删除标题是什么意思;这些听起来像是 PEM 密钥 上的可能操作,它不是签名,也不是十六进制。 -
它根本没有选项。格式取决于算法;对于 RSA,它是由 PKCS1/RFC8017 定义的;对于 DSA 和 ECDSA,它 是 DER(两个 INT 的 SEQ)在几个地方定义;对于 EdDSA,它由 8032 定义。
-
好的,谢谢。我将
ECDSA用于DER。 -
推荐的内置 bin2hex (在评论和答案中)和该链接的最高投票答案中的显式 strToHex 函数为我工作(在 7.4 中,在更正您的代码使 private_key 匹配 priv_key)。你一定是做错了什么,但由于你没有表现出你在做什么,我不知道问题出在哪里。
-
现在您谈论的是密钥,而不是签名和以太坊地址,这不是您的问题。 Stackexchange 的设计目的不是作为聊天论坛或进行讨论或依赖于 cmets 中的添加,这些内容经常被删除;请阅读“欢迎”页面,即“旅游”。请把你的问题放在你的问题中。但是请考虑一下,以太坊地址根本不使用私钥或 DER,并且它们的输入不是十六进制的,有时它们的输出。
标签: php private-key elliptic-curve ecdsa der