【信息安全】RSA Public-Key Encryption and Signature Lab

学习资料

https://www.cnblogs.com/skprimin/p/16172231.html#_label0

预备知识

RSA的基础知识

涉及到的参数有:模数n,公钥指数e,私钥指数d,我们将(e,n)称为公钥,(d,n) 称为私钥
参数计算:

  • 选两个保密的大质数 p , q p,q p,q
  • 计算 N = p q N = pq N=pq,求N的欧拉函数值 ϕ ( N ) = ( p − 1 ) ( q − 1 ) \phi(N)=(p-1)(q-1) ϕ(N)=(p1)(q1)
  • 选择 e , 1 < e < ϕ ( n ) e, 1 < e < \phi(n) e,1<e<ϕ(n) e e e ϕ ( n ) \phi(n) ϕ(n)互为质数
  • d d d,要求 d d d满足 e ∗ d   m o d   ϕ ( n ) = 1 e*d \bmod \phi(n)=1 edmodϕ(n)=1

根据参数加密:
将明文M视为数字,假设 M < n M < n M<n
则密文 c = M e   m o d   n c=M^e \bmod n c=Memodn

根据参数解密:
则明文 M = c d   m o d   n M=c^d \bmod n M=cdmodn

相关软件包

c语言中可以#include <openssl/bn.h>
python中可以直接import gmpy2

Task 1: 推导RSA私钥

已知相关参数求秘钥

p = F7E75FDC469067FFDC4E847C51F452DF
q = E85CED54AF57E53E092113E62F436F4F
e = 0D88C3

vim task1.py
python3 task1.py
# 导入python中的高精度数学库
import gmpy2

# 已知参数
p = 0xF7E75FDC469067FFDC4E847C51F452DF
q = 0xE85CED54AF57E53E092113E62F436F4F
e = 0x0D88C3
# 计算n和n的欧拉函数值,并求出d
n = q * p
phi = (p - 1) * (q - 1)
# 求e mod phi的逆元d
d = gmpy2.invert(e, phi)

# 输出秘钥的16进制表示
print("private key:" + hex(d))

Task 2: 用RSA加密一个消息

使用公钥(e,n)对明文M进行加密,并且使用私钥(d,n)验证加密的正确性

n = DCBFFE3E51F62E09CE7032E2677A78946A849DC4CDDE3A4D0CB81629242FB1A5
e = 010001 (this hex value equals to decimal 65537)
M = A top secret!
d = 74D806F9F3A62BAE331FFE3F0A68AFE35B3D2E4794148AACBC26AA381CD7D30D

vim task2.py
python3 task2.py
import gmpy2
# 公钥参数
n = 0xDCBFFE3E51F62E09CE7032E2677A78946A849DC4CDDE3A4D0CB81629242FB1A5
e = 0x010001
# 明文
# 将字符串转换成16进制字符串,然后转换成16进制的数字
m = "A top secret!".encode("utf-8").hex()
m = int(m, 16)
# 进行加密
c = gmpy2.powmod(m, e, n)
# 输出16进制的加密结果
print(hex(c))

Task 3: 解密这个消息

公钥秘钥与上一个任务相同,让我们解密以下密文C,并将其转换为纯ASCII字符串。

C = 8C0F971DF2F3672B28811407E2DABBE1DA0FEBBBDFC7DCB67396567EA1E2493F

vim task3.py
python3 task3.py
import gmpy2

# 公钥参数
n = 0xDCBFFE3E51F62E09CE7032E2677A78946A849DC4CDDE3A4D0CB81629242FB1A5
d = 0x74D806F9F3A62BAE331FFE3F0A68AFE35B3D2E4794148AACBC26AA381CD7D30D
# 密文
C = 0x8C0F971DF2F3672B28811407E2DABBE1DA0FEBBBDFC7DCB67396567EA1E2493F

# 进行解密
M = gmpy2.powmod(C, d, n)
# 得到16进制的解密结果字符串
m = str(hex(M))[2:]
# 得到ASCII字符串
print("M:" + bytes.fromhex(m).decode("utf-8"))

Task 4: 产生一个消息的数字签名

让我们产生一个消息的签名;接着对消息进行变化,再次产生签名并进行对比

两条消息分别是:
M = I owe you $2000.
M = I owe you $3000.

vim task4.py
python3 task4.py
import gmpy2

# 公钥参数
n = 0xDCBFFE3E51F62E09CE7032E2677A78946A849DC4CDDE3A4D0CB81629242FB1A5
e = 0x010001
d = 0x74D806F9F3A62BAE331FFE3F0A68AFE35B3D2E4794148AACBC26AA381CD7D30D

# 两个消息
msg = ["I owe you $2000", "I owe you $3000"]
for m in msg:
    print(m)
	# 将字符串转换成16进制字符串,然后转换成16进制的数字
    m = int(m.encode("utf-8").hex(), 16)
	# 进行加密
    c = gmpy2.powmod(m, d, n)
	# 输出16进制的加密结果
    print(hex(c))

Task 5: 验证这个数字签名是否正确

Bob收到来自Alice的消息M = “Launch a missile.”,其签名为s。我们知道Alice的公钥是(e, n),请验证该签名是否确实是Alice的。公钥和签名(十六进制)如下所示:
M = Launch a missile.
S = 643D6F34902D9C7EC90CB0B2BCA36C47FA37165C0005CAB026C0542CBDB6802F
e = 010001 (this hex value equals to decimal 65537)
n = AE1CD4DC432798D933779FBD46C6E1247F0CF1233595113AA51B450F18116115
假设in的签名已损坏,签名的最后一个字节从2F更改为3F,即只有一个比特的更改。请重复这个任务,并描述验证过程会发生什么。

vim task5.py
python3 task5.py
import gmpy2

# 消息
M = "Launch a missile."
# 原始消息签名
S_o = 0x643D6F34902D9C7EC90CB0B2BCA36C47FA37165C0005CAB026C0542CBDB6802F
# 损坏的消息签名
S_e = 0x643D6F34902D9C7EC90CB0B2BCA36C47FA37165C0005CAB026C0542CBDB6802A
# 公钥参数
n = 0xAE1CD4DC432798D933779FBD46C6E1247F0CF1233595113AA51B450F18116115
e = 0x010001

sig = [S_o, S_e]
for S in sig:
	# 对消息进行解密
    m = gmpy2.powmod(S, e, n)
    # 得到16进制的字符串
	m = str(hex(m))[2:]
    try:
		# 转成ASCLL
        msg = bytes.fromhex(m).decode('utf-8')
        print(msg)
        if msg == M:
            print("验证成功")
        else:
            print("验证失败")
    except:
        print(bytes.fromhex(m))
        print("验证失败")
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值