当前位置:   article > 正文

rust学习(openssl rsa加解密文件)

rust学习(openssl rsa加解密文件)

rust的openssl中有支持RSA加解密的库。参考地址如下:

openssl::rsa - Rust

里面也有简单的示例代码:

  1. use openssl::rsa::{Rsa, Padding};
  2. let rsa = Rsa::generate(2048).unwrap();
  3. let data = b"foobar";
  4. let mut buf = vec![0; rsa.size() as usize];
  5. let encrypted_len = rsa.public_encrypt(data, &mut buf, Padding::PKCS1).unwrap();

上述代码使用公钥加密数据。参考类似的代码,我们需要写一个加解密文件的操作,

加密代码:

  1. let buff_size = pub_key.size() as usize;
  2. let mut buf = vec![0;buff_size];
  3. let mut start:usize = 0;
  4. //if use Padding::PKCS1 =>encrypt length = key length - 11
  5. //if use Padding::OAEP =>encrypt length = key length - 42
  6. let mut encrypt_len = 0;
  7. if self.m_padding == Padding::PKCS1 {
  8. encrypt_len = buff_size - 11;
  9. } else if self.m_padding == Padding::PKCS1_OAEP{
  10. encrypt_len = buff_size - 42
  11. }
  12. let mut end = start + encrypt_len;
  13. if end > data.len() {
  14. end = data.len();
  15. }
  16. loop { //1
  17. let ret = pub_key.public_encrypt(&data[start..end], &mut buf, self.m_padding);//2
  18. match ret {
  19. Ok(size)=> {
  20. result.extend_from_slice(&buf[0..size]);
  21. start += encrypt_len;
  22. end += encrypt_len;
  23. if start >= data.len() {
  24. break;
  25. }
  26. if end > data.len() {
  27. end = data.len();
  28. }
  29. },
  30. Err(_) => {
  31. break;
  32. }
  33. }
  34. }

1.RSA加密也是类似AES这种逐个block加密,所以每个block的长度是多少呢?这个需要根据padding的类型来计算,具体的可以看上面encrypt_len的计算。所以这个循环实际上就是这个block加密,然后把加密的数据存放到一个Vec<u8>里面。

2.调用rsa的接口,貌似他支持公钥加解密,私钥加解密。使用也很方便,但是有一点注意public_encrypt这个函数每次返回的加密长度都是256.(我的key生成的时候是2048=256*4)

解密代码:

  1. let buff_size = pub_key.size() as usize;
  2. let mut buf = vec![0;buff_size];
  3. let mut start:usize = 0;
  4. let mut end:usize = data.len();
  5. //if use Padding::PKCS1 =>encrypt length = key length - 11
  6. //if use Padding::OAEP =>encrypt length = key length - 42
  7. let mut encrypt_len = 0;
  8. if self.m_padding == Padding::PKCS1 {
  9. encrypt_len = buff_size - 11;
  10. } else if self.m_padding == Padding::PKCS1_OAEP{
  11. encrypt_len = buff_size - 42
  12. }
  13. if end > buff_size {
  14. end = buff_size;
  15. }
  16. loop {//1
  17. let ret = pub_key.public_decrypt(&data[start..end], &mut buf, Padding::PKCS1);//2
  18. match ret {
  19. Ok(size)=> {
  20. result.extend_from_slice(&buf[0..size]);
  21. if size < encrypt_len {
  22. break;
  23. }
  24. start += buff_size;
  25. end += buff_size;
  26. if end > data.len() {
  27. end = data.len();
  28. }
  29. },
  30. Err(_) => {
  31. break;
  32. }
  33. }
  34. }

1.解密的原理和加密类似,也是逐个block解密,每个block的长度就是rsa key的长度,这个比加密时候计算方便。哈哈。

2.注意public_decrypt返回的数字是实际解密后的数据长度,例如你传入解密的数据是256字节(正好是rsa key的长度),那你解密后的数据长度(如果padding是PCKS1)就是256-11 = 245.

关于RUST的学习,我把代码上传到了以下github:

GitHub - wangsun1983/Tarbo

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/581999
推荐阅读
相关标签
  

闽ICP备14008679号