密码技术实训(实验)

Lab1 RSA算法实践

素数筛法

线性筛法,输出素数到 .dat 文件,素数个数回显。

#include <iostream>
#include <fstream>
#include <vector>

static const int NUM = int(1e6 + 1);
static bool isSieved[NUM] = {
    
    false};
std::vector<int> prime;

void linear_sieve() {
    
    
	isSieved[1] = true;
	for (int curr = 2; curr < NUM; ++curr) {
    
    
		if (!isSieved[curr]) prime.emplace_back(curr);
		for (int multi = 0; multi < prime.size() && prime[multi] * curr < NUM; ++multi) {
    
    
			isSieved[prime[multi] * curr] = true;
			if (curr % prime[multi] == 0) break;
		}
	}
}

int main() {
    
    
	linear_sieve();
	std::cout << "The number of primes between 1 and 1e6 is: " << prime.size() << std::endl;

	std::ofstream outfile("./prime_list.dat");
	for (int i : prime) outfile << i << std::endl;
	outfile.close();
	return 0;
}

openssl

openssl genrsa -out rsa_2048_priv.pem 2048
openssl rsa -pubout -in rsa_2048_priv.pem -out rsa_2048_pub.pem

vim .\plaintext.txt
# write something

openssl pkeyutl -encrypt -inkey .\rsa_2048_pub.pem -pubin -in .\plaintext.txt -out .\ciphertext.txt
vim .\ciphertext.txt
openssl pkeyutl -decrypt -inkey .\rsa_2048_priv.pem -in .\ciphertext.txt -out .\plaintext2.txt
vim .\plaintext2.txt

factorize

.\yafu-x64 "factor(@)" -batchfile .\pcat.txt

pcat.txt 末尾须换行。

966808932627497190635859236054960349099463975227350564265384373280336699853387254070662881265937565163000758606154308757944030571837175048514574473061401566330836334647176655282619268592560172726526643074499534129878217409046045533656897050117438496357231575999185527675071002803951800635220029015932007465117818739948903750200830856115668691007706836952244842719419452946259275251773298338162389930518838272704908887016474007051397194588396039111216708866214614779627566959335170676055025850932631053641576566165694121420546081043285806783239296799795655191121966377590175780618944910532816988143056757054052679968538901460893571204904394975714081055455240523895653305315517745729334114549756695334171142876080477105070409544777981602152762154610738540163796164295222810243309051503090866674634440359226192530724635477051576515179864461174911975667162597286769079380660782647952944808596310476973939156187472076952935728249061137481887589103973591082872988641958270285169650803792395556363304056290077801453980822097583574309682935697260204862756923865556397686696854239564541407185709940107806536773160263764483443859425726953142964148216209968437587044617613518058779287167853349364533716458676066734216877566181514607693882375533

Lab2 AES侧信道攻击

环境配置

miniConda 实验环境已打包:cryptLab-conda-24.7.1.tar.gz,解压到 .\envs 目录下即可激活使用(存在部分问题,待更新)。

AES程序

补全主程序密钥,可选择为:

uint8_t key[] = {
    
    
    0x00, 0x01, 0x02, 0x03, 
    0x04, 0x05, 0x06, 0x07, 
    0x08, 0x09, 0x0a, 0x0b, 
    0x0c, 0x0d, 0x0e, 0x0f
};

补全 AES.c 文件中加密函数实现:

	// 轮密钥加启动
	add_round_key(state, w, 0);
	// 前9轮:字节代换,行位移,列混淆,轮密钥加
	for (r = 1; r < Nr; r++) {
    
    
		sub_bytes(state);
		shift_rows(state);
		mix_columns(state);
		add_round_key(state, w, r);
	}
	// 最后一轮:字节代换,行位移,轮密钥加
	sub_bytes(state);
	shift_rows(state);
	add_round_key(state, w, Nr);

补全 .ipynb 文件:

import serial
import numpy as np

# 根据实际情况更改串行接口
mega = serial.Serial('COM3', 115200, timeout=1)

def get_meta():
    p = np.random.randint(0, 256, 16, dtype=np.uint8)
    send = p.tobytes()
    mega.write(send)
    recv = mega.read(16)
    c = np.frombuffer(recv, dtype=np.uint8)
    # 关闭接口
    mega.close()
    return p, c

# 如显示不存在 Crypto module,删除 crypto 库及 pycryptodome 库,并重新安装 pycryptodome 库
from Crypto.Cipher import AES

# 与开发板密钥一致
key = bytes([0x00, 0x01, 0x02, 0x03, 
    0x04, 0x05, 0x06, 0x07, 
    0x08, 0x09, 0x0a, 0x0b, 
    0x0c, 0x0d, 0x0e, 0x0f])
    
aes = AES.new(key,AES.MODE_ECB)

def verify(p, c):
    c_correct = aes.encrypt(p.tobytes())
    if c.tobytes() == c_correct:
        return True
    else:
        return False

# 记录循环运行的性能和加密结果
import time

def verify_multiple_runs(num_runs):
    results = []
    for _ in range(num_runs):
        start_time = time.time()
        p, c = get_meta()
        elapsed_time = time.time() - start_time
        is_valid = verify(p, c)
        results.append((p, c, is_valid, elapsed_time))
        sleep(0.05)
    return results

results_100 = verify_multiple_runs(100)
results_1000 = verify_multiple_runs(1000)
results_10000 = verify_multiple_runs(10000)

def save_results_to_file(results, filename='result.dat'):
    with open(filename, 'w') as file:
        for p, c, is_valid, elapsed_time in results:
            file.write(f'p: {
      
      p.tolist()}, c: {
      
      c.tolist()}, valid: {
      
      is_valid}, time: {
      
      elapsed_time:.6f}\n')

save_results_to_file(results_100, 'result_100.dat')
save_results_to_file(results_1000, 'result_1000.dat')
save_results_to_file(results_10000, 'result_10000.dat')

轨迹采集

补全 .ipynb 文件:TOE 部分与上述一致;导出轨迹文件;补全引用库和相关参数。

import matplotlib.pyplot as plt

for i in tnrange(100):
    plaintext = np.empty((pico.sequence_num, 10000), dtype=np.uint8)
    ciphertext = np.empty((pico.sequence_num, 10000), dtype=np.uint8)

侧信道攻击

补全 .ipynb 文件:补全引用库;导入轨迹文件。

import matplotlib.pyplot as plt

猜你喜欢

转载自blog.csdn.net/annesede/article/details/142962403