RSA非对称加密算法原理和代码实现 信息安全 密码学

news/2024/5/19 17:20:43/文章来源:https://blog.csdn.net/weixin_45792450/article/details/130032901

一 欧拉数论定理

1. 欧拉函数

      设n为一正整数,则欧拉函数φ(n)\varphi (n)φ(n)等于0∼n−10\sim n-10n1中与n互素的整数个数
      比如φ(5)=4\varphi (5) = 4φ(5)=4,因为0~5中, 1,2,3,4均与5互素,即最大公约数为1

2. 欧拉定理

      设a,n为两个正整数,且(a,n)=1,则有:aφ(n)≡1mod(n)a^{\varphi (n)} \equiv 1 \, mod (n)aφ(n)1mod(n)

二 RSA数学原理

      给定两个不同的素数p,q,令n=p*q,则φ(n)=(p−1)(q−1)\varphi (n) = (p-1)(q-1)φ(n)=(p1)(q1),对于满足cd≡1mod(φ(n))cd \equiv 1 mod (\varphi (n))cd1mod(φ(n))的两个正整数c,d,显然满足:acd≡amod(n)a^{cd} \equiv a \, mod (n)acdamod(n)

(1) 对于明文M,则有密文C=M^e mod n  (获得密文是明文的e次方再模n)    
(2) 对于密文C,则有明文M=C^d mod n  (获得明文是密文的d次方再模n)

      明文和密文的产生是建立在一对密钥的基础上的,即(e,n)和(d,n) 。其中,(e,n)称为公钥 , (d,n)称为私钥。公钥在网络中公开,谁都可以使用;私钥在本地保存,仅限自己使用。根据数论,寻求两个大素数比较简单,而将它们的乘积进行因式分解却极其困难,因而在大素数条件下根据公钥去计算私钥是比较耗时的过程,由此保证了信息的安全。

三 Python实现RSA

import random'''
计算两个整数的最大公因数,采用欧几里得算法,其原理具体描述为:
假设 a = t*b + r ,那么a与b最大公约数等于b与r最大公约数
gcd(a,b) = gcd(b,r)
'''def gcd(a, b):while b != 0:a, b = b, a % breturn a'''
当满足 ab同余1模m 时,b即为 a模m 下的逆,采用欧几里得算法反推计算
A1 = T1*A2 + A3
A2 = T2*A3 + A4
......
An = Tn*A(n+1) + A(n+2)
结束时,A(n+2) = 1
'''def inverse(e, phi):a, b, t = phi, e, 0x, y = 0, 0x1, y1 = 1, 0x2, y2 = 0, 1while (a % b) != 1:t = a // bx, y = x2, y2x2, y2 = x1 - t * x2, y1 - t * y2x1, y1 = x, ya, b = b, a % bt = a // bx, y = x1 - t * x2, y1 - t * y2return (y + ((abs(y)) // phi + 1) * phi) % phi'''
测试所选整数是不是质数
'''def is_prime(num):if num == 2:return Trueif num < 2 or num % 2 == 0:return Falsefor n in range(3, int(num ** 0.5) + 2, 2):if num % n == 0:return Falsereturn True'''
生成公钥和私钥
'''def generate_key_pair(p, q):if not (is_prime(p) and is_prime(q)):raise ValueError('Both numbers must be prime.')elif p == q:raise ValueError('p and q cannot be equal')if p < 11 or q < 11:raise ValueError('p or q should larger than 10')  # 保证n大于128,容纳ASCII字符n = p * qphi = (p - 1) * (q - 1)e = random.randrange(1, phi)g = gcd(e, phi)while g != 1:e = random.randrange(1, phi)g = gcd(e, phi)d = inverse(e, phi)# Public key is (e, n) and private key is (d, n)return ((e, n), (d, n))def encrypt(pk, plaincode):key, n = pkciphercode = [pow(code, key, n) for code in plaincode]return ciphercodedef decrypt(pk, ciphercode):key, n = pkplaincode = [pow(code, key, n) for code in ciphercode]plaintext = [chr(code) for code in plaincode]return ''.join(plaintext)if __name__ == '__main__':'''Detect if the script is being run directly by the user'''print("===========================================================================================================")print("================================== RSA Encryptor / Decrypter ==============================================")print(" ")p = int(input(" - Enter a prime number (11, 13, 17, 19, 23, etc): "))q = int(input(" - Enter another prime number (Not one you entered above): "))print(" - Generating your public / private key-pairs now . . .")public, private = generate_key_pair(p, q)print(" - Your public key is ", public, " and your private key is ", private)message = input(" - Enter a message to encrypt with your public key: ")plaintext = [char for char in message]plaincode = [ord(char) for char in message]print(" - Your plaintext is: ", plaintext, "and your plaincode is: ", plaincode)print(" - Encrypting message with public key ", public, " . . .")ciphercode = encrypt(public, plaincode)ciphertext = [chr(code) for code in ciphercode]print(" - Your ciphertext is: ", ciphertext, "and your ciphercode is: ", ciphercode)print(" - Decrypting message with private key ", private, " . . .")print(" - Your message is: ", decrypt(private, ciphercode))print(" ")print("============================================ END ==========================================================")print("===========================================================================================================")

四 C语言实现RSA

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <iostream>
#include <wchar.h>
using namespace std;
// 计算最大公因数
int gcd(long int a, long int b){return b==0?a:gcd(b,a%b);
}
// 计算模phi的逆
int inverse(long int e, long int phi){long int a=phi, b=e, t=0;long int x=0, y=1;while(a%b!=1){t = x;x = y;y = t-y*(a/b);t = a;a = b;b = t%a;}return ((x-y*(a/b))%phi+phi)%phi;
}
//检测是不是质数
int is_prime(long int num){if (num==2) return 1;if (num<2||num%2==0) return 0;long int n = 3;while(1){if (n*n>num) return 1;if (num%n==0) return 0;n += 2;}
}
void generate_key_pair(long int p, long int q, long int* r){if (!(is_prime(p)&&is_prime(q))){printf("Both numbers must be prime.");exit(2);}if (p==q||p+q<24){printf("p and q cannot be equal.");exit(2);}long int n = p * q;long int phi = (p - 1) * (q - 1);srand((unsigned)time(NULL));long int e = (rand()+1)%phi;long int g = gcd(e, phi);while (g != 1){e = (e+rand()+1)%phi;g = gcd(e, phi);}long int d = inverse(e, phi);// Public key is (e, n) and private key is (d, n)r[0] = e;r[1] = n;r[2] = d;r[3] = n;
}
// 指数取模运算
long int ModExp(long int base, long int exp, long int mod){long int res = 1;while(exp){if (exp%2==1) res = (res*base) % mod;exp /= 2;base = (base*base) % mod;//底数平方}return res;
}
void encrypt(long int* pk, long int* plaincode, long int* ciphercode, int length){int key=pk[0], n=pk[1];for (int i=0;i<length;i++) ciphercode[i] = ModExp(plaincode[i],key,n);
}
wstring decrypt(long int* pk, long int* ciphercode, int length){int key=pk[0], n=pk[1];wstring result;long int* plaincode = (long int*)malloc(length*sizeof(long int));for (int i=0;i<length;i++) plaincode[i] = ModExp(ciphercode[i],key,n);for (int i=0;i<length;i++) result = result + wchar_t(plaincode[i]);return result;
}
int main(){printf("===========================================================================================================\n");printf("================================== RSA Encryptor / Decrypter ==============================================\n");long int p,q;printf(" - Enter a prime number (11, 13, 17, 19, 23, etc): ");cin >> p;printf(" - Enter another prime number (Not one you entered above): ");cin >> q;long int* key_pairs = (long int*)malloc(4*sizeof(long int));printf(" - Generating your public / private key-pairs now . . .\n");generate_key_pair(p,q,key_pairs);long int* key_public = (long int*)malloc(2*sizeof(long int));long int* key_private = (long int*)malloc(2*sizeof(long int));key_public[0]=key_pairs[0];key_public[1]=key_pairs[1];key_private[0]=key_pairs[2];key_private[1]=key_pairs[3];printf(" - Your public key is (%ld,%ld) and your private key is (%ld,%ld)\n",key_public[0],key_public[1],key_private[0],key_private[1]);printf(" - Enter a message to encrypt with your public key: ");wstring message;wcin >> message;int length = message.size();long int* plaincode = (long int*)malloc(length*sizeof(long int));long int* ciphercode = (long int*)malloc(length*sizeof(long int));for (int i=0;i<length;i++) plaincode[i] = message[i];cout << " - Your plaintext is: [";for (int i=0;i<length;i++) wcout << " " << message[i] << " ";cout << "]    and your plaincode is: [";for (int i=0;i<length;i++) cout << " " << plaincode[i] << " ";cout << " ]" << endl;printf(" - Encrypting message with public key (%ld, %ld) . . .\n", key_public[0], key_public[1]);encrypt(key_public,plaincode,ciphercode,length);cout << " - Your ciphertext is: [";for (int i=0;i<length;i++) wcout << " " << wchar_t(ciphercode[i]) << " ";cout << "]    and your ciphercode is: [";for (int i=0;i<length;i++) cout << " " << ciphercode[i] << " ";cout << " ]" << endl;printf(" - Decrypting message with private key (%ld, %ld) . . .\n", key_private[0], key_private[1]);wstring ws = decrypt(key_private, ciphercode,length);wcout << " - Your message is: " << ws << endl;printf("============================================ END ==========================================================\n");printf("===========================================================================================================\n");return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_283753.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

采集工具助力市场营销,让您的营销更加高效

随着市场竞争的日益激烈&#xff0c;企业的营销策略也在不断升级。而在这个信息爆炸的时代&#xff0c;采集数据成为了市场营销中不可或缺的一环。为了更好地服务客户&#xff0c;我们公司开发了一款高效、快捷的采集工具&#xff0c;为您的营销活动提供有力支持。 Msray-plus&…

计算机网络习题 | 第一章:计算机网络概述

文章目录概述1、以下关于OSI环境中数据传输的过程的描述中&#xff0c;错误的是&#xff08; &#xff09;2、以下关于广域网 WAN 特点的描述中 &#xff0c;错误的是&#xff08; &#xff09;3、以下关于计算机网络定义的描述中&#xff0c;错误的是&#xff08; &#xff09…

【分布式 论文】之 1. MapReduce——Simplified Data Processing on Large Clusters

文章目录1. 需求 / 现存问题2. 总述3. 实现3.1 概述1. 需求 / 现存问题 输入数据通常很大&#xff0c;为了在合理的时间内完成计算&#xff0c;必须将计算分布到数百或数千台机器上。 如何并行化计算、分发数据和处理故障等问题使得原本简单的计算变得晦涩难懂&#xff0c;需…

chatGPA的主要功能-chatGPT深度分析

ChatGPT功能介绍 ChatGPT是基于深度学习技术的自然语言处理算法&#xff0c;其主要用途是生成自然语言文本&#xff0c;能够应用于多个自然语言处理任务。以下是其主要功能介绍&#xff1a; 文本生成&#xff1a;ChatGPT能够生成高质量的自然语言文本&#xff0c;可以应用于大…

Mybatis-plus学习2

一、Mybatis-plus分页操作 1.配置拦截器即可 //分页插件Beanpublic PaginationInterceptor paginationInterceptor(){return new PaginationInterceptor();} 2.直接使用Page对象 //测试分页查询Testpublic void testPage(){//参数一&#xff1a;当前页//参数二&#xff1a;页面…

关键词采集软件在SEO优化中的应用与效果

搜索引擎的优化被广泛认为是提高网站排名和在线可见性的重要方法之一。SEO人员需要进行大量的工作以确保网站的内容和标签可以被搜索引擎正确地解析和索引。在这项任务中&#xff0c;使用搜索引擎关键词采集软件可以帮助SEO人员完成许多繁琐的任务并简化他们的工作流程。在本文…

【C语言】数组指针-c语言的任督二脉

视频链接:bilibili 关于指针需要注意的地方 只有以下两种情况数组名表示的是整个数组 1.sizeof(数组名) 2.&数组名 除此之外数组名表示的都是首元素地址 一、字符指针 是一个指向字符的指针 int main() {char ch w;char* p &ch;//char* ch2 "abcdef"…

【TreeSet】| 深度剥析Java SE 源码合集Ⅳ

目录一. &#x1f981; 前言二. &#x1f981; 剥析流程2.1 类图2.2 属性2.3 构造方法2.4 添加单个元素2.5 移除单个元素2.6 查找单个元素2.7 查找接近的元素2.8 获得首尾的元素2.9 清空2.10 克隆2.11 序列化2.12 反序列化2.13 获得迭代器2.14 转换成 Set/Collection2.15 查找范…

Python 进阶指南(编程轻松进阶):二、环境配置和命令行

原文&#xff1a;http://inventwithpython.com/beyond/chapter2.html 环境配置是配置你的计算机环境&#xff0c;以便你写代码的过程。这包括安装任何必要的工具&#xff0c;配置它们&#xff0c;以及处理安装过程中的任何问题。没有一键配置这种傻瓜式操作过程&#xff0c;因为…

分享一个智能的问答工具,刷题和学习的好帮手

使用了这个问答工具后&#xff0c;感觉前后端都要被替代了&#xff0c;太强了。 由于本人之前很想体验&#xff0c;但是一直难搞&#xff0c;最近发现了一个免梯子的&#xff0c;重要事情说一遍&#xff0c;免梯子&#xff01;是我最近发现的最好用&#xff0c;最快的&#xff…

OpenCV实战——多尺度FAST特征检测

OpenCV实战——多尺度FAST特征检测0. 前言1. BRISK 特征检测器1.1 BRISK 检测关键点1.2 多尺度关键点快速检测2. ORB 特征检测算法3. 完整代码相关链接0. 前言 FAST 是用于快速检测图像中关键点的方法&#xff0c;而 SURF 和 SIFT 算法的设计重点是尺度不变性。为了同时实现快…

【软件设计师10】软件工程

软件工程 1. 瀑布模型SDLC - 结构化 优点&#xff1a;结构化方法模型&#xff0c;每个阶段分工明确&#xff1b;出现问题可以向上层回溯 缺点&#xff1a;需求阶段难以把控&#xff0c;在项目初期&#xff0c;软件的需求几乎是不明确的&#xff0c;等开发完用户往往再提出问…

微信小程序 | 网易云+ChatGPT实现一个智能音乐推荐小程序

文章目录* 效果预览** 分析用户的输入产生推荐** 分析用户的选择标签进行推荐一、需求背景二、项目原理及架构2.1 实现原理&#xff08;1&#xff09; 基于用户的喜欢歌手推荐&#xff08;2&#xff09;基于用户的兴趣标签推荐&#xff08;3&#xff09;改进上一步推荐的结果2.…

IM即时通讯-N-如何保证消息的可靠性展示

结论先行 客户端如何在推拉结合的模式下保证消息的可靠性展示&#xff1f; 原则&#xff1a; server拉取的消息一定是连续的原则&#xff1a; 端侧记录的消息的连续段有两个作用&#xff1a; 1. 记录消息的连续性&#xff0c; 即起始中间没有断层&#xff0c; 2. 消息连续&am…

【数据结构】树与二叉树的基本概念及性质

目录 一、树的基本概念 1️⃣树的定义 2️⃣基本术语 3️⃣树的性质 二、二叉树的概念 1️⃣二叉树的定义 2️⃣特殊二叉树 3️⃣二叉树的性质 参考资料 一、树的基本概念 1️⃣树的定义 数据结构中的树是什么❓ 树是 个结点的有限集。有且仅有一个特定的称为根(上图A结点…

零基础教学必会篇(详解字符函数和字符串函数)(完结版)

各位csdn的友友们好&#xff0c;上次阿博给大家讲了一些简单的字符串函数的功能和模拟实现&#xff0c;今天就和阿博一起再上一个台阶继续拿捏它们&#x1f60a;&#x1f60a;&#x1f60a; 文章目录1.strstr的功能介绍2.strstr函数的模拟实现3.strtok的功能介绍4.strerror和pe…

零基础学习Java 06

目录 String String构造方法 字符串查找 字符串截取 字符串替换 字符串拆分 字符串修改 String String类在java.lang包下&#xff0c;所以使用的时候不需要导包。 String构造方法 字符串查找 char charAt(int index)&#xff0c;输入位置index&#xff0c;找单个字符 …

MAE论文笔记+Pytroch实现

Masked Autoencoders Are Scalable Vision Learners&#xff0c; 2021 近期在梳理Transformer在CV领域的相关论文&#xff0c;落脚点在于如何去使用Pytroch实现如ViT和MAE等。通过阅读源码&#xff0c;发现不少论文的源码都直接调用timm来实现ViT。故在此需要简单介绍一下timm…

Linux 中的 /dev/random 和 /dev/urandom 是什么?

在Linux系统中&#xff0c;/dev/random和/dev/urandom是两个特殊的设备文件&#xff0c;用于生成随机数。在本文中&#xff0c;我们将深入探讨这两个设备文件的区别&#xff0c;以及它们在Linux系统中的作用。 /dev/random /dev/random是一个随机数生成器设备文件&#xff0c;…

windows10下编译zlib库

系列文章目录 文章目录系列文章目录前言一、问题原因二、准备具体操作编译zlib工程前言 我使用CMake编译zlib源码&#xff0c;出现警告&#xff1a;CMake Deprecation Warning at CMakeLists.txt:1 (cmake_minimum_required): Compatibility with CMake < 2.8.12 will be r…