前提
-
了解gpg是什么?详情点击参考链接:http://www.ruanyifeng.com/blog/2013/07/gpg.html
-
什么是管道?详情点击参考链接:https://blog.csdn.net/h002399/article/details/48657143
pgp常见指令
pgp -h
下图是常见指令,我们重点看下加密和解密指令
.png
- 加密指令
gpg --recipient 54A907763278F930FE4A98A0D9F5 --output key.pgp --encrypt key.json
recipient参数指定接收者的公钥,output参数指定加密后的文件名,encrypt参数指定源文件
- 解密指令
gpg -o test_pipeline -d key.pgp
-d 参数指定需要解密的文件,-o 参数指定解密后生成的文件。这里-o可以指定到文件,也可以指定到管道中,这里的test_pipeline就是自定义的管道。
思路
最近写Rust,用pgp解密文件。要让解密内容输出到自定义管道中,这个管道由接受者创建,接受者销毁。自己先是自己用c写了以上解密过程,经他人指导后,Rust中的libc已经帮助我们封装常用的调用C的方法,自己之前写的C的代码是多余,好了,下面我们看下怎么在Rust中调用C方法。
1.生成gpg加密文件
- 配置好gpg环境 详细点击
- 用公钥生成加密文件
2.Rust解密加密文件
- 程序A创建管道 test_pipeline
- 程序A打开管道 ,等待接收
- 程序B解密文件输出到 test_pipeline
- 程序A读取到管道内容后,删除该管道
分析
假设1已经生成完成为 key.gpg 文件
- 引入 libc dependencies(Cargo.toml)
[dependencies]
libc = "0.2.39"
...
- extern libc
extern crate libc;
use libc::{c_int, c_char, size_t};
use libc::c_void;
use std::ffi::CString;
use libc::mode_t;
use libc::ssize_t;
- 引入libc 函数
//创建管道
extern "C" {
fn mkfifo(path: *const c_char, mode: mode_t) -> c_int;
}
//打开管道
extern "C" {
fn open(path: *const c_char, oflag: c_int) -> c_int;
}
//读取管道
extern "C" {
fn read(fd: c_int, buf: *mut c_void, count: size_t) -> ssize_t;
}
//删除管道
extern "C" {
fn unlink(c: *const c_char) -> c_int;
}
- 调用
let c_str_2 = CString::new(b"test_pipeline" as &[u8]).unwrap();
let c_ptr: *const c_char = c_str_2.as_ptr();
unsafe {
let flag = mkfifo(c_ptr, 0777);//创建管道
let fd = open(c_ptr, 0);//打开管道
let buf = &mut [0; BUFFER_SIZE];
let r_bytes = unsafe { read(fd, buf.as_mut_ptr() as *mut c_void, BUFFER_SIZE) };//读取管道
let result = std::string::String::from_utf8(buf.to_vec()).unwrap();
println!("{}", result);
unlink(c_ptr);//移除管道
}
- exec pub.sh 文件
#!/usr/bin/env bash
cargo run &
sleep 2
sudo gpg -o test_pipeline -d key.pgp
网友评论