信息系统安全实验(五):RSA加密算法在身份互认证中的应用(含c++代码)、国产加密算法SM4的基本知识

这是信息系统安全实验系列的第五篇~

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. 实验过程记录

信息系统安全实验(五):RSA加密算法在身份互认证中的应用(含c++代码)、国产加密算法SM4的基本知识

                                                     图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所示:

信息系统安全实验(五):RSA加密算法在身份互认证中的应用(含c++代码)、国产加密算法SM4的基本知识

                                                                    图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/