
(1)通过实践使信息安全专业学生加深对密码学基本原理和加解密理论知识的理解。
(2)培养学生在计算机上实现不同类型加密、解密操作运算功能的能力。利用实现的典型加解密方法对输入明文或文件实施加密,并对密文或文件进行解密。能够实现基本的密钥分配方法。
(3)培养学生具备简单网络程序开发能力,能够在两个联网终端间进行消息加解密操作。
(4)通过参与信息加解密实践,提高学生的分析设计能力、开发过程的团队合作能力、组织管理能力和语言表达能力。
二、实践环境
操作系统:win7 x
开发工具:VS2013
上机地点:信息楼机房
三、项目组分工
在组内,我负责RSA加解密部分的程序编辑和调试
四、系统设计
功能设计:
单机:用户输入明文和两个素数用作密钥,程序输出密文;输入密文和两个密钥,程序输出明文
双机:服务器端输入MAC地址后开始运行,用户向服务器端发送明文和两个作为密钥的素数,服务器端向客户端传送密文;用户向服务器发送密文和两个密钥,服务器端向客户端输出明文
算法设计:读取用户输入的两个密钥p和q,计算(p-1)*(q-1)的值,记为t,再任取一个与t互素的数,记为n,计算nx=1(modt)中x的值,a^n(modpq)为加密,得到密文b;b^x(mod253)为解密,得到明文a。
界面交互设计:
使用组内统一的加解密界面模板,具体界面设计见程序运行截图
五、系统实现
程序及界面运行截图:
双机加解密:
单机加解密:
程序代码及注释:
头文件:
#pragma once
class RSA
{
public:
RSA();
~RSA();
static CString Encrpt(CString plaintext, int key);
static CString Decrypt(CString ciphertext, int key);
CString encrpt(CString plaintext, int key);
CString decrypt(CString ciphertext, int key);
int prime(int m);
int (int x, int y);
int ExtendedEuclidean(int a, int b, int *r);
int power(int a);
int mod(int f, int g, int h);
};
主程序:
#include "stdafx.h"
#include "RSA.h"
RSA::RSA()
{
}
RSA::~RSA()
{
}
int RSA::prime(int m) //判断是否为素数
{
int i;
for (i = 2; i if (m%i == 0) return 0; } return 1; } int RSA::(int x, int y) //判断是否互素 { int t; while (y) { t = x; x = y; y = t%y; } return x; } int RSA::ExtendedEuclidean(int a, int b, int *r) //根据扩展欧几里得算法求乘法逆元 { int x1, x2, x3, y1, y2, y3, t1, t2, t3, c; x1 = y2 = 1; x2 = y1 = 0; if (a >= b) { x3 = a; y3 = b; } else { x3 = b; y3 = a; } while (1) { c = x3 / y3; t1 = x1 - c*y1; t2 = x2 - c*y2; x1 = y1; x2 = y2; t3 = x3 - c*y3; x3 = y3; y1 = t1; y2 = t2; y3 = t3; if (y3 == 1) { *r = y2; return 1;; } } } int RSA::power(int a) //2的a次幂 { int b = 1, i; for (i = 1; i <= a; i++) { b = b * 2; } return b; } int RSA::mod(int f, int g, int h) //加解密 { int i; int s = 1; for (i = 1; i <= g; i++) { s = s*f; s = s%h; } return s; } CString RSA::encrpt(CString plaintext, int key) { CString ciphertext; int i, j, b, a, sum, k; int t, temp, l = 0, ch = 1, f, l1; int p, q, n, y, e, d = 0; int num[200]; char plain[100]; int plain1[100], cipher[100], al[10000], bl[10000]; // printf("请输入第一个大素数p:"); //输入两个大素数p,q while (1) { //scanf("%d", &p); p = 519817; if (prime(p) == 1) break; else printf("p不是素数,请重新输入:"); } //printf("请输入第二个大素数q:"); while (1) { //scanf("%d", &q); q = 521887; if (prime(q) == 1) break; else printf("q不是素数,请重新输入:"); } n = p*q; y = (p - 1)*(q - 1); //printf("n = %d y = %d\\n", n, y); //printf("请输入一个整数e:"); //输入与y互素的整数e while (1) { //scanf("%d", &e); e = key; if ((e, y) == 1) break; else { //printf("e不符合条件,请重新输入:"); AfxMessageBox(L"e不符合条件,请重新输入"); } } ExtendedEuclidean(e, y, &d); //计算d //printf("d = %d\\n", d); //printf("公钥:( %d , %d )\\n", e, n); //printf("私钥:( %d , %d )\\n", d, n); while (ch ch = ch * 2; l++; } l = l - 1; //每块长度 //printf("%d\\n", l); //printf("请选择:1.加密; 2.解密;\\n"); //scanf("%d", &b); b = 1; if (b == 1) //加密 { // printf("请输入明文:"); // scanf("%s", &plain); int ii; for ( ii = 0; ii < plaintext.GetLength(); ii++) { plain[ii] = plaintext[ii]; } plain[ii] = '\\0'; t = strlen(plain); /*明文信息数字化*/ for (i = 0; i j = 6; temp = plain[i]; while (temp != 0) { al[i * 8 + j + 1] = temp % 2; temp = temp / 2; j--; } al[i * 8] = 0; } if (t * 8 % l == 0) //转为十进制 { f = t * 8 / l; for (i = 0; i sum = 0; for (j = 0; j sum = sum + al[j + i*f] * power(l - 1 - j); } num[i] = sum; // printf("%d ", num[i]); CString tmp; tmp.Format(_T("%d"), num[i]); ciphertext += tmp; } // printf("\\n"); } else { f = t * 8 / l + 1; l1 = t * 8 % l; for (i = 0; i sum = 0; for (j = 0; j sum = sum + al[j + i*f] * power(l - 1 - j); } num[i] = sum; // printf("%d ", num[i]); CString tmp; tmp.Format(_T("%d"), num[i]); ciphertext += tmp; } sum = 0; for (j = 0; j sum = sum + al[j + i*l] * power(l1 - 1 - j); } num[f - 1] = sum; // printf("%d\\n", num[f - 1]); CString tmp; tmp.Format(_T("%d"), num[f-1]); ciphertext += tmp; } for (i = 0; i cipher[i] = mod(num[i], e, n); // printf("%d ", cipher[i]); CString tmp; tmp.Format(_T("%d"), num[i]); ciphertext += tmp; } // printf("\\n"); } return ciphertext; } CString RSA::decrypt(CString ciphertext, int key) { CString plaintext; int i, j, b, a, sum, k; int t, temp, l = 0, ch = 1, f, l1; int p, q, n, y, e, d = 0; int num[200]; char plain[100]; int plain1[100], cipher[100], al[10000], bl[10000]; //printf("请输入第一个大素数p:"); //输入两个大素数p,q while (1) { //scanf("%d", &p); p = 519817; if (prime(p) == 1) break; else printf("p不是素数,请重新输入:"); } //printf("请输入第二个大素数q:"); while (1) { // scanf("%d", &q); q = 521887; if (prime(q) == 1) break; else printf("q不是素数,请重新输入:"); } n = p*q; y = (p - 1)*(q - 1); //printf("n = %d y = %d\\n", n, y); //printf("请输入一个整数e:"); //输入与y互素的整数e while (1) { //scanf("%d", &e); e = key; if ((e, y) == 1) break; else //printf("e不符合条件,请重新输入:"); { AfxMessageBox(L"e不符合条件,请重新输入"); } } ExtendedEuclidean(e, y, &d); //计算d //printf("d = %d\\n", d); //printf("公钥:( %d , %d )\\n", e, n); //printf("私钥:( %d , %d )\\n", d, n); while (ch ch = ch * 2; l++; } l = l - 1; //每块长度 //printf("%d\\n", l); b = 2; if (b == 2) //解密 { //printf("请输入密文的个数:"); //scanf("%d", &a); a = ciphertext.GetLength(); for (i = 0; i { //printf("请输入第%d个密文数字:", i + 1); //scanf("%d", &cipher[i]); cipher[i] = ciphertext[i]; } for (i = 0; i { num[i] = mod(cipher[i], d, n); // printf("%d ", num[i]); } // printf("\\n"); /*数字转换为明文*/
