我正在用 Rust 编写一个小型区块链模拟程序,并且正在努力使用 ECDSA 签名密钥,以便我可以签署添加到区块链的交易。
我在名为
crypto.rs
的文件中配置了以下密钥对:
pub struct KeyPair {
pub name: String,
pub public_key: String,
private_key: String,
}
以及以下实现来生成密钥:
impl KeyPair {
pub fn generate(name: String, key_store: &mut KeyStore) -> KeyPair {
// private key first
let secret = SecretKey::random(&mut OsRng);
let private_key = hex::encode(&secret.to_bytes());
// then public key
let public_key = hex::encode(secret.public_key().to_sec1_bytes());
let key_pair: KeyPair = KeyPair {
name,
public_key,
private_key,
};
// store a clone and return the original for further operations
key_store.append_key_pair(key_pair.clone());
key_store.write();
key_pair
}
}
测试会在名为
key_store.json
的文件中生成以下内容:
{
"keys": [
{
"name": "TEST",
"public_key": "040eda3b0d1b30a78cc830ab9e69dc25a52d5448c3c8228511481a67b1f6420bc55beb4efc297a49a657cfe08b7873293e78fef553724453f55eea3656a6369d5a",
"private_key": "ccb789f12826fd81b45f27489b73ac5650f46f9b8f0281922f459be515f018b6"
}
]
}
现在要签署交易哈希,我需要从私钥(SecretKey)获取签名密钥,但我所做的一切似乎都不起作用。
我尝试使用此函数提取签名,但它出现恐慌
signature error
:
pub fn get_signature(&self, hash: &String) -> String {
let private_key = self.get_private_key();
let signing_key = match private_key.parse::<SigningKey>() {
Ok(key) => key,
Err(e) => panic!("Error parsing signing key from private key: {}", e),
};
let signature: Signature = signing_key.sign(&hash.as_bytes());
signature.to_string()
}
我使用这篇 SO 文章来帮助理解实现:
此实现使用
pem
但我选择使用转换为十六进制的字节字符串,因为这是存储密钥的常见方法。
此尝试会导致出现此消息的恐慌
Error parsing bytes to String: invalid utf-8 sequence of 1 bytes from index 0
:
pub fn get_signature(&self, hash: &String) -> String {
let private_key: String = self.get_private_key();
let decoded: Vec<u8> = match hex::decode(&private_key) {
Ok(bytes) => bytes,
Err(e) => panic!("Error decoding bytes: {}", e),
};
let str_from_bytes: String = match String::from_utf8(decoded) {
Ok(s) => s,
Err(e) => panic!("Error parsing bytes to String: {}", e),
};
let signing_key = match str_from_bytes.parse::<SigningKey>() {
Ok(key) => key,
Err(e) => panic!("Error parsing signing key from private key: {}", e),
};
let signature: Signature = signing_key.sign(&hash.as_bytes());
signature.to_string()
}
有人知道如何从 SecretKey 转换为十六进制后获取签名密钥吗?
谢谢
实验后,此函数返回签名,用于稍后验证签名的签名密钥
pub fn get_signature(&self, hash: &String) -> (Signature, SigningKey) {
let private_key = self.get_private_key();
let key_bytes = hex::decode(&private_key).unwrap();
let signing_key = SigningKey::from_slice(key_bytes.as_slice()).unwrap();
let signature: Signature = signing_key.sign(&hash.as_bytes());
(signature, signing_key)
}
使用
from_slice
初始化 SigningKey 似乎有效:
SigningKey::from_slice(key_bytes.as_slice()).unwrap()
为了完整起见,随附的
verify
函数如下所示:
pub fn verify(&self, signature: Signature, signing_key: SigningKey, hash: String) -> bool {
let verifying_key = VerifyingKey::from(&signing_key);
let verified = match verifying_key.verify(&hash.as_bytes(), &signature) {
Ok(_res) => true,
Err(_) => false,
};
verified
}
非常欢迎评论和替代解决方案,因为我不是 100% 认为这是最好的方法,但这已经足够好了。