网络安全与管理实验之密码技术

实验一:密码技术

实验目的:

  1. 理解同余运算在密码学中的应用,理解中国剩余定理以及二次同余方程平方根求解问题
  2. 掌握凯撒密码
  3. 掌握Rabin公钥密码体制

任务1:编程现实凯撒密码

要求如下:

  1. 输入数据:为自己姓名的拼音字母,例如,李浩,则输入数据为:LIHAO。
  2. 密钥随机:每个字母移动位数不固定,例如输入字母l可以移动4位,输入字母i可以移动5位。
  3. 输出加密之后的密文。
  4. 解密,还原明文,并验证还原的明文是否和输入数据LIHAO相等,如果相等,解密成功。
  5. 可以对任意输入数据进行加密(选做)

任务2:编程实现Rabin公钥密码体制

要求如下:

  1. 输入数据:为自己姓名的拼音字母,例如,李浩,则输入数据为:LIHAO。
  2. 根据ASCII码表,将拼音字母转换为对应十进制数,例如,LIHAO转换为76,73,72,65,79。
  3. 密钥pq为素数,满足p\equiv q\equiv 3\left ( mod 4 \right )
  4. 输出加密之后的密文,包括十进制数以及十进制数对应的字符。
  5. 解密,还原明文,并验证还原的明文是否和输入数据LIHAO相等,如果相等,解密成功。
  6. 可以对任意输入数据进行加密(选做)

 

 对于这两个任务其实难度并不大,只需要弄清楚公式即可。以及思考一下进位的问题即可。
凯撒密码的公式:
加密公式 f(a)=(a+3) mod 26
解密公式 f(a)=(a+23) mod 26
关于Rabin密码体制的内容,大家可以去这里好好了解认识一下,这里主要针对本次实验,这里就不浪费时间了。密码学之公钥密码体系(4):Rabin公钥密码方案_摆渡沧桑的博客-CSDN博客_rabin密码一、Rabin公钥密码方案Rabin密码体制,被认为是对RSA密码体制的改进,其安全性基于求合数的模平方根的难度。而这个困难性等价于求解因子分解。RSA算法中只要素数被分解,密码就会被破解。而Rabin方案其实可以看做为RSA方案的一个特例,但被证明破译的难度和分解大整数一样难度。Rabin方案的特点:1. Rabin 方案不是一一映射的,对于同一个密文,可能会有多个对应的明文;2. Rabin算法的安全性基于求解合数模平方根困难性问题,破解难度和大整数分解相当;3. Rabin算法可以看做https://blog.csdn.net/vivid117/article/details/124784493现在我们在了解了公式的情况下,我们就可以去用代码实现这些了。

任务1源代码如下:
C++

#define _CRT_SECURE_NO_DEPRECATE
#include<stdio.h>
#include<iostream>
#include<stdlib.h>
#include <string.h>
#define N 100
using namespace std;
//凯撒密码
//加密公式 f(a)=(a+3) mod 26
//解密公式 f(a)=(a+23) mod 26

void Encry(char* strI, int numB, int model);//加密公式函数
void Decry(char* strI, int numB, int model);//解密公式函数
int FileOut(char* strI);
int main()
{
    char str[N];
    int model;
    int numB;

    while (1)
    {
        std::cout<< "凯撒密码:请选择模式:\n";
        std::cout << "1.加密\n";
        std::cout << "2.解密\n";
        std::cout << "3.退出\n";
        cin >> model;
        std::cout << endl;
        switch (model)
        {
        case 1:
            std::cout << "请输入要加密的字符串:";
            cin >> str;
            std::cout << "请输入该密码算法的偏移数量:";
            cin >> numB;
            Encry(str, numB, model);
            std::cout << endl;
            break;
        case 2:
            std::cout << "请输入要解密的字符串:";
            cin >> str;
            std::cout << "请输入原密码算法的偏移数量:";
            cin >> numB;
            Decry(str, numB, model);
            std::cout << endl;
            break;
        case 3:
            return 0;
            break;
        default:
            break;
        }
    }
    return 0;
}



void Encry(char* strI, int numB, int model)
{//明文串 秘钥 功能模式
    if (model == 1)
    {
            for (int i = 0; i < strlen(strI); i++)
            {
                    if (strI[i] >= 'A' && strI[i] <= 'Z')
                    {  
                            strI[i] = ((strI[i] - 'A') + numB) % 26 + 'A';
                    }

                    else if (strI[i] >= 'a' && strI[i] <= 'z')
                    {                      
                            strI[i] = ((strI[i] - 'a') + numB) % 26 + 'a';
                    }

            }
          std::cout << "加密完成:" << strI << endl;

        FileOut(strI);

        std::cout << "已输出到文件!" << endl;

    }

    else

    {       
        std::cout << "该模式不支持此项功能!" << endl;
    }

}



void Decry(char* strI, int numB, int model)
{ 
        if (model == 2)
        {          
            int num;
            num = 26 - numB;
            for (int i = 0; i < strlen(strI); i++)
            {

                if (strI[i] >= 'A' && strI[i] <= 'Z')
                {                    
                    strI[i] = ((strI[i] - 'A') + num) % 26 + 'A';
                }

                    else if (strI[i] >= 'a' && strI[i] <= 'z')

                    {                       
                            strI[i] = ((strI[i] - 'a') + num) % 26 + 'a';

                    }
            }
            std::cout << "解密完成:" << strI << endl;
        }

        else
        {          
                std::cout << "该模式不支持此项功能!" << endl;

        }

}



int FileOut(char* strI)

{   
        FILE* fp = NULL;
    int iWrite = 0;
    int len = strlen(strI);
    if (strI == NULL || len == 0)
        return false;
    //! 打开文件句柄
    if ((fp = fopen("密文.txt", "w")) == NULL)      // 文本模式写

        return false;



    iWrite = fwrite(strI, 1, len, fp);

    fclose(fp);



    if (iWrite > 0)

        return true;

    else

        return false;

}

 

任务2源代码如下:
python

import random
import time

# 判断是否为素数
# 判断可能失效,因为该方法有伪素数存在
def is_prime(n):
    if n == 0:
        return False
    return 1 == square_and_multiply(17, n - 1, n)


# 莫重复平方运算 b^n%m
def square_and_multiply(b, n, m):
    bi = b
    ai = 1
    k = len("{0:b}".format(n))
    for i in range(0, k):
        if (n >> i & 1) == 1:
            ai = ai * bi % m
        bi = bi ** 2 % m
    return ai


# 拓展欧几里得 , 求逆
def ex_gcd(a, b):
    if b == 0:
        return 1, 0, a
    else:
        s, t, r = ex_gcd(b, a % b)
        s, t = t, (s - (a // b) * t)
        return s, t, r


# 密钥生成
# return p,q,n, (p,q) is private key, n is public key
def key_generator():
    p = 0
    q = 0
    n = 0
    while (p - 3) % 4 != 0 or (q - 3) % 4 != 0 or p == q:
        random.seed(time.time())
        # 可以取非常大的值
        p = random.randint(2 * 300, 2 * 400)
        q = random.randint(2 * 300, 2 * 400)
    while not is_prime(p) or not is_prime(q):
        p += 4
        q += 4
    n = p * q
    return p, q, n


# 加密
# m is plaintext, n is public key
# 该算法通过重复明文方法来区分四个解
def encode(m, n):
    m1 = str(m)
    m1 = int(m1 + m1)
    c = m1 ** 2 % n
    return c


# 处理4个解的子方法
def sub_handle_decode_res(m):
    if len(m) % 2 != 0:
        return False
    i = 0
    while i < len(m) // 2:
        if m[i] != m[len(m) // 2 + i]:
            return False
        i = i + 1
    return m[:len(m) // 2]


# 处理4个解的情况
def handle_decode_res(m1, m2, m3, m4):
    m1_str = sub_handle_decode_res(str(m1))
    m2_str = sub_handle_decode_res(str(m2))
    m3_str = sub_handle_decode_res(str(m3))
    m4_str = sub_handle_decode_res(str(m4))
    if m1_str:
        return m1_str
    if m2_str:
        return m2_str
    if m3_str:
        return m3_str
    if m4_str:
        return m4_str


# 解密
def decode(c, p, q, n):
    s, t, r = ex_gcd(p, q)
    u = square_and_multiply(c, (p + 1) // 4, p)
    v = square_and_multiply(c, (q + 1) // 4, q)
    m1 = int(u * t * q + v * s * p) % n
    m2 = int(u * t * q - v * s * p) % n
    return handle_decode_res(m1, n - m1, m2, n - m2)


if __name__ == '__main__':
    p, q, n = key_generator()
    # 处理公钥私钥。
    print("p is {}, q is {}, n is {}".format(p, q, n))
    M = input("请输入明文:")
    # 转化为数组
    result1 = list(M)
    result2 = []
    result3 = []
    result4 = []
    for i in range(len(result1)):
        # 将字母转化为十进制
        m = ord(result1[i])
        c = encode(int(m), n)
        result2.append(c)
        # result3.append(chr(c))
        m = decode(c, p, q, n)
        result4.append(chr(int(m)))

    # print("密文十进制为{}, 字符为{}".format(result2, result3))
    print("密文十进制为{}".format(result2))
    m = ''.join(result4)
    if m == M:
        print("解密成功!")
    print("明文为 {}".format(m))

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

新人小季学编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值