Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >RSA公钥文件解密密文的原理分析

RSA公钥文件解密密文的原理分析

作者头像
Angel_Kitty
发布于 2018-08-15 07:26:35
发布于 2018-08-15 07:26:35
2.4K00
代码可运行
举报
运行总次数:0
代码可运行

前言

  最近在学习RSA加解密过程中遇到一个这样的难题:假设已知publickey公钥文件和加密后的密文flag,如何对其密文进行解密,转换成明文~~

分析

  对于rsa算法的公钥与私钥的产生,我们可以了解到以下产生原理:

公钥与私钥的产生

  1. 随机选择两个不同大质数 $p$ 和 $q$,计算 $N = p \times q$
  2. 根据欧拉函数,求得 $r=\varphi (N)=\varphi (p)\varphi (q)=(p-1)(q-1)$
  3. 选择一个小于 $r$ 的整数 $e$,使 $e$ 和 $r$ 互质。并求得 $e$ 关于 $r$ 的模反元素,命名为 $d$,有 $ed\equiv 1 \pmod r$
  4. 将 $p$ 和 $q$ 的记录销毁

此时,$(N,e)$ 是公钥,$(N,d)$ 是私钥。

消息加密

首先需要将消息 $m$ 以一个双方约定好的格式转化为一个小于 $N$,且与 $N$ 互质的整数 $n$。如果消息太长,可以将消息分为几段,这也就是我们所说的块加密,后对于每一部分利用如下公式加密:

$$ n^{e}\equiv c\pmod N $$

消息解密

利用密钥 $d$ 进行解密。

$$ c^{d}\equiv n\pmod N $$

我们可以知道,RSA公钥主要有两个信息:模数(modulus)和指数(exponent),也就是我们所说的N和e。只要有了这两个信息,我们便可以生成公钥,然后使用rsa库对数据进行加密~

脚本实现如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import rsa

key = rsa.PublicKey(modulus, exponent)
print key

这时候我们有如下的publickey.pem文件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
-----BEGIN PUBLIC KEY-----
MDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhAMJjauXD2OQ/+5erCQKPGqxsC/bNPXDr
yigb/+l/vjDdAgMBAAE=
-----END PUBLIC KEY-----

现在我们需要做的就是从这段字符串中提出模数和指数。

首先我们得知道pem文件是什么?

简单来讲,pem文件这种格式就是用于ASCII(Base64)编码的各种X.509 v3 证书。

文件开始由一行"-----BEGIN PUBLIC KEY-----“开始,由"-----END PUBLIC KEY-----"结束

pem类型的数据除去begin和end之外的内容,要根据base64编码解码后,得到的数据需要进行增加或裁剪特殊字符-、\n、\r、begin信息、end信息等。

这里有张图片很清楚的解释了这个问题~~

既然我们现在已经知道了pem这种文件格式,并且也知道其中的数据内容,我们该如何对这种文件内容进行解密呢?

我们可以做以下尝试Base64解码尝试:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import base64

pubkey = "MDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhAMJjauXD2OQ/+5erCQKPGqxsC/bNPXDr
yigb/+l/vjDdAgMBAAE="
b64_str = base64.b64decode(pubkey)
print b64_str
print len(b64_str)

解码以后如下:

很明显,我们解出来一段乱码,我们尝试把这串乱码转换成16进制,这里我们用的是python自带的binascii库进行解码

发现结尾是"\x01\x00\x01",10001,看多了rsa的公钥,就知道这个数,多半是exponent了。

再看看解码后的长度为162,我们找到偏移表,发现模数的偏移位置是159,长度是3,加起来正好162~

那么说明这段字符串就是指数和模数加密过后的结果,甚至比一般的pem文件中的信息还要简单~

按照这个思路,对照偏移表我们找出指数e和模数N:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# /usr/bin/python
# -*- coding: utf-8 -*-

import base64

def str2key(s):
    # 对字符串解码
    b_str = base64.b64decode(s)

    if len(b_str) < 162:
        return False

    hex_str = ''

    # 按位转换成16进制
    for x in b_str:
        h = hex(ord(x))[2:]
        h = h.rjust(2, '0')
        hex_str += h

    # 找到模数和指数的开头结束位置
    m_start = 29 * 2
    e_start = 159 * 2
    m_len = 128 * 2
    e_len = 3 * 2

    modulus = hex_str[m_start:m_start + m_len]
    exponent = hex_str[e_start:e_start + e_len]

    return modulus,exponent

if __name__ == "__main__":

    pubkey = "MDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhAMJjauXD2OQ/+5erCQKPGqxsC/bNPXDr
yigb/+l/vjDdAgMBAAE="
    key = str2key(pubkey)
    print key

结果如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
('C2636AE5C3D8E43FFB97AB09028F1AAC6C0BF6CD3D70EBCA281BFFE97FBE30DD', '010001')

这个即为我们求出来模数N和指数e。

当然我们也可以用一些比较方便的工具,Kali Linux里面自带了openssl,其他版本的Linux官方也提供了源码安装:https://github.com/openssl/openssl

而在Windows下安装大家可以参考这篇文章:https://bbs.csdn.net/topics/392193545?page=1,当然我还是不建议大家在Windows下进行操作,安装过程相对麻烦,而且可能安装过程中会出现各种状况~~~

我们使用如下命令对pubkey.pem找出指数e和模数N:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
openssl rsa -pubin -text -modulus -in warmup -in pubkey.pem

结果如下:

我们可以得到如下参数:

e=65537 (0x10001)

Modulus即为N=C2636AE5C3D8E43FFB97AB09028F1AAC6C0BF6CD3D70EBCA281BFFE97FBE30DD

然后我们可以使用yafu对n进行因数分解,得到p、q

p=275127860351348928173285174381581152299

q=319576316814478949870590164193048041239

解码网站在这里:https://factordb.com/

至此,各个参数已经求得如下,可以编写代码获得私钥,再用私钥解密密文,得到明文信息~

p = 275127860351348928173285174381581152299

q = 319576316814478949870590164193048041239

N = 87924348264132406875276140514499937145050893665602592992418171647042491658461

e = 65537

我们可以开始用python写脚本了~

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import gmpy2
import rsa

p = 275127860351348928173285174381581152299
q = 319576316814478949870590164193048041239
N = 87924348264132406875276140514499937145050893665602592992418171647042491658461
e = 65537
d = int(gmpy2.invert((e,p - 1) * (q - 1)))
privatekey = rsa.PrivateKey(N,e,d,p,q)
s = open("flag.enc","rb")
print rsa.decrypt(s.read().privatekey).decode()

结果如下:

当然了,我们也可以用之前的公钥对一段信息进行加密操作,具体实现过程如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import rsa
import base64

message = 'Angel_Kitty'
key = ('C2636AE5C3D8E43FFB97AB09028F1AAC6C0BF6CD3D70EBCA281BFFE97FBE30DD', '010001')
modulus = int(key[0], 16)
exponent = int(key[1], 16)
rsa_pubkey = rsa.PublicKey(modulus, exponent)
crypto = rsa.encrypt(message, rsa_pubkey)
b64str = base64.b64encode(crypto)
print b64str

加密结果如下:

这样子我们就得到一个rsa加密,base64编码过的字符串了,我们这个过程主要就是在一串字符串中,对照一个偏移表,提取需要的位置上的数字~~

本文用到的文件我已经上传到本地

点击下载即可:https://files.cnblogs.com/files/ECJTUACM-873284962/RSA公钥文件解密密文的原理分析实例.rar

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

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

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

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
[1249]python实现rsa非对称加密解密
这两种方法都可以实现RSA加密,第一种方法使用了Python的内置模块rsa,而第二种方法使用了第三方库cryptography。请注意,第二种方法需要先安装cryptography库。两种方法的核心思路是相同的,即生成密钥对、加密和解密过程,只是具体的实现细节有所不同。
周小董
2023/12/25
1.6K0
攻防世界Normal_RSA
先进入openssl 输入 rsa -pubin -text -modulus -in warmup -in pubkey.pem 查看信息
babyctfer
2023/12/18
1840
Android RSA 加密
没想到被Android里的RSA加密折腾了几个小时,主要还是自己对RSA加密的原理不了解,然后网上相关的资料也少。 使用AndroidUtilCode工具类中的EncryptUtils.encryptRSA()加密后的数据怎么也不对,后来自己找了段加密代码,才总算是可以了,这里记录一下。
全栈程序员站长
2022/08/29
1.2K0
Android RSA 加密
python实现AES/DES/RSA/MD5/SM2/SM4/3DES加密算法模板汇总
都是作者累积的,且看其珍惜,大家可以尽量可以保存一下,如果转载请写好出处https://www.cnblogs.com/pythonywy
小小咸鱼YwY
2020/11/24
4.9K0
如何使用RSA 对数据加解密和签名验签?一篇文章带你搞定
加密是指利用某个值(密钥)对明文的数据通过一定的算法变换加密(密文)数据的过程,它的逆向过程叫解密。
用户8949263
2022/04/08
5.7K0
如何使用RSA 对数据加解密和签名验签?一篇文章带你搞定
C++ CryptoPP使用RSA加解密
Crypto++ (CryptoPP) 是一个用于密码学和加密的 C++ 库。它是一个开源项目,提供了大量的密码学算法和功能,包括对称加密、非对称加密、哈希函数、消息认证码 (MAC)、数字签名等。Crypto++ 的目标是提供高性能和可靠的密码学工具,以满足软件开发中对安全性的需求。RSA(Rivest-Shamir-Adleman)是一种非对称加密算法,由三位密码学家Ron Rivest、Adi Shamir和Leonard Adleman于1977年共同提出。RSA算法被广泛应用于信息安全领域,特别是在数字签名和密钥交换等场景中。
王瑞MVP
2023/12/01
1.6K0
C++ CryptoPP使用RSA加解密
java与openssl的rsa算法互
说明    1.java生成的公私钥格式为 pkcs8, 而openssl默认生成的公私钥格式为 pkcs1,两者的密钥实际上是不能直接互用的     2.java采用的rsa默认补齐方式是pkcs1, 因此互用的时候需要将openssl中的补齐方式设置为RSA_PKCS1_PADDING     3.rsa加密中,加密数据长度有限制,不能超过密钥长度-11, 如密钥为1024位,则最长的加密数据位117字节; 加密后的密文长度总是为密钥的一半,即1024位的密文为512位 RSA加密常用的填充方式有下
一灰灰blog
2018/02/06
4.2K0
.NET Core 使用RSA算法 加密/解密/签名/验证签名
前言 前不久移植了支付宝官方的SDK,以适用ASP.NET Core使用支付宝支付,但是最近有好几位用户反应在Linux下使用会出错,调试发现是RSA加密的错误,下面具体讲一讲。 RSA在.NET Core的改动 以前我们使用RSA加密主要是使用RSACryptoServiceProvider这个类,在.NET Core中也有这个类,但是这个类并不支持跨平台,所以如果你是用这个类来进行加/解密在windows上运行是完全没有错误的,但是只要你一放到Linux下就会出现异常。 查阅资料得知,要解决这个问题,需
晓晨
2018/06/22
4K0
RSA工具集-openssl,rsatool,RsaCtfTool,RSAtool
用法一:已知公钥(自动求私钥) –publickey,密文 —-uncipherfile。 将文件解压复制到RsaCtfTool里:
小简
2022/12/29
1.9K0
RSA工具集-openssl,rsatool,RsaCtfTool,RSAtool
【愚公系列】2021年12月 攻防世界-简单题-CRYPTO-011(Normal_RSA)
题目描述:你和小鱼走啊走走啊走,走到下一个题目一看你又一愣,怎么还是一个数学题啊 小鱼又一笑,hhhh数学在密码学里面很重要的!现在知道吃亏了吧!你哼一声不服气,我知道数学 很重要了!但是工具也很重要的,你看我拿工具把他解出来!你打开电脑折腾了一会还真的把答案 做了出来,小鱼有些吃惊,向你投过来一个赞叹的目光
愚公搬代码
2021/12/27
4670
【愚公系列】2021年12月 攻防世界-简单题-CRYPTO-011(Normal_RSA)
公钥私钥的那点事儿
生成秘钥参考官网:https://docs.open.alipay.com/291/105971
IT茂茂
2020/03/05
3.8K1
公钥私钥的那点事儿
RSA的公钥私钥
非对称加密使用的是RSA算法,所谓的非对称,指的是,加密时使用的秘钥和解密时使用的秘钥是不一样的。也就是说RSA有一对秘钥,其中一个是公钥,另一个是私钥,一个用于加密,一个用于解密。
赵哥窟
2022/04/02
2.6K0
RSA的公钥私钥
RSA 敏感数据加解密方案
RSA密码是1978年美国麻省理工学院三位密码学者R.L.Rivest、A.Shamir和L.Adleman提出的一种基于大合数因子分解困难性的公开密钥密码。由于RSA密码既可用于加密,又可用于数字签名,通俗易懂,因此RSA密码已成为目前应用最广泛的公开密钥密码。RSA算法是现今使用最广泛的公钥密码算法,也是号称地球上最安全的加密算法。在了解RSA算法之前,先熟悉下几个术语,根据密钥的使用方法,可以将密码分为对称密码和公钥密码。
架构探险之道
2020/08/17
1.3K0
python爬虫以及后端开发--实用加密模板整理
都是作者累积的,且看其珍惜,大家可以尽量可以保存一下,如果转载请写好出处https://www.cnblogs.com/pythonywy
小小咸鱼YwY
2020/08/24
7280
非对称加密的RSA算法如何通过golang来实现?
上一篇文章我们讲了golang实现AES的方式,这里我们来讲一下RSA算法如何通过golang实现。需要注意的是rsa本身不支持大文件的加密,我们需要分段切割进行加解密。下面我们来看下代码。
公众号-利志分享
2022/04/25
6300
RSA der加密 p12解密以及配合AES使用详解
在前面的文章中我有说过AES和RSA这两种加密方式,正好在前段时间再项目中有使用到,在这里再把这两种加密方式综合在一起写一下,具体到他们的使用,以及RSA各种加密文件的生成。
Mr.RisingSun
2019/08/14
2.3K0
RSA der加密 p12解密以及配合AES使用详解
python使用rsa库做公钥解密(网上别处找不到)
  使用RSA公钥解密,用openssl命令就是openssl rsautl -verify -in cipher_text -inkey public.pem -pubin -out clear_text,但其python网上还真没有找到有博文去写,只有hash的rsa解签名。   这里使用rsa库,如果没有可以到官方网址https://pypi.python.org/pypi/rsa/3.1.4下载。   想了想原理,然后到rsa库的python代码里找了找,从verify的代码里提取了出来,又试验了试
窗户
2018/02/07
3.6K0
RSA加解密算法的Java实现
发布者:全栈程序员栈长,转转请注明出处:https://javaforall.cn/100043.html原文链接:
全栈程序员站长
2021/04/13
2.1K0
Golang:加密解密算法
在项目开发过程中,当操作一些用户的隐私信息,诸如密码,帐户密钥等数据时,往往需要加密后可以在网上传输.这时,需要一些高效地,简单易用的加密算法加密数据,然后把加密后的数据存入数据库或进行其他操作;当需要读取数据时,把加密后的数据取出来,再通过算法解密.
OwenZhang
2021/12/08
1.8K0
Golang:加密解密算法
分享几个 Go 语言中使用 RSA 算法对字符串的加密解密的代码片段
使用随机数据生成器random生成一对具有指定字位数的RSA密钥,生成 RSA 的公钥和私钥,并保存至 key 目录中,入参为加密的位数。
耕耘实录
2023/12/19
4030
相关推荐
[1249]python实现rsa非对称加密解密
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验