網站首頁 編程語言 正文
一、什么是RSA算法
在計算機中常用的加密算法分為兩類:對稱加密算法和非對稱加密算法。
1.對稱加密
在對稱加密技術中,對信息的加密和解密都使用了相同的密鑰Key,也就是說使用同一個密鑰Key對數據進行加密和解密。這種加密方法可簡化加解密的處理過程,信息交換雙方都不必彼此研究和交換專用的加解米算法。如果在交換階段,密鑰Key沒有泄露,那么加密數據的機密性和報文的完整性就可以得到保證。
2.非對稱加密
在非對稱加密中,不再只有一個密鑰Key了。在非對稱加密算法中,密鑰被分解為一對,一個稱為公開密鑰,另一個稱為私有密鑰。對于公鑰,可以通過非保密方式向他人公開,而私鑰則由解密方保密,不對別人公開。
3.非對稱加密的應用
由于非對稱加密方式可以使通信雙方無需事先交換密鑰就可以建立安全通信,因此被廣泛應用于身份認證、數字簽名、等信息交換領域。其中最具有代表性的非對稱加密方式就是RSA公鑰密碼體制。
二、RSA算法的基礎操作步驟
1.生成公鑰和私鑰
生成公鑰PK和私鑰SK的步驟如下:
(1)隨意選擇兩個大的素數P、Q,P不等于Q。
此處在算法實現中需要快速的判斷P、Q是否為素數,代碼如下:
ll primeNum(ll num) //判斷素數
{
if (num == 1 || num == 0)
{
return 0;
}
for (int i = 2; i * i <= num; i++)
{
if (num % i == 0)
{
// 不是素數返回0
return 0;
}
}
return 1; //是素數返回1
}
(2)將P、Q兩個素數相乘得到一個N,即N=PQ
(3)將P、Q分別減一,再相乘,得到一個數T,即T=(Q-1)*(P-1)
(4)選擇一個整數E,作為一個密鑰,使E與T互質(即E與T的最大公約數為1),且E必須小于T
此處在算法實現中需要對E與T進行互質的判斷(最大公約數為1)
//判斷兩個數是否互素
ll coprime(ll a, ll b) //判斷互質
{
ll t;
if (a < b)
{
t = a;
a = b;
b = t;
}
while (a % b)
{
t = b;
b = a % b;
a = t;
}
//返回值為1,則a,b互素
return b;
}
(5)根據公式DE mod T = 1 ,計算出D的值,作為另一個密鑰。
此時根據算法,逆向求D
d = 1;
//求e的乘法逆
while (((e * d) % t) != 1)
d++;
(6)通過以上的步驟就可以求出N,E,D這三個數據,其中(N,E)作為公鑰,(N,D)作為私鑰。
(7)生成公鑰和私鑰后,就可以對外發布了,其中RSA算法的詳細的流程圖如下:
2.用公鑰加密信息?
發送信息的一方收到公鑰PK后,就可以通過公鑰PK對數據進行加密,加密的操作步驟如下圖所示,其中明文為:M,密文為:C
明文:M
加密:
密文 :C
其中加密的算法,先進行密文的取余運算在加密,代碼如下:
//計算密文
ll candp(ll b, ll p, ll k) //b--明文或密文 p--指數(e/d) k--模數
{
if (p == 1)
{
return b % k;
}
if (p == 2)
{
return b * b % k;
}
if (p % 2 == 0)
{
ll sum = candp(b, p / 2, k);
return sum * sum % k;
}
if (p % 2 == 1)
{
ll sun = candp(b, p / 2, k);
return sun * sun * b % k;
}
}
在進行加密運算
ll encryption()
{
ll n, e, x, y;
cout << "請輸入公鑰(e,n)" << endl;
cin >> e >> n;
cout << "請輸入明文: (明文需小于" << n << ")" << endl; //計算密文
cin >> x;
y = candp(x, e, n);
cout << "密文為:" << y << endl;
return 0;
}
3.用私鑰解密信息
接收方持有私鑰(N,D)在接受到密文C后,既可以通過私鑰解密,得到明文M,解密過程如下:
密文:C
解密:
明文:M
其中解密算法,先產生密鑰Key算法:
ll key()
{
ll p, q, t, n, e, d;
cout << "請輸入兩個素數 p,q: " << endl; //輸入兩個素數q,p
cin >> p >> q;
if (primeNum(p)==0||primeNum(q)==0)
{
cout << "輸入的p或q不是素數" << endl;
return 0;
}
n = p * q;
//t為n的歐拉函數
t = (p - 1) * (q - 1);
cout << "請輸入密鑰e: " << endl;
cin >> e;
d = 1;
//求e的乘法逆
while (((e * d) % t) != 1)
d++;
cout << "n = p * q = " << n << endl;
cout << "t = (p - 1) * (q - 1) = " << t << endl;
cout << ("公鑰(e,n)為:(") << e << "," << n << ")" << endl;
cout << ("私鑰(d,n)為:(") << d << "," << n << ")" << endl;
return 0;
}
?在進行解密:
ll decode()
{
ll n, d, x, y;
cout << "請輸入私鑰(d,n)" << endl;
cin >> d >> n;
cout << "請輸入密文: "; //計算密文
cin >> y;
x = candp(y, d, n);
cout << "明文為:" << x << endl;
return 0;
}
三、AC代碼
新建一個頭文件RSA.h
#pragma once
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
// 判斷素數
ll primeNum(ll num);
// 判斷互質
ll coprime(ll a, ll b);
// 計算密文
ll candp(ll b, ll p, ll k);
// 生成密鑰
ll key();
//加密
ll encryption();
//解密
ll decode();
// 菜單
void menu();
將函數寫在RSA.cpp中,用于主函數RSA()的調用代碼如下:
#define _CRT_SECURE_NO_WARNINGS 1
#include "RSA.h"
void menu()
{
printf("------------------------------------------\n");
printf("***** 請選擇所需功能 *****\n");
printf("***** 1.生成鑰匙 *****\n");
printf("***** 2.加密 *****\n");
printf("***** 3.解密 *****\n");
printf("***** 4.退出 *****\n");
printf("------------------------------------------\n");
}
ll primeNum(ll num) //判斷素數
{
if (num == 1 || num == 0)
{
return 0;
}
for (int i = 2; i * i <= num; i++)
{
if (num % i == 0)
{
// 不是素數返回0
return 0;
}
}
return 1; //是素數返回1
}
//判斷兩個數是否互素
ll coprime(ll a, ll b) //判斷互質
{
ll t;
if (a < b)
{
t = a;
a = b;
b = t;
}
while (a % b)
{
t = b;
b = a % b;
a = t;
}
//返回值為1,則a,b互素
return b;
}
//計算密文
ll candp(ll b, ll p, ll k) //b--明文或密文 p--指數(e/d) k--模數
{
if (p == 1)
{
return b % k;
}
if (p == 2)
{
return b * b % k;
}
if (p % 2 == 0)
{
ll sum = candp(b, p / 2, k);
return sum * sum % k;
}
if (p % 2 == 1)
{
ll sun = candp(b, p / 2, k);
return sun * sun * b % k;
}
}
//生成密鑰
ll key()
{
ll p, q, t, n, e, d;
cout << "請輸入兩個素數 p,q: " << endl; //輸入兩個素數q,p
cin >> p >> q;
if (primeNum(p)==0||primeNum(q)==0)
{
cout << "輸入的p或q不是素數" << endl;
return 0;
}
n = p * q;
//t為n的歐拉函數
t = (p - 1) * (q - 1);
cout << "請輸入密鑰e: " << endl;
cin >> e;
d = 1;
//求e的乘法逆
while (((e * d) % t) != 1)
d++;
cout << "n = p * q = " << n << endl;
cout << "t = (p - 1) * (q - 1) = " << t << endl;
cout << ("公鑰(e,n)為:(") << e << "," << n << ")" << endl;
cout << ("私鑰(d,n)為:(") << d << "," << n << ")" << endl;
return 0;
}
//加密
ll encryption()
{
ll n, e, x, y;
cout << "請輸入公鑰(e,n)" << endl;
cin >> e >> n;
cout << "請輸入明文: (明文需小于" << n << ")" << endl; //計算密文
cin >> x;
y = candp(x, e, n);
cout << "密文為:" << y << endl;
return 0;
}
//解密
ll decode()
{
ll n, d, x, y;
cout << "請輸入私鑰(d,n)" << endl;
cin >> d >> n;
cout << "請輸入密文: "; //計算密文
cin >> y;
x = candp(y, d, n);
cout << "明文為:" << x << endl;
return 0;
}
在寫出主函數test.c,對上面的函數進行調用即可:
#include "RSA.h"
void RSA()
{
while (1)
{
menu();
ll i = 0;
cin >> i;
switch (i)
{
case 1:
key();
break;
case 2:
encryption();
break;
case 3:
decode();
break;
case 4:
exit(0);
default:
cout << "輸入錯誤,請重新輸入" << endl;
}
}
}
void menu1()
{
printf("******************************************\n");
printf("******************************************\n");
printf("***** 歡迎來到RSA加密測試系統 ******\n");
printf("******************************************\n");
printf("******************************************\n");
}
int main()
{
menu1();
RSA();
return 0;
}
四、RSA算法的測試
原文鏈接:https://blog.csdn.net/weixin_45031801/article/details/126728082
相關推薦
- 2023-11-21 linux sudo:/etc/sudoers 中第 11 行附近有解析錯誤 sudo:no val
- 2022-09-09 python實現0到1之間的隨機數方式_python
- 2023-11-12 python 列表、字典、元組與集合的特點以及對比
- 2023-11-16 nvidia jetson設備(Jetson Nano, TX1/TX2,Xavier NX/AGX
- 2022-05-08 ASP.NET中Web?API的參數綁定_實用技巧
- 2022-04-05 antd form操作表單元素以及獲取值方法,antd form獲取某個值
- 2022-03-27 C++如何用數組模擬鏈表_C 語言
- 2022-05-15 Web?API身份認證解決方案之Basic基礎認證_實用技巧
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支