0%

RSA-BASE64-AES

Base64编码详解:

这么几个月了,最近做了好多题,也有好多很隐蔽的base64,所以有必要深刻的了解一下base64的编码原理了。

一、base64编码规则:

第一步,将待转换的字符串每三个字节分为一组,每个字节占8bit,那么共有24个二进制位。
第二步,将上面的24个二进制位每6个一组,共分为4组。
第三步,在每组前面添加两个0,每组由6个变为8个二进制位,总共32个二进制位,即四个字节。
第四步,根据Base64编码对照表(见下图)获得对应的值。

就是先转换成二进制,分6分切开,再在前面补两个0,变成9位,算索引,找表即可。

第一步:“M”、“a”、”n”对应的ASCII码值分别为77,97,110,对应的二进制值是01001101、01100001、01101110。如图第二三行所示,由此组成一个24位的二进制字符串。
第二步:如图红色框,将24位每6位二进制位一组分成四组。
第三步:在上面每一组前面补两个0,扩展成32个二进制位,此时变为四个字节:00010011、00010110、00000101、00101110。分别对应的值(Base64编码索引)为:19、22、5、46。
第四步:用上面的值在Base64编码表中进行查找,分别对应:T、W、F、u。因此“Man”Base64编码之后就变为:TWFu。

那么有时候会出现“==”是什么情况呢?

二、base64的补位

当只有一个字符时,不足24位,那么后面就需要补0,不存在的位就需要” = “来取代。

上图很好的表示了补位。

三、base58,base32,base16

base64是切成6份,base32是切成5份,同理base16切成4份。

base58编码方式显然是不一样的,采用辗转相除:

如要将1234转换为58进制;

第一步:1234除于58,商21,余数为16,查表得H

第二步:21除于58,商0,余数为21,查表得N

所以得到base58编码为:NH

四、代码表示

base64的C语言的代码有很明显的特征,我们只需要找到“ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/”字符串即可,有时候又会变表,那么我们给出一个python变表脚本:

1
2
3
4
5
6
7
8
9
10
11
12
import base64
t1="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
t2='nopqrstuvwxyzabcdefghijklm0123456789ABCDEFGHIJKL+/MNOPQRSTUVWXYZ'
data="OBufaa21Td86rWS8Wob8iGhZYocbr5vxZfcCoWv3"
result = ''
flag=""
for ch in data:
result += t1[t2.index(ch)]
result = bytearray(base64.b64decode(result+"=="))
for i in range(len(result)):
flag+=chr(result[i])
print(flag)

RSA详细介绍:

在极客的时候做了好几道RSA的题,现在来详细介绍一下。

RSA是一种非对称加密。

一、生成密钥过程

首先选择两个不相等的质数,分别为p和q,然后算出pq为n,n就是密钥长度。计算欧拉函数,如果n是质数,则 φ(n)=n-1,所以φ(3233) = φ(61x53) = φ(61)φ(53)=60x52=3120。接下来选择一个整数e,且e与φ(n)互质。然后计算模反元素,所谓“模反元素”就是指有一个整数d,可以使得ed除以φ(n)的余数为1,公式表示:ed*≡1(*m**odφ*(n)),即*edkφ(n)=1,所以公钥是(n,e)**,私钥*(n,d)**,则公钥可以发布,私钥自己留着。

二、反解密钥过程

直接给出脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
from gmpy2 import*
from libnum import*
from Crypto.Util.number import long_to_bytes
import gmpy2
n=103461035900816914121390101299049044413950405173712170434161686539878160984549
c=0xad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35
e=65537
p=366669102002966856876605669837014229419
q=282164587459512124844245113950593348271
phi=(p-1)*(q-1)
d=gmpy2.invert(e,phi)
flag=pow(c,int(d),n)
print(n2s(flag))

AES详细介绍:

是一种常见的对称加密方式:加密和解密用到的密钥是相同的,这种加密方式加密速度非常快,适合经常发送数据的场合。缺点是密钥的传输比较麻烦。AES加密由明文,密钥,加密函数,密文,AES解密函数组成。加密函数是将明文和密钥作为参数传进函数中的,

一、加密

AES为分组密码,分组密码也就是把明文分成一组一组的,每组长度相等,每次加密一组数据,直到加密完整个明文。在AES标准规范中,分组长度只能是128位,也就是说,每个分组为16个字节(每个字节8位)。

假设这里使用128位的密钥,加密10轮

设P位明文,我们知道明文是16个字节,我们将这16个字节搞成4×4的矩阵,矩阵的排列顺序为从上到下、从左至右。再将明文矩阵换成对应ascii码成为状态矩阵.

密钥的加密是不一样的

128位密钥也是用字节为单位的矩阵表示,矩阵的每一列被称为1个32位比特字。通过密钥编排函数该密钥矩阵被扩展成一个44个字组成的序列W[0],W[1], … ,W[43],该序列的前4个元素W[0],W[1],W[2],W[3]是原始密钥,用于加密运算中的初始密钥加(下面介绍);后面40个字分为10组,每组4个字(128比特)分别用于10轮加密运算中的轮密钥加,如下图所示:

AES加密分为4个步骤:字节代换、行位移、列混合和轮密钥加

1、字节代换

AES字节代换是一个查表的操作。AES定义了一个S盒和逆S盒。

S盒是一个16×16的表格,我们怎么进行查取呢,一个字节是8位,我们取高4位作为行值,低4位作为列值,按照表格进行查询,然后替换。

2、行移位

行移位是一个简单的左循环移位操作。当密钥长度为128比特时,状态矩阵的第0行左移0字节,第1行左移1字节,第2行左移2字节,第3行左移3字节,如下图所示:

3、列混合

列混合的操作是通过矩阵相乘实现,但乘法实际上是异或

4、轮密钥加

使用P和密钥进行异或,以列位单位,对应位置异或,对应下标相等异或。

二、密钥扩展

我们知道密钥总共存在44列,前4列是我们给出的16位密钥分成的4列,那么后面40列每4列是经过一轮AES函数所搞出来的

这个44矩阵的每一列的4个字节组成一个字,矩阵4列的4个字依次命名为W[0]、W[1]、W[2]和W[3],它们构成一个以字为单位的数组W。例如,设密钥K为”abcdefghijklmnop”,则K0 = ‘a’,K1 = ‘b’, K2 = ‘c’,K3 = ‘d’,W[0] = “abcd”。
接着,对W数组扩充40个新列,构成总共44列的扩展密钥数组。新列以如下的递归方式产生:
1.如果i不是4的倍数,那么第i列由如下等式确定:
W[i]=W[i-4]⨁W[i-1]
2.如果i是4的倍数,那么第i列由如下等式确定:
W[i]=W[i-4]⨁T(W[i-1])
其中,T是一个有点复杂的函数。
函数T由3部分组成:字循环、字节代换和轮常量异或,这3部分的作用分别如下。
a.字循环:将1个字中的4个字节循环左移1个字节。即将输入字[b0, b1, b2, b3]变换成[b1,b2,b3,b0]。
b.字节代换:对字循环的结果使用S盒进行字节代换。
c.轮常量异或:将前两步的结果同轮常量Rcon[j]进行异或,其中j表示轮数。
轮常量Rcon[j]是一个字,其值见下表。

下面举个例子:
设初始的128位密钥为:
3C A1 0B 21 57 F0 19 16 90 2E 13 80 AC C1 07 BD
那么4个初始值为:
W[0] = 3C A1 0B 21
W[1] = 57 F0 19 16
W[2] = 90 2E 13 80
W[3] = AC C1 07 BD
下面求扩展的第1轮的子密钥(W[4],W[5],W[6],W[7])。
由于4是4的倍数,所以:
W[4] = W[0] ⨁ T(W[3])
T(W[3])的计算步骤如下:

循环地将W[3]的元素移位:AC C1 07 BD变成C1 07 BD AC;
将 C1 07 BD AC 作为S盒的输入,输出为78 C5 7A 91;
将78 C5 7A 91与第一轮轮常量Rcon[1]进行异或运算,将得到79 C5 7A 91,因此,T(W[3])=79 C5 7A 91,故
W[4] = 3C A1 0B 21 ⨁ 79 C5 7A 91 = 45 64 71 B0
其余的3个子密钥段的计算如下:
W[5] = W[1] ⨁ W[4] = 57 F0 19 16 ⨁ 45 64 71 B0 = 12 94 68 A6
W[6] = W[2] ⨁ W[5] =90 2E 13 80 ⨁ 12 94 68 A6 = 82 BA 7B 26
W[7] = W[3] ⨁ W[6] = AC C1 07 BD ⨁ 82 BA 7B 26 = 2E 7B 7C 9B
所以,第一轮的密钥为 45 64 71 B0 12 94 68 A6 82 BA 7B 26 2E 7B 7C 9B。

三、解密

1、字节代换

查逆S盒

2、行移位

行移位的逆变换是将状态矩阵中的每一行执行相反的移位操作,例如AES-128中,状态矩阵的第0行右移0字节,第1行右移1字节,第2行右移2字节,第3行右移3字节。

3、列混合

左乘的为逆变换矩阵,逆变换矩阵与变换矩阵乘积为单位矩阵

4、轮密钥加

轮密钥加的逆运算同正向的轮密钥加运算完全一致