RSA签名算法

RSA签名算法简介

  • 签名就是在这份资料后面增加一段强而有力的证明,以此证明这段信息的发布者和这段信息的有效性完整性。
  • RSA签名常用的就是将这份信息进行hash,得到一个hash值,再将hash值加密作为签名,后缀在信息的末尾。
  • 哈希的好处:更安全,签名更快,解除了签名长度的限制。

RSA签名的过程

  • A生成一对密钥(公钥和私钥),私钥不公开,A自己保留。公钥为公开的,任何人可以获取。
  • A用自己的私钥对消息加签,形成签名,并将加签的消息和消息本身一起传递给B。
  • B收到消息后,在获取A的公钥进行验签,如果验签出来的内容与消息本身一致,证明消息是A回复的。
  • 哈希函数的实现请参考本人其它文章:SHA256SHA1
  • 这里直接调用库函数实现哈希SHA512

全部代码

# -*-coding:utf-8-*-
"""
File Name: RSA签名.py

Program IDE: PyCharm

Create Time: 2021-10-31 14:20

Create By Author: 陆依依

"""
import hashlib		# 实现哈希
import random


# 产生大素数(w位)
def generate_prime(w):
    while True:
        # 产生一个奇数()
        num = random.randint(2 ** (w - 1), 2 ** w - 1) | 1
        # 对素数进行50次素性检验, 错误概率为:7.888609052210118e-31, 可以忽略
        for i in range(50):
            if not Miller_Rabin(num):
                break
            if i == 49:
                return num


# Miller-Rabin素性检测
def Miller_Rabin(num):
    m = num - 1
    k = 0
    while m % 2 == 0:
        m = m // 2
        k = k + 1
    a = random.randint(2, num)

    b = Mod_P(a, m, num)
    if b == 1:
        return True
    for i in range(k):
        if b == num - 1:
            return True
        else:
            b = b * b % num
    return False


# 非递归求a^n mod p, 快速幂思想
def Mod_P(a, n, p):
    c = 1
    binstr = bin(n)[2:][::-1]  # 通过切片去掉开头的0b,截取后面,然后反转
    for item in binstr:
        if item == '1':
            c = (c * a) % p
            a = (a ** 2) % p
        elif item == '0':
            a = (a ** 2) % p
    return c


# 求最大公因子.欧几里得算法
def gcd(a, b):
    if a % b == 0:
        return b
    else:
        return gcd(b, a % b)


# 求逆元,扩展欧几里得算法
def Ex_Euclid(x, n):
    r0 = n
    r1 = x % n
    if r1 == 1:
        y = 1
    else:
        s0 = 1
        s1 = 0
        t0 = 0
        t1 = 1
        while r0 % r1 != 0:
            q = r0 // r1
            r = r0 % r1
            r0 = r1
            r1 = r
            s = s0 - q * s1
            s0 = s1
            s1 = s
            t = t0 - q * t1
            t0 = t1
            t1 = t
            if r == 1:
                y = (t + n) % n
    return y


# 产生公私钥
def Build_key():
    p = generate_prime(512)
    q = generate_prime(512)

    n = p * q                   # n的长度近似为1024位,即秘钥长度1024
    _n = (p - 1) * (q - 1)      # n的欧拉函数

    while True:
        e = random.randint(2, _n-1)  # 随机选择一个与_n互质的整数,一般选择65537。
        if gcd(e, _n) == 1:        # 模拟计算
            break
    d = Ex_Euclid(e, _n)           # 计算e对_n的模反元素
    return n, e, d                  # 返回公私钥,公钥(n,e),私钥(n,d)


def sign(m, n, d):
    s = [Mod_P(ord(i), d, n) for i in m]
    return m, s


def verify(m, s, n, e):
    return m == ''.join([chr(Mod_P(i, e, n)) for i in s])


# demo
if __name__ == '__main__':
    choose = int(input('请选择加密对象:1)文件  2)非文件\t'))

    if choose == 2:
        message = input('请输入待加密内容:').encode('utf-8')
    else:
        path = input('请输入完整文件路径:')
        with open(path, 'rb') as f:
            message = f.read()

    m = hashlib.sha512(message).hexdigest()

    print('散列后的消息:', m)

    n, e, d = Build_key()

    m, s = sign(m, n, d)
    print('签名列表长度:', len(s))

    # 将签名写入新文件
    with open('sign.txt', 'w') as f:
        f.write(str(s).replace('[', '').replace(']', '').replace(',', '\n').replace(' ', ''))
    print('签名写入成功!!!')

    print('签名验证结果?', verify(m, s, n, e))

运行结果

  • 文本文件进行签名
    在这里插入图片描述
  • 签名结果:大概就是128个1024bit的大整数,后续不再展示
    在这里插入图片描述
  • 对非文本文件进行签名
    在这里插入图片描述
  • 对字符串进行签名
    在这里插入图片描述
  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
RSA(Rivest-Shamir-Adleman)是一种非对称加密算法,常用于进行数字签名等安全通信场景中。 RSA算法的原理是基于数论中的大数分解难题。该算法使用一个公钥和一个私钥来加密和解密数据。在数字签名场景中,发送方使用自己的私钥对消息进行签名,而接收方则使用发送方的公钥来验证签名的有效性。 具体实现上,RSA算法首先要生成一对密钥,包括一个公钥和一个私钥。公钥用于加密数据和验证签名,可以公开给任何人使用;私钥用于解密数据和生成签名,只能由拥有者私密保存。 在数字签名的过程中,发送方使用私钥对消息进行哈希运算,得到的哈希值再用私钥进行加密,生成数字签名。接收方收到消息和数字签名后,使用发送方的公钥进行解密,得到解密后的哈希值,并与原始消息进行哈希运算,将两个哈希值进行比较。如果相等,则说明消息未被篡改,签名有效;反之,则说明消息可能被篡改过。 RSA算法具有以下特点:安全性较高,计算复杂度大,适合对较小的数据进行加密和签名。不过,由于算法复杂度较高,对于大型数据的加密和签名会有一定的性能影响。 总之,C语言中实现RSA签名算法的过程涉及到生成密钥对、加密和解密数据、生成和验证签名的过程。通过使用RSA算法,可以实现数据的机密性和完整性保护,在安全通信中起到重要作用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值