当前位置: 首页 > news >正文

数据加密:RSA 加解密

1、加解密方法

对于RSA加解密来说,在iOS的API中同样也是提供了这两种形式的方法。

SecKeyEncrypt(加密)
SecKeyDecrypt(解密)
复制代码

openssl 同样也提供了一系列的方法:

RSA_public_encrypt
RSA_private_encrypt
RSA_public_decrypt
RSA_private_decrypt
复制代码

相比较而言,openssl 提供的方法更为明确,比如:公钥解密,私钥解密,私钥加密,公钥解密。虽然 iOS 原生给出的只是加密和解密的方法,但是在方法注释中明确说了,加密用的就是公钥,解密用的就是私钥。

其实公钥加密私钥解密也是最常用的方式,私钥加密公钥解密用的并不多,但是私钥加密公钥解密有的时候也是需要的。如果真的需要私钥加密公钥解密,openssl 会更方便一点,但其实 iOS 也可以做私钥加密公钥解密。

这里大致说一下RSA加解密的过程:

1.生成密钥

公钥 (E,N)  
私钥 (E,D,N)
复制代码

2.加解密

密文 = 明文E  % N  
明文 = 密文D  % N

我们通过一个具体的例子来直观体验下,经过计算我们现在得到一对具体的密钥对:

公钥=(E,N) = (5,323)  
私钥=(D,N) = (29,323)  

B = AE  mod N = pow(123, 5) % 323 = 225  
A = BD  mod N = pow(225, 29) % 323 = 123  

如果 A(123) 为明文,那上面的过程就是 公钥加密私钥解密;
如果 B(225) 为明文,那上面的过程就是 私钥加密公钥解密;

换一下顺序可能会更清除一点:

A = BD  mod N = pow(225, 29) % 323 = 123 (私钥加密)   
B = AE  mod N = pow(123, 5) % 323 = 225 (公钥解密)  

这样一来我们就会发现,其实加解密是同一个方法。那为什么会有加密和解密两个方法呢?我的理解是:

加密就是,传入数据直接做计算(就像上面的那样)
解密就是,传入数据直接做计算(还是上面的那样),不过会根据填充模式做数据处理,把填充的随机数剔除掉。

所以从原理上来说私钥加密公钥解密是行的通的,只是需要自己做一些数据上的处理。具体实现可以看Demo。

2、分段加密

RSA算法本身要求加密内容也就是明文长度 m 必须 0<m<n ,也就是说内容这个大整数不能超过 n,否则就出错。那么如果 m=0,RSA加密器会直接返回全0结果。所以在对较长的数据进行加密的时候要把数据分段,每一段的数据长度不能大于模数长度(密钥长度)。

在实际的 RSA 加密中,分段的长度跟填充模式也有一定的关系:

填充方式最大输入长度输出长度填充内容
PKCS1keySize - 11keySize随机数
NONEkeySize - 1keySize00

有的文章说 padding 为 NONE 是的最大输入长度为 keySize,其实这样是有风险的。如果明文长度跟密钥长度一样的话,明文就有可能大于模数,这样在加密的时候就会出错。所以这里建议 padding 为 NONE 是明文的分段长度取 keySize - 1

分段加密之后就要分段解密了,在实际的RSA加密中,加密出来的密文总是等于密钥的长度,所以在分段解密的时候密文的分段大小直接取密钥长度。

3、填充模式

RSA在实际应用为了提高安全性防范各种攻击,在加解密过程中都需要添加一定的随机因素。为了让同一明文每次加密产生的密文都不一样,加密前先填充一部分随机数,这个不止RSA有,DES等对称加密也都有,称为padding。加密标准里有各种类型的padding标准,比如PCKS1。

对于PKCS1,这个填充格式会要求每次加密的数据比密钥长度短至少11个字节(keySize - 11),填充格式如下:

PS 为随机填充数,M为明文

00 02 | PS | 00 | M     (公钥加密)
00 01 | PS | 00 | M     (私钥加密)
复制代码

以 00 开头填充同时也保证了待加密数据不会大于密钥的模数。

还有一个比较常用的就是None(不填充),如果明文比密钥短的话会在明文的前面填充零(0)

0000 | M
复制代码

Demo传送门

相关文章:

  • react 前端项目技术选型、开发工具、周边生态
  • Keras笔记
  • JQ和Js获取span标签的内容
  • yaml 配置文件
  • 前端之JQuery:JQuery属性操作
  • canvas 绘制双线技巧
  • 软件工程期末考试复习
  • Spark任务调度
  • 阿里架构师教你如何设计一个 RPC 系统!
  • JS实现的四叉树算法详解
  • LeetCode算法题-Sum of Two Integers(Java实现)
  • 摩拜创始人胡玮炜也彻底离开了,共享单车行业还有未来吗?
  • 对于Ping的过程,你真的了解吗?
  • 05.java多线程问题
  • java8 -函数式编程之四个基本接口
  • 时间复杂度分析经典问题——最大子序列和
  • [译]CSS 居中(Center)方法大合集
  • 【108天】Java——《Head First Java》笔记(第1-4章)
  • 【140天】尚学堂高淇Java300集视频精华笔记(86-87)
  • 30天自制操作系统-2
  • Angular 响应式表单 基础例子
  • canvas实际项目操作,包含:线条,圆形,扇形,图片绘制,图片圆角遮罩,矩形,弧形文字...
  • JAVA_NIO系列——Channel和Buffer详解
  • Java读取Properties文件的六种方法
  • java概述
  • Java教程_软件开发基础
  • React 快速上手 - 06 容器组件、展示组件、操作组件
  • Spring Boot快速入门(一):Hello Spring Boot
  • webgl (原生)基础入门指南【一】
  • 编写高质量JavaScript代码之并发
  • 基于Android乐音识别(2)
  • 目录与文件属性:编写ls
  • 入门到放弃node系列之Hello Word篇
  • 深度学习中的信息论知识详解
  • 微信开源mars源码分析1—上层samples分析
  • 树莓派用上kodexplorer也能玩成私有网盘
  • ​比特币大跌的 2 个原因
  • (2)关于RabbitMq 的 Topic Exchange 主题交换机
  • (4)(4.6) Triducer
  • (function(){})()的分步解析
  • (初研) Sentence-embedding fine-tune notebook
  • (附源码)springboot 基于HTML5的个人网页的网站设计与实现 毕业设计 031623
  • (一)RocketMQ初步认识
  • (转)ABI是什么
  • (转)h264中avc和flv数据的解析
  • (转)菜鸟学数据库(三)——存储过程
  • .net core IResultFilter 的 OnResultExecuted和OnResultExecuting的区别
  • .NET I/O 学习笔记:对文件和目录进行解压缩操作
  • .Net Winform开发笔记(一)
  • .net 按比例显示图片的缩略图
  • .net2005怎么读string形的xml,不是xml文件。
  • .net安装_还在用第三方安装.NET?Win10自带.NET3.5安装
  • .NET命令行(CLI)常用命令
  • .NET企业级应用架构设计系列之技术选型
  • .Net中的集合