RSA公钥文件解密密文的原理分析
前言
最近在学习RSA加解密过程中遇到一个这样的难题:假设已知publickey公钥文件和加密后的密文flag,如何对其密文进行解密,转换成明文~~
分析
对于rsa算法的公钥与私钥的产生,我们可以了解到以下产生原理:
公钥与私钥的产生
- 随机选择两个不同大质数 $p$ 和 $q$,计算 $N = p \times q$
- 根据欧拉函数,求得 $r=\varphi (N)=\varphi (p)\varphi (q)=(p-1)(q-1)$
- 选择一个小于 $r$ 的整数 $e$,使 $e$ 和 $r$ 互质。并求得 $e$ 关于 $r$ 的模反元素,命名为 $d$,有 $ed\equiv 1 \pmod r$
- 将 $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库对数据进行加密~
脚本实现如下:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import rsa key = rsa.PublicKey(modulus, exponent)
print key
这时候我们有如下的publickey.pem文件:
-----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解码尝试:
#!/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:
# /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, '')
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
结果如下:
('C2636AE5C3D8E43FFB97AB09028F1AAC6C0BF6CD3D70EBCA281BFFE97FBE30DD', '')
这个即为我们求出来模数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:
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写脚本了~
#!/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()
结果如下:

当然了,我们也可以用之前的公钥对一段信息进行加密操作,具体实现过程如下:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import rsa
import base64 message = 'Angel_Kitty'
key = ('C2636AE5C3D8E43FFB97AB09028F1AAC6C0BF6CD3D70EBCA281BFFE97FBE30DD', '')
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


RSA公钥文件解密密文的原理分析的更多相关文章
- Python rsa公私钥生成 rsa公钥加解密(分段加解密)-私钥加签验签实战
一般现在的SAAS服务提供现在的sdk或api对接服务都涉及到一个身份验证和数据加密的问题.一般现在普遍的做法就是配置使用非对称加密的方式来解决这个问题,你持有SAAS公司的公钥,SAAS公司持有你的 ...
- 【论文阅读笔记】-针对RSA的短解密指数的密码学分析(Cryptanalysis of Short RSA Secret Exponents)
目录 1. 介绍 polynomially larger 2. 连分数背景知识 3. 连分数算法 4. 连分数算法在RSA中的应用 5. 例子 6. 对RSA连分数攻击的反制 7. 对于攻击的改进 8 ...
- Windows 下使用OpenSSL生成RSA公钥和私钥
Windows 下使用OpenSSL生成RSA公钥和私钥 (1)下载OpenSSL 可到该地址下载OpenSSL: https://www.openssl.org/source/(https://ww ...
- 通过公钥解密密文思路(256bits RSA)
256bit RSA公钥安全系数极低,只需要几分钟即可破解密文,本文综合其他文章记录了一次解密256bits RSA加密的密文的过程,仅作为备忘. 1.分解公钥,分解出n与e: 1.1使用openss ...
- 非对称加密技术- RSA算法数学原理分析
非对称加密技术,在现在网络中,有非常广泛应用.加密技术更是数字货币的基础. 所谓非对称,就是指该算法需要一对密钥,使用其中一个(公钥)加密,则需要用另一个(私钥)才能解密. 但是对于其原理大部分同学应 ...
- RSA加密、解密、签名、验签的原理及方法
一.RSA加密简介 RSA加密是一种非对称加密.可以在不直接传递密钥的情况下,完成解密.这能够确保信息的安全性,避免了直接传递密钥所造成的被破解的风险.是由一对密钥来进行加解密的过程,分别称为公钥和私 ...
- RSA签名,加解密处理核心文件
import java.io.ByteArrayOutputStream; import java.io.UnsupportedEncodingException; import java.secur ...
- PHP中使用OpenSSL生成RSA公钥私钥及进行加密解密示例(非对称加密)
php服务端与客户端交互.提供开放api时,通常需要对敏感的部分api数据传输进行数据加密,这时候rsa非对称加密就能派上用处了,下面通过一个例子来说明如何用php来实现数据的加密解密 先了解一下关于 ...
- rsa公钥和私钥到底哪个才是用来加密,哪个用来解密?
本文转自:91博客:原文地址:http://www.9191boke.com/138589019.html 公钥和私钥在一些银行系统.第三方支付系统SDK中经常会遇到,刚接触公钥私钥的朋友们估计很难区 ...
随机推荐
- MSSQL清理所有用户数据库日志(SQLSERVER2008)
USE [master]; SET NOCOUNT ON; )=''; )=''; DECLARE @clearSql VARCHAR(MAX)=''; ; ,),TMP_WHILE_FLAG, T. ...
- Vue延迟点击
从点击屏幕上的元素到触发元素的 click 事件,移动浏览器会有大约 300 毫秒的等待时间 fastclick清除点击延迟,让程序更灵敏 1.导出fastclick import Vue from ...
- IntelliJ IDEA 2017 永久注册方法
https://blog.csdn.net/weixin_39913200/article/details/80859897 在安装的idea下面的bin目录下面有2个文件 : 一个是idea64.e ...
- 转:日志插件 log4net 的使用
文本格式说明 可以记载的日志类别包括:FATAL(致命错误).ERROR(一般错误).WARN(警告).INFO(一般信息).DEBUG(调试信息). 文本参数说明 %m(message):输出的日志 ...
- 高通移植mipi LCD的过程LK代码
lk部分:(实现LCD兼容) 1. 函数定位 aboot_init()来到target_display_init(): 这就是高通原生lk LCD 兼容的关键所在.至于你需要兼容多少LCD 就在whi ...
- 路由交换02-----ARP协议
路由交换协议-----ARP ARP协议 ARP(Address Resolution Protocol),是根据IP地址获取MAC地址的一个TCP/IP协议,即将IP地址对应到物理地址,从而实现数据 ...
- swift的调用约定
swift的静态绑定 Swift Calling Convention @convention(swift) func foo(_ x:Int, y:Int) sil @foo : $(x:Int, ...
- IOS - 执行时 (经常使用函数)
能够通过NSObject的一些方法获取运行时信息或动态运行一些消息: /*Returns a Boolean value that indicates whether the receiving cl ...
- 数据挖掘十大算法--K-均值聚类算法
一.相异度计算 在正式讨论聚类前,我们要先弄清楚一个问题:怎样定量计算两个可比較元素间的相异度.用通俗的话说.相异度就是两个东西区别有多大.比如人类与章鱼的相异度明显大于人类与黑猩猩的相异度,这是能 ...
- go标准库的学习-encoding/base64
参考:https://studygolang.com/pkgdoc 导入方式: import "encoding/base64" base64实现了RFC 4648规定的base6 ...