赞
踩
rust的openssl中有支持RSA加解密的库。参考地址如下:
里面也有简单的示例代码:
- 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();
上述代码使用公钥加密数据。参考类似的代码,我们需要写一个加解密文件的操作,
加密代码:
- 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)
解密代码:
- 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:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。