rust的openssl中有支持RSA加解密的库。参考地址如下:
里面也有简单的示例代码:
rust
use openssl::rsa::{Rsa, Padding};
let rsa = Rsa::generate(2048).unwrap();
let data = b"foobar";
let mut buf = vec![0; rsa.size() as usize];
let encrypted_len = rsa.public_encrypt(data, &mut buf, Padding::PKCS1).unwrap();
上述代码使用公钥加密数据。参考类似的代码,我们需要写一个加解密文件的操作,
加密代码:
rust
let buff_size = pub_key.size() as usize;
let mut buf = vec![0;buff_size];
let mut start:usize = 0;
//if use Padding::PKCS1 =>encrypt length = key length - 11
//if use Padding::OAEP =>encrypt length = key length - 42
let mut encrypt_len = 0;
if self.m_padding == Padding::PKCS1 {
encrypt_len = buff_size - 11;
} else if self.m_padding == Padding::PKCS1_OAEP{
encrypt_len = buff_size - 42
}
let mut end = start + encrypt_len;
if end > data.len() {
end = data.len();
}
loop { //1
let ret = pub_key.public_encrypt(&data[start..end], &mut buf, self.m_padding);//2
match ret {
Ok(size)=> {
result.extend_from_slice(&buf[0..size]);
start += encrypt_len;
end += encrypt_len;
if start >= data.len() {
break;
}
if end > data.len() {
end = data.len();
}
},
Err(_) => {
break;
}
}
}
1.RSA加密也是类似AES这种逐个block加密,所以每个block的长度是多少呢?这个需要根据padding的类型来计算,具体的可以看上面encrypt_len的计算。所以这个循环实际上就是这个block加密,然后把加密的数据存放到一个Vec<u8>里面。
2.调用rsa的接口,貌似他支持公钥加解密,私钥加解密。使用也很方便,但是有一点注意public_encrypt这个函数每次返回的加密长度都是256.(我的key生成的时候是2048=256*4)
解密代码:
rust
let buff_size = pub_key.size() as usize;
let mut buf = vec![0;buff_size];
let mut start:usize = 0;
let mut end:usize = data.len();
//if use Padding::PKCS1 =>encrypt length = key length - 11
//if use Padding::OAEP =>encrypt length = key length - 42
let mut encrypt_len = 0;
if self.m_padding == Padding::PKCS1 {
encrypt_len = buff_size - 11;
} else if self.m_padding == Padding::PKCS1_OAEP{
encrypt_len = buff_size - 42
}
if end > buff_size {
end = buff_size;
}
loop {//1
let ret = pub_key.public_decrypt(&data[start..end], &mut buf, Padding::PKCS1);//2
match ret {
Ok(size)=> {
result.extend_from_slice(&buf[0..size]);
if size < encrypt_len {
break;
}
start += buff_size;
end += buff_size;
if end > data.len() {
end = data.len();
}
},
Err(_) => {
break;
}
}
}
1.解密的原理和加密类似,也是逐个block解密,每个block的长度就是rsa key的长度,这个比加密时候计算方便。哈哈。
2.注意public_decrypt返回的数字是实际解密后的数据长度,例如你传入解密的数据是256字节(正好是rsa key的长度),那你解密后的数据长度(如果padding是PCKS1)就是256-11 = 245.
关于RUST的学习,我把代码上传到了以下github: