南邮算法分析与设计实验4 密码算法

实验目的

了解现代密码学的基本原理和数论的基础知识,掌握非对称密码体制的著名代表RSA加密算法的工作原理和流程,并设计实现一个简单的密钥系统。

实验内容

了解加/解密的基本原理和工作过程,用公开密钥对明文进行加密,并用私人密钥对密文进行解密,构造一个简单的 RSA 公开密钥系统。

实验原理

1、RSA算法是由麻省理工学院的 Ron Rivest,Adi Shamir 和Len Adleman 于 1977 年研制并于1978 年首次发表的一种算法,是第一个能同时用于加密和数字签名的算法,且易于理解和操作,因此作为一种通用公开密钥加密方式而受到推崇。RSA是一种分组密码,其中明文和密文都是小于某个 n 的从0 到 n-1 的整数,则分组的

二进制值长度必须小于或等于log2n。若以 M 表示明文分组,而C 表示密文分组,则加密和解密的过程如下:

加密:C=M^e mod n

解密:M’=C^d mod n

发送方和接受方都必须知道n 的值。发送方知道 e 的值,而只有接受方知道d 的值。因此这是一种公开密钥为{e,n},且私有密钥为{d,n}的公开密钥加密算法。此时算法要能够满足公开密钥加密的要求,则必须满足以下条件:

(1)        有可能找到 e、d、n的值,使得对所有 M<n 有

M^(ed) modn = M mod n。

(2)对于所有M<n 的值,要计算 M^e和C^d 相对来说是简单的。

(3)在给定e 和 n 时,判断出d 是不可行的。

2、重点考虑第一个条件:

由 Euler 定理的一个推论:给定两个素数p和 q以及两个整数 n 和m,使得 n=pq 而且0<m<n,并且对于任意整数k,下列关系成立:

m^(kΦ(n)+1)=m

k(p-1)(q-1)+1≡m mod n

其中Φ(n)是欧拉函数,也就是不超过n 且与 n 互素的整数个数。对于素数p 和 q,有Φ(pq)=(p-1)(q-1)。

因此得到需要的关系:ed=kΦ(n)+1,

等价于: ed≡1mod Φ(n) => d≡e-1mod Φ(n)

也就是说:d 和e 是以Φ(n)为模的乘法逆元。

根据模运算规则,它的必要条件是:d、e和Φ(n)是互素的,即gcd(Φ(n),d)=1。3、因此给出RSA 方案:

1. 选择两个大素数p,q(私有,选择)

2. 计算乘积n = p q,得到Φ(n)=(p-1)(q-1)(公开,计算出)

3. 选择随机整数e,其中gcd(Φ(n),e)=1;0<e<Φ(n)(公开,选择)

4. 计算d≡e-1mod Φ(n) (私有,计算出)

5. 私有密钥由{d,n}组成,公开密钥由{e,n}组成。

假设用户 A 公布了它的公开密钥,而用户B 希望向 A 发送一个报文M,那么 B 计算出C=M^e mod n 并传输 C。在收到这个密文时,用户A 通过计算 M’=C^d mod n 进行解密。

3、编程一个简单的RSA 加、解密系统。

(1)假设用户A 选择两个素数 p 和q,计算得到 n=pq 和Φ(n)=(p-1)(q-1)。选择一个加密密钥e,它小于Φ(n)且与Φ(n)互素。计算解密密钥d≡ e-1 mod Φ(n)。则用户A 公布公开密钥{e,n},自己拥有私有密钥{d,n}。

(2)用户B 使用用户 A 的公开密钥e 和 n 对报文M 进行加密,得到 C= M^e mod n,并发送给用户A。

(3)用户A 收到加密的报文后,使用自己的私有密钥 d 和n 对加密报文 C 进行解密,恢复得到明文M=C^d mod n。

实验代码:

#include <iostream>
using namespace std;
int MOD;
int extended_euclid(int a, int b, int &x, int &y)
{
    if(b == 0)
    {
        x = 1;
        y = 0;
        return a;
    }
    int gcd = extended_euclid(b, a % b, x, y);
    int t = x % MOD;
    x = y % MOD;
    y = ((t - a / b * x) % MOD + MOD) % MOD;
    return gcd;
}

int main()
{
    int p, q, i, d;
    cout << "输入一个质数p:";
    cin >> p;
    cout << "输入一个质数q:";
    cin >> q;
    int n = p * q;
    cout<<"分组加密时,每个分组的大小不能超过p*q=";
    cout << n << endl;
    //求得φ(n)=(p-1)*(q-1)的值
    MOD = (p - 1) * (q - 1);
    cout << "模φ(n)=(p-1)*(q-1)=";
    cout << MOD << endl << endl;
    //选取与φ(n)互质的公钥e
    int e;
    cout << "输入与φ(n)互质的公钥e:";
    cin >> e;
    //由e和φ(n)生成私钥d
    int x, y;
    extended_euclid(e, MOD, d, y);
    while(d < 0)
        d += MOD;
    cout << "通过调用扩展欧几里德算法,求得密钥d为:" << d << endl;
    //利用生成的公钥{e,n}对明文M进行加密
    int M, C;
    cout << "现在公钥{e,n}、私钥{d,n}均已生成完毕。\n\n请输入需要传输的明文内容进行加密(如9726):";
    cin >> M;
    C = 1;
    for(i = 1; i <= e; i++)
        C = C * M % n;
    cout << "明文M=" << M << "经加密后得到密文C=M^e(mod n):" << C << endl;
    //利用生成的私钥私钥{e,n}对密文C进行解密
    M = 1;
    for(i = 1; i <= d; i++)
        M = M * C % n;
    cout << "密文C=" << C << "经解密后得到明文M=C^d(mod n):" << M << endl;
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-11 15:26:51

南邮算法分析与设计实验4 密码算法的相关文章

南邮算法分析与设计实验2 动态规划法

动态规划法 实验目的: 加深对动态规划法的算法原理及实现过程的理解,学习用动态规划法解决实际应用中的最长公共子序列问题. 实验内容: 用动态规划法实现求两序列的最长公共子序列,其比较结果可用于基因比较.文章比较等多个领域. 实验要求: 掌握动态规划法的思想,及动态规划法在实际中的应用:分析最长公共子序列的问题特征,选择算法策略并设计具体算法,编程实现两输入序列的比较,并输出它们的最长公共子序列. 实验原理及内容(包括操作过程.结果分析等) 1.最长公共子序列(LCS)问题是:给定两个字符序列X=

南邮算法分析与设计实验3 回溯法

回溯法 实验目的: 学习编程实现深度优先搜索状态空间树求解实际问题的方法,着重体会求解第一个可行解和求解所有可行解之间的差别.加深理解回溯法通过搜索状态空间树.同时用约束函数剪去不含答案状态子树的算法思想,会用蒙特卡罗方法估计算法实际生成的状态空间树的结点数. 实验内容: 1.求24点问题 给定四个1-9之间的自然数,其中每个数字只能使用一次,用算术运算符+,-,*,/构造出一个表达式,将这4个正整数连接起来(可以使用括号),使最终的得数为24.要求根据问题的特征设计具体算法并编程实现,输入数据

南邮算法分析与设计实验1 分治策略

分治策略 实验目的: 理解分治法的算法思想,阅读实现书上已有的部分程序代码并完善程序,加深对分治法的算法原理及实现过程的理解. 实验内容: 用分治法实现一组无序序列的两路合并排序和快速排序.要求清楚合并排序及快速排序的基本原理,编程实现分别用这两种方法将输入的一组无序序列排序为有序序列后输出. 代码: #include <iostream> #include <cstdlib> #include <ctime> using namespace std; void Swa

南邮算法分析和实验设计1 分而治之

分而治之 实验目的: 理解分治法的算法思想,阅读实现书上已有的部分程序代码并完好程序,加深对分治法的算法原理及实现过程的理解. 实验内容: 用分治法实现一组无序序列的两路合并排序和高速排序.要求清楚合并排序及高速排序的基本原理,编程实现分别用这两种方法将输入的一组无序序列排序为有序序列后输出. 代码: #include <iostream> #include <cstdlib> #include <ctime> using namespace std; void Swa

南邮JAVA程序设计实验4 线程程序设计(指针式时钟)

南邮JAVA程序设计实验4  线程程序设计(指针式时钟) 实验目的: 本实验旨在通过实验,培养学生将JAVA 线程的相关知识点(包括线程调度,线程同步等)有机结合并加以综合应用,在实验中设计多线程程序的能力. 实验内容: 设计和编写一个编写一个指针式时钟程序,应用线程实现时钟的走动. 实验设计: 主要是控制时针分针秒针的转动度数,这个直接通过坐标的三角函数值求得,线程方面,隔一秒休眠一下,然后通过时分秒的换算关系来改变三个对应指示针在时钟上的位置 实验代码: import java.awt.*;

南邮JAVA程序设计实验1 综合图形界面程序设计

南邮JAVA程序设计实验1  综合图形界面程序设计 实验目的: 学习和理解JAVA SWING中的容器,部件,布局管理器和部件事件处理方法.通过编写和调试程序,掌握JAVA图形界面程序设计的基本方法. 实验内容: 设计和编写一个用于将人民币转换为等值的美元的程序,界面要求可以输入人民币的金额并可以得到转换后的结果.(每100美元等值买入人民币数:619.72) 实验代码: import java.awt.*; import java.awt.event.*; import java.math.*

南邮JAVA程序设计实验3 流处理程序设计

南邮JAVA程序设计实验3  流处理程序设计 实验目的: 要求学生能在学习和理解课堂学习内容中JAVA流编程理论的基础上,学习并逐步掌握JAVA流程序的编写和调试,学习根据处理需求对不同流的正确选择使用和组合使用方法. 实验内容: 设计和编写一个程序从键盘读入一行字符串,将其写入一个文本文件中,再编写另一个程序从文本文件中读入字符串并在命令行窗口显示出来. 实验程序1: 用数据的基本的读入Scanner读入一行,用缓冲流写入文件. import java.io.*; import java.ut

算法分析与设计——贪心法实验报告

   算法导论  课程设计 成 绩 题    目:    贪心法 学院班级:        1613013         学    号:      16130130216       姓    名:        库 妍           主讲教师:        张立勇          日    期:       2019.5.9         一.Knapsack Problem 1.实验题目 下面有5个具有值和权重列表的项目,背包最多可以包含100磅.解决了分数背包和0/1背包问题

算法分析与设计——分治法实验报告

   算法导论  课程设计 成 绩 题    目:  算法导论课程设计实验报告 学院班级:        1613013         学    号:      16130130216       姓    名:        库 妍           主讲教师:        张立勇          日    期:       2019.6.3         录 分治法 一.Implement exercise 2.3-7................................