IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> RSA非对称加密 -> 正文阅读

[网络协议]RSA非对称加密

一、背景

要对接实时翻译的平台,而对方提供的加密方式就是RSA(非对称加密),以往都是php对接,所以也没有深度研究过该加密方式,趁此次机会,学习一下

二、概述

非对称加密就是加密和解密使用的不是相同的密钥:只有同一个公钥-私钥对才能正常加解密。

比如,如果A要加密一个文件发送给B,他应该先向B索要公钥,然后用B给他的公钥加密,把加密文件发送给B,此文件只能由B的私钥解开。因为B的私钥在他自己手机,所以,除了B,没有任何人能解开此加密文件。

非对称加密的典型算法就是RSA算法,它是由Ron Rivest,Adi Shamir,Leonard Adleman这三个哥们一起发明的,所以用他们仨的姓的首字母缩写表示。

优点: 非对称加密相比对称加密的显著优点在于,对称加密需要协商密钥,而非对称加密可以安全地公开各自的公钥,在N个人之间通信的时候,使用废对称加密只需要N各密钥对,每个人只管理自己的密钥对。而使用对称加密需要N*(N-1)/2个密钥,因此每个人需要管理N-1个密钥,密钥管理难度大,且非常容易泄露。

缺点: 非对称加密的缺点就是运算速度非常慢,比对称加密要慢得多。

所以在实际应用中,两者总是一起使用。假设A要给B传输加密文件,他俩首先交换了各自的公钥,然后:

  • A生成一个随机的AES口令,然后用B的公钥通过RSA加密这个口令, 并发给B;
  • B用自己的RSA私钥解密得到AES口令;
  • 双方使用这个共享的AES口令用AES加密通信。

可见非对称加密实际上应用在第一步,即加密‘AES口令’,这也是浏览器中常用的https协议的做法,即浏览器和服务器先通过RSA交换AES口令,接下来双方通信实际上采用的是速度较快的AES对称加密,而非缓慢的RSA非对称加密。

知识点: RSA算法,它的密钥有256/512/1024/2048/4096等不同的长度。长度越长,密码强度越大,当然计算速度也越慢。使用512bit的RSA加密时,明文长度不能超过53字节,使用1024bit的RSA加密时,明文长度不能超过117字节,这也是为什么使用RSA的时候,总是配合AES一起使用,即用AES加密任意长度的明文,用RSA加密AES口令。只使用非对称加密算法不能防止中间人攻击。

三、RSA PKCS公钥加密标准

RSA PCKS(Public-Key Cryptography Standards Series 公钥加密标准系列),为了定义 RSA 加密的标准系列,IETF 组织总共定义了 15 个子系列标准,分别用在定义标准格式、如何封装、公钥加密封装标准、私钥加密封装标准、网络传输序列化标准等等… 具体可以参考 wikipedia PCKS 的解释: https://en.wikipedia.org/wiki/PKCS
PKCS #1 RSA Cryptography Standard: 定义了公钥加密技术(RSA)相关的数学属性以及相关的公钥和密钥的格式标准(通过 ASN.1 的格式标准来定义并明文展示),以及为 RSA 进行加密、解密,生成和验证签名等操作定义了基本的算法和编码/补零(padding)的方案;PCKS #1 定义的都是明文的格式;

除此以外,还有

四、密钥格式

  • PKCS #1: 该标准是专门为RSA密钥进行定义的,其对应的PEM文件格式如下:

公钥PEM格式:

-----BEGIN RSA PUBLIC KEY-----
BASE64 ENCODED DATA
-----END RSA PUBLIC KEY-----

私钥PEM文件格式:

-----BEGIN RSA PRIVATE KEY-----
BASE64 ENCODED DATA
-----END RSA PRIVATE KEY-----

  • PKCS #8: 该标准定义了一个密钥格式的通用方案,它不仅仅为 RSA 所使用,同样也可以被其它密钥所使用;其对应的PEM文件格式如下:

公钥PEM格式:

-----BEGIN PUBLIC KEY-----
BASE64 ENCODED DATA
-----END PUBLIC KEY-----

私钥PEM文件格式:

-----BEGIN PRIVATE KEY-----
BASE64 ENCODED DATA
-----END PRIVATE KEY-----

知识点: PEM和DER都是指文件的格式;其中DER是密钥的二进制表述格式,PEM是对DER编码转码为Base64字符的格式,通过解码还是能还原为DER格式的。

五、填充模式

跟DES、AES一样,RSA也是一个块加密算法,即总是在一个固定长度的块上进行操作,但是跟AES不同的是,block length跟key length以及所使用的填充模式有关。

  • RSA_PKCS1_PADDING
    最常用的填充模式,要求:
    输入必须比RSA钥 模长(modulus)短至少11ge字节,也就说输入长度要小于等于 RSA _size - 11 ;如果输入的明文过长,必须切割,然后填充;
    输出 和modulus以一样长
    根据这个要求,也就解释了在概述中密钥长度不同,明文长度就受限。
    block length = 512/8 - 11 = 53字节
    block length = 1024/8 -11 = 117字节
    加密的时候会在你的明文中随机填充一些数据,所以会导致对同样的明文每次加密后的结果都不一样。
    对加密后的密文,服务器使用相同的填充方式都能解密。解密后的明文也就是之前加密的明文。

  • RSA_PKCS1_OAEP_PADDING
    输入 比 RSA modulus 短至少41个字节
    输出 和modulus一样长

  • OPENSSL_NO_PADDING
    输入可以和RSA modulus一样长,如果输入的明文过长,必须切割, 然后填充
    输出和modulus一样长
    如果你的明文不够128字节,加密的时候会在你的明文前面填充零。
    解密后的明文也会包括前面填充的零,这是服务器需要注意把解密后的字段前向填充的零去掉,才是真正之前加密的明文。

六、实战代码示例

<?php

namespace App\Services;
/**
 * 填充方式为RSA_PKCS1_PADDING,
 * 密钥格式为PKCS1-V1_5
 * */
class AtmanService
{

    const API_TRANSFER_PATH = '/api/rsa/sso';
    /**
     * 构造函数
     */
    public function __construct() {
    }

    /**
    获取公共key字符串  重新格式化 为保证任何key都可以识别
     */

    public static function get_public_key(){
        $public_key = file_get_contents('public.txt');
        $search = [
            "-----BEGIN PUBLIC KEY-----",
            "-----END PUBLIC KEY-----",
            "\n",
            "\r",
            "\r\n"
        ];
        $public_key=str_replace($search,"",$public_key);
        return openssl_pkey_get_public($search[0] . PHP_EOL . wordwrap($public_key, 64, "\n", true) . PHP_EOL . $search[1]);
    }

    /**
    获取私有key字符串 重新格式化  为保证任何key都可以识别
     */
    public static function get_private_key()
    {
        $private_key= file_get_contents('private.txt');
        $search = [
            "-----BEGIN RSA PRIVATE KEY-----",
            "-----END RSA PRIVATE KEY-----",
            "\n",
            "\r",
            "\r\n"
        ];

        $private_key = str_replace($search, "", $private_key);
        return openssl_pkey_get_private($search[0] . PHP_EOL . wordwrap($private_key, 64, "\n", true) . PHP_EOL . $search[1]);

    }

    /**
     * 用公钥加密
     */
    public static function public_encrypt($input) {
        if (!is_string($input)) {
            return null;
        }

        openssl_public_encrypt($input,$output,self::get_public_key(),OPENSSL_PKCS1_PADDING);
        return base64_encode($output);
    }


    /**
     * 解密 公钥加密后的密文
     */
    public static function private_decrypt($input)
    {
        if (!is_string($input)) {
            return null;
        }

        openssl_private_decrypt(base64_decode($input), $output, self::get_private_key(), OPENSSL_PKCS1_PADDING);
        return $output;

    }

}

前人栽树,后人乘凉
栽树人1

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-04-01 00:30:35  更:2022-04-01 00:30:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 5:27:43-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码