前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【愚公系列】2021年12月 攻防世界-简单题-CRYPTO-011(Normal_RSA)

【愚公系列】2021年12月 攻防世界-简单题-CRYPTO-011(Normal_RSA)

作者头像
愚公搬代码
发布2021-12-27 08:15:41
4110
发布2021-12-27 08:15:41
举报
文章被收录于专栏:历史专栏

文章目录


前言

题目描述:你和小鱼走啊走走啊走,走到下一个题目一看你又一愣,怎么还是一个数学题啊 小鱼又一笑,hhhh数学在密码学里面很重要的!现在知道吃亏了吧!你哼一声不服气,我知道数学 很重要了!但是工具也很重要的,你看我拿工具把他解出来!你打开电脑折腾了一会还真的把答案 做了出来,小鱼有些吃惊,向你投过来一个赞叹的目光


提示:以下是本篇文章正文内容,下面案例可供参考

一、Normal_RSA

题目链接:https://adworld.xctf.org.cn/task/answer?type=crypto&number=5&grade=0&id=5109&page=1

二、使用步骤

1.下载附件

flag.enc 看后缀enc,分析是一个通过openssl加密后生成的文件

pubkey.pem 应该是一个公钥信息文件

在这里插入图片描述
在这里插入图片描述

2.openssl

这里我使用kali系统,因为kali系统自带了openssl

先进入openssl 输入 rsa -pubin -text -modulus -in warmup -in pubkey.pem 查看信息

在这里插入图片描述
在这里插入图片描述

Exponent:指的是RSA中的e Modulus:指的是N,即pq相乘

代码语言:javascript
复制
Exponent:00:c2:63:6a:e5:c3:d8:e4:3f:fb:97:ab:09:02:8f:
    1a:ac:6c:0b:f6:cd:3d:70:eb:ca:28:1b:ff:e9:7f:
    be:30:dd
Modulus:65537

先将16进制转为10进制,接着在线质因数分解 分解网址:http://www.factordb.com/

在这里插入图片描述
在这里插入图片描述

现在已得到的信息:

代码语言:javascript
复制
p=275127860351348928173285174381581152299
q=319576316814478949870590164193048041239
e=65537

3.生成私钥

restool脚本代码

代码语言:javascript
复制
#!/usr/bin/env python3
import base64
import fractions
import argparse
import random
import sys

try:
    import gmpy
except ImportError as e:
    try:
        import gmpy2 as gmpy
    except ImportError:
        raise e

if sys.version_info >= (3,5):
    from math import gcd
else:
    from fractions import gcd

from pyasn1.codec.der import encoder
from pyasn1.type.univ import Sequence, Integer

PEM_TEMPLATE = b'-----BEGIN RSA PRIVATE KEY-----\n%s-----END RSA PRIVATE KEY-----\n'
DEFAULT_EXP = 65537


def factor_modulus(n, d, e):
    """
    Efficiently recover non-trivial factors of n
    See: Handbook of Applied Cryptography
    8.2.2 Security of RSA -> (i) Relation to factoring (p.287)
    http://www.cacr.math.uwaterloo.ca/hac/
    """
    t = (e * d - 1)
    s = 0

    while True:
        quotient, remainder = divmod(t, 2)

        if remainder != 0:
            break

        s += 1
        t = quotient

    found = False

    while not found:
        i = 1
        a = random.randint(1, n-1)

        while i <= s and not found:
            c1 = pow(a, pow(2, i-1, n) * t, n)
            c2 = pow(a, pow(2, i, n) * t, n)

            found = c1 != 1 and c1 != (-1 % n) and c2 == 1

            i += 1

    p = gcd(c1-1, n)
    q = n // p

    return p, q


class RSA:
    def __init__(self, p=None, q=None, n=None, d=None, e=DEFAULT_EXP):
        """
        Initialize RSA instance using primes (p, q)
        or modulus and private exponent (n, d)
        """

        self.e = e

        if p and q:
            assert gmpy.is_prime(p), 'p is not prime'
            assert gmpy.is_prime(q), 'q is not prime'

            self.p = p
            self.q = q
        elif n and d:
            self.p, self.q = factor_modulus(n, d, e)
        else:
            raise ArgumentError('Either (p, q) or (n, d) must be provided')

        self._calc_values()

    def _calc_values(self):
        self.n = self.p * self.q

        if self.p != self.q:
            phi = (self.p - 1) * (self.q - 1)
        else:
            phi = (self.p ** 2) - self.p

        self.d = gmpy.invert(self.e, phi)

        # CRT-RSA precomputation
        self.dP = self.d % (self.p - 1)
        self.dQ = self.d % (self.q - 1)
        self.qInv = gmpy.invert(self.q, self.p)

    def to_pem(self):
        """
        Return OpenSSL-compatible PEM encoded key
        """
        return PEM_TEMPLATE % base64.encodebytes(self.to_der())

    def to_der(self):
        """
        Return parameters as OpenSSL compatible DER encoded key
        """
        seq = Sequence()

        for idx, x in enumerate([0, self.n, self.e, self.d, self.p, self.q, self.dP, self.dQ, self.qInv]):
            seq.setComponentByPosition(idx, Integer(x))

        return encoder.encode(seq)

    def dump(self, verbose):
        vars = ['n', 'e', 'd', 'p', 'q']

        if verbose:
            vars += ['dP', 'dQ', 'qInv']

        for v in vars:
            self._dumpvar(v)

    def _dumpvar(self, var):
        val = getattr(self, var)

        def parts(s, l): return '\n'.join(
            [s[i:i+l] for i in range(0, len(s), l)])

        if len(str(val)) <= 40:
            print('%s = %d (%#x)\n' % (var, val, val))
        else:
            print('%s =' % var)
            print(parts('%x' % val, 80) + '\n')


if __name__ == '__main__':
    parser = argparse.ArgumentParser()

    parser.add_argument('-n', help='modulus. format : int or 0xhex', type=lambda x: int(x, 0))
    parser.add_argument('-p', help='first prime number. format : int or 0xhex', type=lambda x: int(x, 0))
    parser.add_argument('-q', help='second prime number. format : int or 0xhex', type=lambda x: int(x, 0))
    parser.add_argument('-d', help='private exponent. format : int or 0xhex',
                        type=lambda x: int(x, 0))
    parser.add_argument('-e', help='public exponent (default: %d). format : int or 0xhex' %
                        DEFAULT_EXP, default=DEFAULT_EXP, type=lambda x: int(x, 0))
    parser.add_argument('-o', '--output', help='output filename')
    parser.add_argument('-f', '--format', help='output format (DER, PEM) (default: PEM)',
                        choices=['DER', 'PEM'], default='PEM')
    parser.add_argument('-v', '--verbose', help='also display CRT-RSA representation',
                        action='store_true', default=False)

    args = parser.parse_args()

    if args.p and args.q:
        print('Using (p, q) to initialise RSA instance\n')
        rsa = RSA(p=args.p, q=args.q, e=args.e)
    elif args.n and args.d:
        print('Using (n, d) to initialise RSA instance\n')
        rsa = RSA(n=args.n, d=args.d, e=args.e)
    else:
        parser.print_help()
        parser.error('Either (p, q) or (n, d) needs to be specified')

    rsa.dump(args.verbose)

    if args.format == 'PEM':
        data = rsa.to_pem()
    elif args.format == 'DER':
        data = rsa.to_der()

    if args.output:
        print('Saving %s as %s' % (args.format, args.output))

        fp = open(args.output, 'wb')
        fp.write(data)
        fp.close()

    else:
        sys.stdout.buffer.write(data)

这里我使用了如下命令:

代码语言:javascript
复制
python3 -m pip install gmpy

安装好需要的模块后输入命令:

代码语言:javascript
复制
python3 rsatool.py -f PEM -o private.pem -p 275127860351348928173285174381581152299 -q 319576316814478949870590164193048041239 -e 65537

即可生成private.pem文件

在这里插入图片描述
在这里插入图片描述

4.解密文件

代码语言:javascript
复制
openssl rsautl -decrypt -in flag.enc -inkey private.pem
在这里插入图片描述
在这里插入图片描述

得到flag:PCTF{256b_i5_m3dium}


总结

  • openssl
  • gmpy
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/12/26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 前言
  • 一、Normal_RSA
  • 二、使用步骤
    • 1.下载附件
      • 2.openssl
        • 3.生成私钥
          • 4.解密文件
          • 总结
          相关产品与服务
          SSL 证书
          腾讯云 SSL 证书(SSL Certificates)为您提供 SSL 证书的申请、管理、部署等服务,为您提供一站式 HTTPS 解决方案。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档