概述
这是信息系统安全实验系列的第五篇~
1. 实验目的
(1)掌握对称加密、非对称加密、身份认证的基本原理;
(2)实现凯撒密码加密算法、RSA加密算法以及他们的应用;
(3)了解国产加密算法SM4的基本知识。
2. 实验原理
(1)凯撒密码加密算法
凯撒密码是一种简单的替换密码,属于对称加密算法中的一种。密钥十分简单,选定一个mod 26的数作为密钥。加密时,将被加密的字母转换为数字(例如按字母顺序编号),然后将数字加上密钥在模26,便得到密文。解密时,将密文数字前移即可。
(2)RSA加密算法
RSA算法基于简单的数论事实:将两个大质数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。步骤如下:
选择一对不同的、足够大的素数p,q。
计算n=pq。
计算f(n)=(p-1)(q-1),同时对p, q严加保密,不让任何人知道。
找一个与f(n)互质的数e,且1<e<f(n)。
计算d,使得de≡1 mod f(n)。这个公式也可以表达为d ≡e-1 mod f(n)
公钥KU=(e,n),私钥KR=(d,n)。
加密时,先将明文变换成0至n-1的一个整数M。若明文较长,可先分割成适当的组,然后再进行交换。设密文为C,则加密过程为。C=M^e (mod n)
解密过程为:M=C^d (mod n)
3. 实验过程记录
图1(加密通信过程)
(1)实现加密通信过程
① 代码(只支持传递仅含小写字母的消息)
#include<iostream>
#include<string>
#include<time.h>
#include<stdlib.h>
using namespace std;
//本程序只传输小写字母
const string message = "congratulations";//要传输的信息
const int length_k_sess = 8;//会话密钥的长度
const int half_length_key = 6;//双方的公钥和私钥的长度的一半(为简便,假设双方的密钥一样长)
int prime_num_1[20] = {17,23,31,41,47,59,67,73,83,97,103,109,127,137,149,157,163,173,181,193};//素数表(为简便,仅提供20个选择)
int prime_num_2[20] = {13,19,29,37,43,53,61,71,79,89,101,107,113,131,139,151,167,179,191,197};
class User{
public:
string name;//名字
int pub_key[2*half_length_key];//公钥
int pri_key[2*half_length_key];//私钥
string message_send;//发出的密文
string message_receive;//收到的密文
int k_sess[length_k_sess];//保存的会话密钥
string message;//信息明文
};
User Alice;
User Bob;
void generate_keys_rsa(User X){//生成X的公钥和私钥
cout << "Generating keys of " << X.name << " ..." << endl;
int suiji = (int)time(NULL);
for(int i = 0; i < half_length_key; i++){
srand(suiji);
int choice = (int)rand() % 20 + i * 77;
choice = choice % 20;
int p, q;
if(X.name == "Alice"){
p = prime_num_1[choice];
q = prime_num_1[(choice + 10) % 20];
}else{
p = prime_num_2[choice];
q = prime_num_2[(choice + 10) % 20];
}
suiji = choice * q * 1000;
int n = p * q;
int f = (p-1) * (q-1);
int e;
if(X.name == "Alice"){
if(f % p != 0){
e = p;
}else{
e = q;
}
}else{
if(f % q != 0){
e = q;
}else{
e = p;
}
}
int d;
for(int j = 1; j < f; j++){
int temp = (j*e) % f;
if(temp < 0){
temp += f;
}
if(temp == 1){
d = j;
break;
}
}
if(X.name == "Alice"){
Alice.pub_key[i] = e;
Alice.pub_key[i + half_length_key] = n;
Alice.pri_key[i] = d;
Alice.pri_key[i + half_length_key] = n;
}else{
Bob.pub_key[i] = e;
Bob.pub_key[i + half_length_key] = n;
Bob.pri_key[i] = d;
Bob.pri_key[i + half_length_key] = n;
}
}
cout << "Keys of " << X.name << " are generated." << endl;
}
void generate_k_sess(){//随机生成会话密钥
cout << "Generating Ksess..." << endl;
for(int i = 0; i < length_k_sess; i++){
int c = (int)rand() % 1000;
Alice.k_sess[i] = c;
srand(100*c);
}
cout << "Ksess is generated." << endl;
}
void initiate(){//初始化
Alice.name = "Alice";
Bob.name = "Bob";
//生成双方的公钥和私钥
generate_keys_rsa(Alice);
generate_keys_rsa(Bob);
//随机生成会话密钥
generate_k_sess();
Alice.message = message;
}
void rsa(int* text, int* key, int* result){//使用rsa算法加密/解密
for(int i = 0; i < length_k_sess; i++){
int e_or_d = key[i % half_length_key];
int n = key[i % half_length_key + half_length_key];
int temp = text[i];
for(int j = 1; j < e_or_d; j++){
temp *= text[i];
temp %= n;
if(temp < 0){
temp += n;
}
}
result[i] = temp;
}
}
string encrypt_ks(string text, int* key){//使用凯撒算法加密明文text,密钥为key,返回密文
int len_key = length_k_sess;
int len_text = text.size();
string text_1;
for(int i = 0; i < len_text; i++){
int mv = key[i % length_k_sess];
int index = (text[i] - 'a' + 1 + mv) % 26;
if(index <= 0){
index += 26;
}
text_1.append(1, index + 'a' - 1);
}
//cout << ".:" << text_1 << endl;
return text_1;
}
string decrypt_ks(string text, int* key){//使用凯撒算法解密密文text,密钥为key,返回明文
int len_key = length_k_sess;
int len_text = text.size();
string text_1;
for(int i = 0; i < len_text; i++){
int mv = key[i % length_k_sess];
int index = (text[i] - 'a' + 1 - mv) % 26;
if(index <= 0){
index += 26;
}
text_1.append(1, index + 'a' - 1);
}
//cout << ".:" << text_1 << endl;
return text_1;
}
void session(){//会话过程
int temp_a[length_k_sess];
int temp_b[length_k_sess];
//步骤1:Alice先后用Bob的公钥和Alice的私钥加密会话密钥,发给Bob
cout << "Alice is encrypting Ksess using the public key of Bob..." << endl;
rsa(Alice.k_sess, Bob.pub_key, temp_a);
cout << "Alice is encrypting Ksess using her private key..." << endl;
rsa(temp_a, Alice.pri_key, temp_b);
cout << "Encrypted Ksess sent from Alice to Bob." << endl;
//步骤2:Bob得到数据包后,先后用Alice的公钥和Bob的私钥解密得到会话密钥
cout << "Bob is decrypting Ksess using the public key of Alice..." << endl;
rsa(temp_b, Alice.pub_key, temp_b);
cout << "Bob is decrypting Ksess using his private key..." << endl;
rsa(temp_b, Bob.pri_key, Bob.k_sess);
cout << "Bob has gotten Ksess." << endl;
//步骤3:Bob先后用Alice的公钥和Bob的私钥加密会话密钥,发给Alice
cout << "Bob is encrypting Ksess using the public key of Alice..." << endl;
rsa(Bob.k_sess, Alice.pub_key, temp_b);
cout << "Bob is encrypting Ksess using his private key..." << endl;
rsa(temp_b, Bob.pri_key, temp_a);
cout << "Encrypted Ksess sent from Bob to Alice." << endl;
//步骤4:Alice解密数据包并确认会话密钥是否正确,若错误,会话结束,否则把用会话密钥加密的信息发给Bob
cout << "Alice is decrypting returned Ksess using the public key of Bob..." << endl;
rsa(temp_a, Bob.pub_key, temp_a);
cout << "Alice is decrypting returned Ksess using her private key..." << endl;
rsa(temp_a, Alice.pri_key, temp_a);
cout << "Alice is verifying Ksess..." << endl;
bool flag = true;
for(int i = 0; i < length_k_sess; i++){
if(temp_a[i] != Alice.k_sess[i]){
flag = false;
break;
}
}
if(!flag){
cout << "The session is finished due to unmatched Ksess." << endl;
return;
}else{
cout << "Ksess verified." << endl;
cout << "Alice is encrypting the message using Ksess..." << endl;
Alice.message_send = encrypt_ks(Alice.message, Alice.k_sess);
cout << "Encrypted message sent from Alice to Bob." << endl;
Bob.message_receive = Alice.message_send;
}
//步骤5:Bob得到数据包后,用会话密钥解密信息
cout << "Bob is decrypting the message using Ksess..." << endl;
Bob.message = decrypt_ks(Bob.message_receive, Bob.k_sess);
cout << "Bob has gotten the message." << endl;
}
void verify(){//确认加密解密过程是否正确
cout << "The session is finished.nDetails: " << endl;
cout << "The Ksess generated by Alice is:";
for(int i = 0; i < length_k_sess; i++){
cout << " " << Alice.k_sess[i];
}
cout << endl;
cout << "The Ksess adopted by Bob is:";
for(int i = 0; i < length_k_sess; i++){
cout << " " << Bob.k_sess[i];
}
cout << endl;
cout << "The message sent by Alice is: " << Alice.message << endl;
cout << "The message gotten by Bob is: " << Bob.message << endl;
}
int main(){
//初始化
initiate();
//会话过程
session();
//确认加密解密过程是否正确
verify();
return 0;
}
② 过程分析和结果截图
对整个session的过程的分析和信息传递的结果如图2所示:
图2(信息传递过程及结果)
③ 阐明每个字母的意义和不可缺少性
字母 | 意义 | 不可缺少性 |
Ksess | 会话密钥 | 用于对称加密,即对话双方都使用它来加密和解密明文。如果没有它,对话双方只能以明文形式或某种用公开的密钥加密的形式传输信息,很不安全。 |
KPUB-A | Alice的公钥 | 用于非对称加密,Bob使用它来对会话密钥进行第一层加密和验证Alice的数字签名。 所有人都可以用公钥来加密要传输给Alice的信息,但只有使用Alice的私钥才能解密。如果没有它,所有人都可以在用Bob的公钥解开第一层签名后,获得会话密钥。 所有人都可以用公钥来验证Alice的数字签名,但只有使用Alice的私钥才能进行签名。如果没有它,将无法确认数据包是否由Alice发出。 |
KPUB-B | Bob的公钥 | 用于非对称加密,Alice使用它来对会话密钥进行第一层加密和验证Bob的数字签名。 所有人都可以用公钥来加密要传输给Bob的信息,但只有使用Bob的私钥才能解密。如果没有它,所有人都可以在用Alice的公钥解开第一层签名后,获得会话密钥。 所有人都可以用公钥来验证Bob的数字签名,但只有使用Bob的私钥才能进行签名。如果没有它,将无法确认数据包是否由Bob发出。 |
KPRI-A | Alice的私钥 | 用于非对称加密,Alice使用它来对要传输的数据包进行数字签名和解出经KPUB-A加密过的会话密钥。 只有使用私钥才能对传输的数据进行数字签名。如果没有它,其他人都无法验证该数据包是否由Alice发出。 所有人都可以用公钥来加密要传输给Alice的信息,但只有使用Alice的私钥才能解密。如果没有它,将无法解密获得会话密钥。 |
KPRI-B | Bob的私钥 | 用于非对称加密,Bob使用它来对要传输的数据包进行数字签名和解出经KPUB-B加密过的会话密钥。 只有使用私钥才能对传输的数据进行数字签名。如果没有它,其他人都无法验证该数据包是否由Bob发出。 所有人都可以用公钥来加密要传输给Bob的信息,但只有使用Bob的私钥才能解密。如果没有它,将无法解密获得会话密钥。 |
(2)国产加密算法SM4的相关知识
① 简介
SM4.0(原名SMS4.0)是中华人民共和国政府采用的一种分组密码标准,由国家密码管理局于2012年3月21日发布。相关标准为“GM/T 0002-2012《SM4分组密码算法》(原SMS4分组密码算法)”。
在商用密码体系中,SM4主要用于数据加密,其算法公开,分组长度与密钥长度均为128bit,加密算法与密钥扩展算法都采用32轮非线性迭代结构,S盒为固定的8比特输入8比特输出。
SM4.0中的指令长度被提升到大于64K(即64×1024)的水平,这是SM 3.0规格(渲染指令长度允许大于512)的128倍。
② 加密过程
加密算法采用32轮迭代结构,每轮使用一个轮密钥,与DES算法相似,每一轮中先使用sbox进行非线性变换,然后再通过循环移位操作进行线性变换。其每轮加密用到了之前四轮加密的结果,进一步提高了加密的强度。
③ 解密过程
SM4密码算法是对合运算,因此解密算法与加密算法的结构相同,只是轮密铝的使用顺序相反,解密轮密钥是加密轮密钥的逆序。
④ 安全性
SM4密码算法经过我国专业密码机构的充分分析测试,可以抵抗差分攻击、线性攻击等现有攻击,因此是安全的。
*参考资料:
http://www.kokojia.com/article/23866.html
https://baike.baidu.com/item/SM4.0/3901780?fr=aladdin
http://www.cnnic.net.cn/jscx/mixbz/sm4/
最后
以上就是乐观小伙为你收集整理的信息系统安全实验(五):RSA加密算法在身份互认证中的应用(含c++代码)、国产加密算法SM4的基本知识1. 实验目的2. 实验原理3. 实验过程记录的全部内容,希望文章能够帮你解决信息系统安全实验(五):RSA加密算法在身份互认证中的应用(含c++代码)、国产加密算法SM4的基本知识1. 实验目的2. 实验原理3. 实验过程记录所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复