RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1505982
Accepted
RandomDice 779
RandomDice 779
Asked:2023-03-18 14:14:34 +0000 UTC2023-03-18 14:14:34 +0000 UTC 2023-03-18 14:14:34 +0000 UTC

如何在 Rust 中签署文件?

  • 772

您需要使用 Rust 对文件进行签名。我正在尝试这样做:

extern crate openssl;

use std::env;
use std::string::String;
use std::fs::File;
use std::path::Path;                                                                             use openssl::pkey::PKey;
use openssl::sign::Signer;                                                                       use openssl::hash::MessageDigest;
use std::io::Write;
use std::io::Read;

fn sign(file: String, key: String, sigfile: String) {
    if Path::new(&file).exists() {
        if Path::new(&key).exists() {
            let kd = File::open(key).expect("File not found!");
            let mut strdata = String::new();
            kd.read_to_string(&mut strdata).expect("Error reading of file!");
            let data: &[u8] = strdata.as_bytes();
            let pkd = File::open(key).expect("Private key not found!");
            let mut pkdata = String::new();
            pkd.read_to_string(&mut pkdata).expect("Error reading of private key!");
            let pkb: Vec<u8> = pkdata.as_bytes().to_vec();
            let privk = PKey::private_key_from_pem(&pkb);

            let mut signer = Signer::new(MessageDigest::sha512(), &privk).unwrap();
            signer.update(data).unwrap();

            let signature = signer.sign_to_vec().unwrap();
            let sigdump = signature.as_slice();
            let fd = match File::create(sigfile) {
                    Err(why) => panic!("Cant open signature file {}: {}", sigfile, why),
                    Ok(fd) => fd
            };
            fd.write_all(&sigdump);
        } else {
            eprintln!("Keyfile {} is not found!", key);
            panic!();
        }
    } else {
        eprintln!("File {} is not found!", file);
        panic!();
    }
}

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() == 4 {
        sign(args[1].clone(), args[2].clone(), args[3].clone());
    } else {
        println!("Usage: signfile (file) (private.key) (out.sig)");
    }
}

build的时候报错:

 ~/signfile $ cargo build
error[E0308]: mismatched types
   --> src/main.rs:26:61
    |
26  |             let mut signer = Signer::new(MessageDigest::sha512(), &privk).unwrap();
    |                              -----------                          ^^^^^^ expected `&PKeyRef<_>`, found `&Result<PKey<...>, ...>`
    |                              |
    |                              arguments to this function are incorrect
    |
    = note: expected reference `&PKeyRef<_>`
               found reference `&Result<PKey<Private>, ErrorStack>`
note: associated function defined here
   --> /root/.cargo/registry/src/github.com-1ecc6299db9ec823/openssl-0.10.46/src/sign.rs:142:12
    |
142 |     pub fn new<T>(type_: MessageDigest, pkey: &'a PKeyRef<T>) -> Result<Signer<'a>, Erro...
    |            ^^^

For more information about this error, try `rustc --explain E0308`.

Vo1,我对 Rust 仍然知之甚少,v2,在我在 Internet 上找到的所有示例中,密钥都是在一个可执行文件中生成的,并且文件会立即使用它们进行签名。但问题是我从文件中获取了(私钥)密钥,但我不知道如何将Result<PKey<...>>其转换为...PKeyRef<...>

rust
  • 1 1 个回答
  • 19 Views

1 个回答

  • Voted
  1. Best Answer
    Pak Uula
    2023-03-18T17:23:01Z2023-03-18T17:23:01Z

    看 - 你expect到处都写着 -s,如果操作失败就会恐慌,并且在从中提取私钥的行中PEM,既没有expect, 也没有unwrap:let privk = PKey::private_key_from_pem(&pkb);

    把它改成类似的东西

    let privk = PKey::private_key_from_pem(&pkb).expect("Failed to parse private key");
    

    并在通话时,pkey替换而不是pkey.as_ref(),因为您需要类型PKeyRef

    修复这个错误后,rustc 会给你更多关于使用移动值和对非可变值调用非常量方法的通知。您可以像这样修复它们:

    extern crate openssl;
    
    use std::env;
    use std::string::String;
    use std::fs::File;
    use std::path::Path;
    use openssl::pkey::PKey;
    use openssl::sign::Signer;
    use openssl::hash::MessageDigest;
    use std::io::Write;
    use std::io::Read;
    
    fn sign(file: String, key: String, sigfile: String) {
        if Path::new(&file).exists() {
            if Path::new(&key.clone()).exists() {
                let mut kd = File::open(key.clone()).expect("File not found!");
                let mut strdata = String::new();
                kd.read_to_string(&mut strdata).expect("Error reading of file!");
                let data: &[u8] = strdata.as_bytes();
                let mut pkd = File::open(key).expect("Private key not found!");
                let mut pkdata = String::new();
                pkd.read_to_string(&mut pkdata).expect("Error reading of private key!");
                let pkb: Vec<u8> = pkdata.as_bytes().to_vec();
                let privk = PKey::private_key_from_pem(&pkb).expect("Failed to parse PEM");
    
                let mut signer = Signer::new(MessageDigest::sha512(), &privk.as_ref()).unwrap();
                signer.update(data).unwrap();
    
                let signature = signer.sign_to_vec().unwrap();
                let sigdump = signature.as_slice();
                
                let mut fd = match File::create(sigfile) {
                        Err(why) => panic!("Cant open signature file: {}", why),
                        Ok(fd) => fd
                };
                fd.write_all(&sigdump).expect("Failed to write signature");
            } else {
                eprintln!("Keyfile {} is not found!", key);
                panic!();
            }
        } else {
            eprintln!("File {} is not found!", file);
            panic!();
        }
    }
    
    fn main() {
        let args: Vec<String> = env::args().collect();
        if args.len() == 4 {
            sign(args[1].clone(), args[2].clone(), args[3].clone());
        } else {
            println!("Usage: signfile (file) (private.key) (out.sig)");
        }
    }
    

    编译、运行,但openssl无法验证签名。

    • 2

相关问题

  • 在 Rust 中通过 read_line 输入数据

  • 如何取消引用 rust-gdb 中的 Box?

  • 无法提供静态文件

  • Rust 中的西里尔字母问题

  • 如何从 Rust 的文本文件中逐个字符地读取?

  • 为什么 Rust 不能像在 C++ 中那样在 main 之前分配内存?

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5