密码学基础

0x01编码

hex & ascii

img
# ascii
c = input()
print("{}:{}".format(c, ord(c)))
input > f

f:102
# str2hex
def str2hex(str):
    a = ""
    for x in str:
        a += hex(ord(x))
        a = a.replace("0x", "")
        print("a+={}/{} ---> a=0x{}".format(ord(x), hex(ord(x)), a))
    return a.replace("0x", "")

str = input()
byte = bytes(str, 'UTF-8')
print("{} -> 0x{}/0x{} -> (dec){}".format(str, byte.hex(), str2hex(str), int(byte.hex(), 16)))
input > flag

a+=102/0x66 ---> a=0x66
a+=108/0x6c ---> a=0x666c
a+=97/0x61 ---> a=0x666c61
a+=103/0x67 ---> a=0x666c6167
flag -> 0x666c6167/0x666c6167 -> (dec)1718378855
# hex decode
print()
num = 8922333133093133239960474404255406756030333
print("(dec){}->{} ---> {}".format(num,
                                   hex(num),
                                   binascii.unhexlify(hex(num)[2:]).decode('utf-8')))
(dec)8922333133093133239960474404255406756030333->0x666c61677b746869735f69735f666c61677d ---> flag{this_is_flag}

十六进制和字符串之间的相互转化(python3)

str2hex:
#!/usr/bin python3
#-*-coding=utf-8-*-
import binascii

#若传入的是一连串16进制串,可用以下函数
def hex_to_str1(s):	#s="68656c6c6f"
	s=binascii.unhexlify(s) #unhexlify()传入的参数也可以是b'xxxx'(xxxx要符合16进制特征)
	print(s.decode('utf-8')) #s的类型是bytes类型,用encode()方法转化为str类型

#若传入的是用空格隔开的16进制串,可以用一下函数
def hex_to_str2(s): #s="68 65 6c 6c 6f"
    print("".join([chr(i) for i in [int(b,16) for b in s.split(' ')]])) 

hex2str:
#!/usr/bin python3
#-*-coding=utf-8-*-
import binascii

#若传入的是二进制串,可用以下函数
def str_to_hex1(s):	#s=b'hello'
	s=binascii.hexlify(s) #hexlify()传入的参数也可以是b'xxxx'(xxxx要符合16进制特征)
	print(s.decode('utf-8')) #s的类型是bytes类型,用encode()方法转化为str类型

#若传入的是文本串,可以用一下函数
def str_to_hex2(s): #s="hello"
    print("".join([hex(ord(c)).replace('0x','') for c in s]))

python中的字符串前缀

1.字符串前加 u

例子:

u"字符串中有中文"

含义:

前缀u表示该字符串是unicode编码,Python2中用,用在含有中文字符的字符串前,防止因为编码问题,导致中文出现乱码。另外一般要在文件开关标明编码方式采用utf8。

Python3中,所有字符串默认都是unicode字符串。

2.字符串前加 r

例子:

r"\n\t"

含义:

在普通字符串中,反斜线是转义符,代表一些特殊的内容,如换行符\n。

前缀r表示该字符串是原始字符串,即\不是转义符,只是单纯的一个符号。

常用于特殊的字符如换行符、正则表达式、文件路径。

注意不能在原始字符串结尾输入反斜线,否则Python不知道这是一个字符还是换行符(字符串最后用\表示换行),会报错:

SyntaxError: EOL while scanning string literal

那如果是一个文件夹路径就是以\结尾怎么办呢,可以再接一个转义\的字符串:

>>>print r'C:\Program File\my\path''\\'
C:\Program File\my\path\

3.字符串前加 b

例子:

b'<h1>Hello World!</h1>'

含义:

前缀b表示该字符串是bytes类型。

用在Python3中,Python3里默认的str是unicode类。Python2的str本身就是bytes类,所以可不用。

常用在如网络编程中,服务器和浏览器只认bytes类型数据。如:send 函数的参数和 recv 函数的返回值都是 bytes 类型。

在 Python3 中,bytes 和 str 的互相转换方式是

str.encode('utf-8')
bytes.decode('utf-8')

4.字符串前加 f

例子:

>>> account = '测试工程师小站'
>>> month = '30'
>>> f'我的微信公众号是:{account},已经连续发文{int(month) * 5}天啦!'
'我的微信公众号是:测试工程师小站,已经连续发文150天啦!'

含义:

Python3.6新加特性,前缀f用来格式化字符串。可以看出f前缀可以更方便的格式化字符串,比format()方法可读性高且使用方便。

而且加上f前缀后,支持在大括号内,运行Python表达式。

你还可以用fr前缀来表示原生字符串。

urlencode

url编码又叫百分号编码,是统一资源定位(URL)编码方式。URL地址(常说网址)规定了常用地数字,字母可以直接使用,另外一批作为特殊用户字符也可以直接用(/,:@等),剩下的其它所有字符必须通过%xx编码处理。

现在已经成为一种规范了,基本所有程序语言都有这种编码,如js:有encodeURI、encodeURIComponent,PHP有 urlencode、urldecode等。编码方法很简单,在该字节ascii码的的16进制字符前面加%.

如 空格字符,ascii码是32,对应16进制是’20’,那么urlencode编码结果是:%20。

import urllib.parse

print(urllib.parse.quote("flag{this_is_flag}")) # 对字符串进行url编码 unquote()可以解码
data = {
    'name': "email@e.com",
    'flag': "flag{this_is_flag}"
}
print(urllib.parse.urlencode(data)) # urlencode可以对字典模式的键值进行url编码
flag%7Bthis_is_flag%7D
name=email%40e.com&flag=flag%7Bthis_is_flag%7D

base系列

base16 (0-9,A-F)

编码的方式:

1.将数据(根据ASCII编码,UTF-8编码等)转成对应的二进制数,不足8比特位高位补0.然后将所有的二进制全部串起来,4个二进制位为一组,转化成对应十进制数.

2.根据十进制数值找到Base16编码表里面对应的字符.Base16是4个比特位表示一个字符,所以原始是1个字节(8个比特位)刚好可以分成两组,也就是说原先如果使用ASCII编码后的一个字符,现在转化成两个字符.数据量是原先的2倍.

img

样例:

将"ILU"字符串,根据ASCII编码得到对应的二进制,将所有二进制串起来,然后按4个二进制位分割,转化成十进制数值,根据Base16编码表得到编码"494C55",编码后的数据是原先的2倍.

image-20220222135244212
base32 (2-7,A-Z)

与Base16编码区别的是,Base32使用了ASCII编码中可打印的32个字符(大写字母AZ和数字27)对任意字节数据进行编码.Base32将串起来的二进制数据按照5个二进制位分为一组,由于传输数据的单位是字节(即8个二进制位).所以分割之前的二进制位数是40的倍数(40是5和8的最小公倍数).如果不足40位,则在编码后数据补充"=“,一个”="相当于一个组(5个二进制位),编码后的数据是原先的8/5倍.

img

样例:

案例:“ILU"字符串根据Base32编码进行编码,先根据ASCII编码得到对应字符编码值以及对应二进制,将所有二进制串起来,然后按照5个二进制位为一组分割 ,得到十进制值=>找到Base32编码表找到对应的字符.案例总共分割成了5组(25位),还差三组(15位).在末尾补充3个”=“.经过Base32编码后最终值应是"JFGFK===”.

image-20220222135554193
base64 (A-Z,a-z,0-9,+,/)

Base64编码使用了ASCII编码中64个可打印的字符(大写字母AZ,小写字母az,数字0~9以及"+“,”/“)将任意字节数据进行编码.Base64编码将串起来的二进制以6位进行分割.所以分切之前的二进制位数应该是24的倍数(即6,8的最小公倍数).如果不足24位,则在编码后数据后面添加”=“,一个”="想当于6个二进制位.数据量是原先的4/3倍.

img

样例:
“ILU"字符串编码,前面的过程与Base16编码,Base32编码一样,区别是将串起来的二进制按6位分为一组.得到4组(24位).所以末尾不用补充”=“,所以经过Base64编码后的结果是"SUxV”.

image-20220222135829185

除此之外还有 base85 base36 base58 base91 base92 base62

python中的使用
str = "这是flag"
b_str = bytes(str,'utf-8')
print(f"{base64.b16encode(b_str).decode('utf-8')} -> {base64.b16decode(base64.b16encode(b_str)).decode('utf-8')}")
print(f"{base64.b32encode(b_str).decode('utf-8')} -> {base64.b32decode(base64.b32encode(b_str)).decode('utf-8')}")
print(f"{base64.b64encode(b_str).decode('utf-8')} -> {base64.b64decode(base64.b64encode(b_str)).decode('utf-8')}")
E8BF99E698AF666C6167 -> 这是flag
5C7ZTZUYV5TGYYLH -> 这是flag
6L+Z5pivZmxhZw== -> 这是flag

xxencode

XXencode将输入文本以每三个字节为单位进行编码。如果最后剩下的资料少于三个字节,不够的部份用零补齐。这三个字节共有24个Bit,以6bit为单位分为4个组,每个组以十进制来表示所出现的数值只会落在0到63之间。以所对应值的位置字符代替。它所选择的可打印字符是:±0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz,一共64个字符。跟base64打印字符相比,就是UUencode多一个“-” 字符,少一个”/” 字符。

img

源文本: The quick brown fox jumps over the lazy dog

编码后: hJ4VZ653pOKBf647mPrRi64NjS0-eRKpkQm-jRaJm65FcNG-gMLdt64FjNkc+

UUencode

UUencode是一种二进制到文字的编码,最早在unix 邮件系统中使用,全称:Unix-to-Unix encoding,UUencode将输入文本以每三个字节为单位进行编码,如果最后剩下的资料少于三个字节,不够的部份用零补齐。三个字节共有24个Bit,以6-bit为单位分为4个组,每个组以十进制来表示所出现的字节的数值。这个数值只会落在0到63之间。然后将每个数加上32,所产生的结果刚好落在ASCII字符集中可打印字符(32-空白…95-底线)的范围之中。

源文本: The quick brown fox jumps over the lazy dog

编码后: M5&AE('%U:6-K(&)R;W=N(&9O>"!J=6UP<R!O=F5R('1H92!L87IY(&1O9PH*

Escape/Unescape

Escape/Unescape加密解码/编码解码,又叫%u编码,采用UTF-16BE模式, Escape编码/加密,就是字符对应UTF-16 16进制表示方式前面加%u。Unescape解码/解密,就是去掉"%u"后,将16进制字符还原后,由utf-16转码到自己目标字符。如:字符“中”,UTF-16BE是:“6d93”,因此Escape是“%u6d93”。

源文本: The

编码后: %u0054%u0068%u0065

HTML实体编码

img

完整编码手册 参考

敲击码

敲击码(Tap code)是一种以非常简单的方式对文本信息进行编码的方法。因该编码对信息通过使用一系列的点击声音来编码而命名,敲击码是基于5×5方格波利比奥斯方阵来实现的,不同点是是用K字母被整合到C中。

敲击码表:

#!shell
  1  2  3  4  5
1 A  B C/K D  E
2 F  G  H  I  J 
3 L  M  N  O  P
4 Q  R  S  T  U
5 V  W  X  Y  Z

img

摩斯电码

摩尔斯电码(Morse Code)是由美国人萨缪尔·摩尔斯在1836年发明的一种时通时断的且通过不同的排列顺序来表达不同英文字母、数字和标点符号的信号代码,摩尔斯电码主要由以下5种它的代码组成:

  1. 点(.)
  2. 划(-)
  3. 每个字符间短的停顿(通常用空格表示停顿)
  4. 每个词之间中等的停顿(通常用 / 划分)
  5. 以及句子之间长的停顿

摩尔斯电码字母和数字对应表:

#!shell
A  .-    N  -.    .  .-.-.-  +  .-.-.    1  .----
B  -...  O  ---   ,  --..--  _  ..--.-   2  ..---
C  -.-.  P  .--.  :  ---...  $  ...-..-  3  ...--
D  -..   Q  --.-  "  .-..-.  &  .-...    4  ....-
E  .     R  .-.   '  .----.  /  -..-.    5  .....
F  ..-.  S  ...   !  -.-.--              6  -....
G  --.   T  -     ?  ..--..              7  --...
H  ....  U  ..-   @  .--.-.              8  ---..
I  ..    V  ...-  -  -....-              9  ----.
J  .---  W  .--   ;  -.-.-.              0  -----
K  -.-   X  -..-  (  -.--.           
L  .-..  Y  -.--  )  -.--.-          
M  --    Z  --..  =  -...-

源文本: THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG

编码后:

#!shell
- .... . / --.- ..- .. -.-. -.- / -... .-. --- .-- -. / ..-. --- -..- / .--- ..- -- .--. ... / --- ...- . .-. / - .... . / .-.. .- --.. -.-- / -.. --- --.

在线编码解码 传送门

摩尔斯电码除了能对字母数字编码以外还对一些标点符号,非英语字符进行了编码,而且还有一些特定意义的组合称为特殊符号,比如 ·-·-·-·-·- 表达的意思是调用信号,表示“我有消息发送”。如果你感兴趣可以参考 WiKi

杂项

http://www.hiencode.com/

jsfuck,uuencode,morsecode,rabbit,Brainfuck/OoK,Quoted-printable

0x02移位密码

列置换

将一个明文S以固定宽度 m m m按行写出, 得到一个 m × n m\times n m×n的矩阵 M m × n M_{m\times n} Mm×n, 不够的按双方约定的字符补充,比如空格,然后通过某个交换列位置的矩阵 P P_{} P

栅栏密码

栅栏密码(Rail-fence Cipher)就是把要加密的明文分成N个一组,然后把每组的第1个字符组合,每组第2个字符组合…每组的第N(最后一个分组可能不足N个)个字符组合,最后把他们全部连接起来就是密文,这里以2栏栅栏加密为例。

明文: The quick brown fox jumps over the lazy dog

去空格: Thequickbrownfoxjumpsoverthelazydog

分组: Th eq ui ck br ow nf ox ju mp so ve rt he la zy do g

第一组: Teucbonojmsvrhlzdg

第二组: hqikrwfxupoeteayo

密文: Teucbonojmsvrhlzdghqikrwfxupoeteayo

加解密 传送门

曲路密码

曲路密码(Curve Cipher)是一种换位密码,需要事先双方约定密钥(也就是曲路路径)。

明文: The quick brown fox jumps over the lazy dog

填入5行7列表(事先约定填充的行列数)

img

加密的回路线(事先约定填充的行列数)

img

密文: gesfc inpho dtmwu qoury zejre hbxva lookT

0x03替换密码#单表代换

埃特巴什码

埃特巴什码(Atbash Cipher)是一种以字母倒序排列作为特殊密钥的替换加密,也就是下面的对应关系:

ABCDEFGHIJKLMNOPQRSTUVWXYZ
ZYXWVUTSRQPONMLKJIHGFEDCBA

明文: the quick brown fox jumps over the lazy dog

密文: gsv jfrxp yildm ulc qfnkh levi gsv ozab wlt

加解密 传送门

凯撒密码

凯撒密码(Caesar Cipher或称恺撒加密、恺撒变换、变换加密、位移加密)是一种替换加密,明文中的所有字母都在字母表上向后(或向前)按照一个固定数目进行偏移后被替换成密文。例,当偏移量是3的时候,所有的字母A将被替换成D,B变成E,以此类推,更多 参考

加密实例:

明文: The quick brown fox jumps over the lazy dog

偏移量:1

密文: Uif rvjdl cspxo gpy kvnqt pwfs uif mbaz eph

乘法密码

加密过程 E ( A i ) = A j j = i k (   m o d   n ) g c d ( k , n ) = 1 E(A_i)=A_j\quad j=ik(\bmod n) \quad gcd(k,n)=1 E(Ai)=Ajj=ik(modn)gcd(k,n)=1

关 于 g c d ( k , n ) = 1 关于gcd(k,n)=1 gcd(k,n)=1

考 虑 到 j = i k (   m o d   n ) , 如 果 g c d ( k , n ) ≠ 1 , 则 集 合 A = { i k   m o d   n ∣ i < n } ⊊ B = { x ∣ 1 ≤ x < n } 考虑到j=ik(\bmod n),如果gcd(k,n)\ne1,则集合A=\{ ik\bmod n|i<n \} \subsetneq B =\{ x|1\leq x < n \} j=ik(modn)gcd(k,n)=1,A={ikmodni<n}B={x1x<n}

这 意 味 着 明 文 到 密 文 之 间 的 字 符 不 能 构 成 一 一 映 射 这意味着明文到密文之间的字符不能构成一一映射

解密过程

设 明 文 为 P , 加 密 密 钥 为 K , 密 文 为 C , 解 密 密 钥 为 K − 1 : K × K − 1   m o d   n = 1 ( K 的 模 逆 ) 设明文为P,加密密钥为K,密文为C,解密密钥为K^{-1}:K\times K^{-1}\bmod n =1 (K的模逆) P,K,C,K1:K×K1modn=1(K)

因 为 P i × K   m o d   n = C i 因为P_i\times K\bmod n=C_i Pi×Kmodn=Ci

有 K − 1 × C i   m o d   n = K − 1 × K × P i   m o d   n = P i 有K^{-1}\times C_i\bmod n=K^{-1}\times K\times P_i\bmod n = P_i K1×Cimodn=K1×K×Pimodn=Pi

python计算库 gmpy2

仿射密码

加密过程 E ( x ) = ( a x + b )   m o d   n E(x)=(ax+b)\bmod n E(x)=(ax+b)modn

解密过程 D ( x ) = a − 1 ( x − b )   m o d   n ( a a − 1   m o d   n = 1 ) D(x)=a^{-1}(x-b)\bmod n \quad (aa^{-1}\bmod n=1) D(x)=a1(xb)modn(aa1modn=1)

培根密码

培根密码(Baconian Cipher)是一种替换密码,每个明文字母被一个由5字符组成的序列替换,最初的加密方式就是由’A’和’B’组成序列替换明文(所以你当然也可以用别的字母),比如字母’D’替换成"aaabb",以下是全部的对应关系(另一种对于关系是每个字母都有唯一对应序列,I和J与U/V各自都有不同对应序列):

#!shell
A = aaaaa  I/J = abaaa  R = baaaa

B = aaaab  K = abaab    S = baaab

C = aaaba  L = ababa    T = baaba

D = aaabb  M = ababb    U/V = baabb

E = aabaa  N = abbaa    W = babaa

F = aabab  O = abbab    X = babab

G = aabba  P = abbba    Y = babba

H = aabbb  Q = abbbb    Z = babbb

明文: T H E F O X

密文: baaba aabbb aabaa aabab abbab babab

加解密 传送门

ROT5/13/18/47

ROT5/13/18/47是一种简单的码元位置顺序替换暗码。此类编码具有可逆性,可以自我解密,主要用于应对快速浏览,或者是机器的读取。

ROT5 是 rotate by 5 places 的简写,意思是旋转5个位置,其它皆同。下面分别说说它们的编码方式:

ROT5:只对数字进行编码,用当前数字往前数的第5个数字替换当前数字,例如当前为0,编码后变成5,当前为1,编码后变成6,以此类推顺序循环。

ROT13:只对字母进行编码,用当前字母往前数的第13个字母替换当前字母,例如当前为A,编码后变成N,当前为B,编码后变成O,以此类推顺序循环。

ROT18:这是一个异类,本来没有,它是将ROT5和ROT13组合在一起,为了好称呼,将其命名为ROT18。

ROT47:对数字、字母、常用符号进行编码,按照它们的ASCII值进行位置替换,用当前字符ASCII值往前数的第47位对应字符替换当前字符,例如当前为小写字母z,编码后变成大写字母K,当前为数字0,编码后变成符号_。用于ROT47编码的字符其ASCII值范围是33-126,具体可参考ASCII编码,下面以rot13以例。

明文: the quick brown fox jumps over the lazy dog

密文: gur dhvpx oebja sbk whzcf bire gur ynml qbt

传送门

猪圈密码

介绍

猪圈密码(Pigpen Cipher或称九宫格密码、朱高密码、共济会密码或共济会员密码),是一种以格子为基础的简单替代式密码。更多 参考

明文字母和对应密文:

img

明文: THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG

密文:

img

在线加密 传送门

变种

圣堂武士密码(Templar Cipher)是共济会的“猪圈密码”的一个变种,一直被共济会圣殿骑士用。

明文字母和对应密文:

img

其他变种

明文字母和对应密文:

img

明文字母和对应密文:

img

明文字母和对应密文:

img

0x04替换密码#多表代换

维吉尼亚密码

介绍

维吉尼亚密码(Vigenère Cipher)是在单一恺撒密码的基础上扩展出多表代换密码,根据密钥(当密钥长度小于明文长度时可以循环使用)来决定用哪一行的密表来进行替换,以此来对抗字频统计,更多 参考

密表:

img

明文: THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG

密钥(循环使用,密钥越长相对破解难度越大): CULTURE

加密过程:如果第一行为明文字母,第一列为密钥字母,那么明文字母’T’列和密钥字母’C’行的交点就是密文字母’V’,以此类推。

密文: VBP JOZGM VCHQE JQR UNGGW QPPK NYI NUKR XFK

已知密钥加解密
#!python
>>>from pycipher import Vigenere
>>>Vigenere('CULTURE').encipher('THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG')
'VBPJOZGMVCHQEJQRUNGGWQPPKNYINUKRXFK'
>>>Vigenere('CULTURE').decipher('VBPJOZGMVCHQEJQRUNGGWQPPKNYINUKRXFK')
'THEQUICKBROWNFOXJUMPSOVERTHELAZYDOG'

在线加密解密 传送门

未知密钥破解

可以参考 维吉尼亚密码分析 这篇文章,破解维吉尼亚密码第一步是确定密钥长度,维吉尼亚密码分析这篇文章里介绍了使用 重合指数 算法来确定密钥长度,在确定密钥长度后就可以尝试确定密钥,通常我们可以使用 卡方检验 来找到每个字母的偏移量,基于维吉尼亚密码分析一文中的算法实现的工具破解示例。

密文: kiqpbkxspshwehospzqhoinlgapp

解密:

img

(ps:结合左边的值,密钥以及解出明文可以确定kien 5或者klen 10为准确的结果)

明文: DEFEND THE EAST WALL OF THE CASTLE

变种

有几种密码和维吉尼亚密码相似,格罗斯费尔德密码(Gronsfeld cipher)实际上和维吉尼亚密码相同,除了使用了数字来代替字母以外没有什么区别。数字可以选择一种数列,如斐波那契数列,或者一些其他的伪随机序列。格罗斯费尔德密码密码分析过程和维吉尼亚密码大同小异,不过,自动密钥密码不能使用 卡西斯基算法 (kasiski)来破译,因为自动密钥密码的密钥不重复循环使用,破译自动密钥密码最好的方法的就是从密文不断尝试和猜测其中明文或密钥的一部分。

img

#!python
>>>from pycipher import Gronsfeld
>>>Gronsfeld([2,20,11,45,20,43,4]).encipher('THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG')
'VBPJOZGMVCHQEJQRUNGGWQPPKNYINUKRXFK'
>>>Gronsfeld([2,20,11,45,20,43,4]).decipher('VBPJOZGMVCHQEJQRUNGGWQPPKNYINUKRXFK')
'THEQUICKBROWNFOXJUMPSOVERTHELAZYDOG'

在线加解密 传送门

希尔密码

介绍

希尔密码(Hill Cipher)是基于线性代数多重代换密码,由Lester S. Hill在1929年发明。每个字母转换成26进制数字:A=0, B=1, C=2…Z=25一串字母当成n维向量,跟一个n×n的矩阵相乘,再将得出的结果MOD26。更多 参考

加密

明文: ACT

img

明 文 对 应 矩 阵 : ( 0 2 19 ) 加 密 密 钥 : G Y B N Q K U R P 加 密 矩 阵 : ( 6 24 1 13 16 10 20 17 15 ) 明文对应矩阵:\begin{pmatrix}0 \\ 2\\ 19\end{pmatrix} \quad加密密钥:GYBNQKURP \quad加密矩阵:\begin{pmatrix}6 & 24 & 1 \\ 13 & 16 & 10 \\ 20 & 17 & 15 \end{pmatrix} :0219:GYBNQKURP:6132024161711015

( 6 24 1 13 16 10 20 17 15 ) ( 0 2 19 ) = ( 67 222 319 ) ≡ ( 15 14 7 ) ( m o d 2 ) 6 \begin{pmatrix}6 & 24 & 1 \\ 13 & 16 & 10 \\ 20 & 17 & 15\end{pmatrix}\begin{pmatrix}0 \\ 2 \\ 19\end{pmatrix}=\begin{pmatrix}67 \\ 222 \\ 319\end{pmatrix}\equiv\begin{pmatrix}15 \\ 14 \\ 7\end{pmatrix}\pmod26 61320241617110150219=6722231915147(mod2)6

密文: FIN

解密

密文: FIN

计 算 加 密 矩 阵 的 模 26 逆 矩 阵 : ( 6 24 1 13 16 10 20 17 15 ) − 1 ≡ ( 8 5 10 21 8 21 21 12 8 ) (   m o d   26 ) 计算加密矩阵的模26逆矩阵:\begin{pmatrix}6 & 24 & 1 \\ 13 & 16 & 10 \\ 20 & 17 & 15\end{pmatrix}^{-1}\equiv\begin{pmatrix}8 & 5 & 10 \\ 21 & 8 & 21 \\ 21 & 12 & 8\end{pmatrix} (\bmod26) 266132024161711015182121581210218(mod26)

( 8 5 10 21 8 21 21 12 8 ) ( 15 14 7 ) = ( 260 574 539 ) ≡ ( 0 2 19 ) (   m o d   26 ) \begin{pmatrix}8 & 5 & 10 \\ 21 & 8 & 21 \\ 21 & 12 & 8\end{pmatrix}\begin{pmatrix}15 \\ 14 \\ 7\end{pmatrix}=\begin{pmatrix}260 \\ 574 \\ 539\end{pmatrix}\equiv\begin{pmatrix}0 \\ 2 \\ 19\end{pmatrix}(\bmod26) 8212158121021815147=2605745390219(mod26)

明文: ACT

至于证明和求逆可以参考线性代数知识。

破解

密码分析一门破解编码和密码的艺术。当我们尝试去攻破希尔密码你会发现频率分析实际上没有什么用处,特别在密钥长度增多的情况下。对于较长的二元矩阵(2×2的希尔密码)频率分析可能可能会有帮助,但是对于较短的密文分析是没有实际作用的。

这里推荐一篇关于用 已知明文样本攻击的方式破解希尔密码 的文章,基础的希尔密码用 已知明文攻击 的方式是可攻破的,由于加密完全是线性的,所以攻击者在截取到部分明文/密文字符对可以轻松建立一个线性系统,轻松搞定希尔密码,如果不能完全确定线性系统,那么只需要添加部分明文/密文对即可。已知明文攻击时最好的方式去破解写入密码,如果明文一无所知,那就进行推测猜出部分明文。基于已知明文样本攻击的方式破解希尔密码的算法的实现工具破解示例:

密文:

#!shell
XUKEXWSLZJUAXUNKIGWFSOZRAWURORKXAOSLHROBXBTKCMUWDVPTFBLMKEFVWMUXTVTWUIDDJVZKBRMCWOIWYDXMLUFPVSHAGSVWUFWORCWUIDUJCNVTTBERTUNOJUZHVTWKORSVRZSVVFSQXOCMUWPYTRLGBMCYPOJCLRIYTVFCCMUWUFPOXCNMCIWMSKPXEDLYIQKDJWIWCJUMVRCJUMVRKXWURKPSEEIWZVXULEIOETOOFWKBIUXPXUGOWLFPWUSCH

解密:

解密 脚本实例

在线加解密 传送门

Playfair

普莱菲尔密码(Playfair Cipher)是第一种用于实际的双字替换密码,用双字加密取代了简单代换密码的单字加密,很明显这样使得密文更难破译,因为使用简单替换密码的频率分析基本没有什么作用,虽然频率分析,通常仍然可以进行,但是有25×25=625种可能而不是25种可能,可以分为三个步骤,即编制密码表、整理明文、编写译文,下面我们以明文:

THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG 和密钥 CULTURE 为例来讲解。普莱菲尔密码又称为单方密码(Single Cipher)之后又出现它的升级版Double Playfair,也就是 二方密码 (Two-square Cipher),在之后又有四方密码(Four-square Cipher)

编制密码表

1.整理密钥字母 C U L T U R E ,去掉后面重复的字母得到: C U L T R E

2.用上一步得到的字母自上而下来填补5乘5方表的纵列(也可横排),之后的空白按照相同的顺序用字母表中剩余的字母依次填补完整,得到如下的方格:

img

这一步需要注意的要点:整理密钥字母时,如果出现"Z",则需要去除,因为在英文里"Z"的使用频率最低,相应的如果是德文,则需将"I"与"J"当作一个字母来看待,而法语则去掉"W"或"K"。

整理明文

我们要遵循的原则是“两个一组”,得到是若干个两两成对的字母段,用到的是明文 THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG 与字母" X ":

1.将明文两两一组按顺序排开,得到: TH EQ UI CK BR OW NF OX JU MP SO VE RT HE LA ZY DO G

2.对于末尾的单个字母要加上一个" X "使之成对: TH EQ UI CK BR OW NF OX JU MP SO VE RT HE LA ZY DO GX

这一步需要注意的要点:对于相连字母相同者,每个后面都需要加" X ",例如 TOMORROW ,需要写成: TO MO RX RX OW

编写密文

我们要得到的密文,当然,对于每个字母对,要严格遵循如下的原则:

1.如果两个字母在同一行则要用它右邻的字母替换,如果已在最右边,则用该行最左边的替换,如明文为" CE “,依据上表,应替换为” EG ";

2.如果两个字母在同一列则要用它下边的字母替换,如果已在最下边,则用该行最上边的替换,如明文为" OQ “,依据上表,应替换为” PS ";

3.如果两个字母在不同的行或列,则应在密码表中找两个字母使四个字母组成一个矩形,明文占据两个顶点,需用另外两个顶点的字母替换,如明文为" HX “,可以替换为” WI/J “或” I/JW "(下面的例子将按照横向替换原则即同行优先)。

按照上述原则,将明文 TH EQ UI CK BR OW NF OX JU MP SO VE RT HE LA ZY DO GX 加以转换得到 KU ND LH GT LF WU ES PW LH SI/J NP CG CR AG BU VZ QA I/JV (/表示或者,不过一般用I不用J,所以分析密文时你看25个字母都有而只差一个字母没有用到可以考虑一下这种加密方式)将得到的字母改为大写并五个一组列好,得到密文 KUNDL HGTLF WUESP WLHSI NPCGC RAGBU VZQAI V

加密解密 传送门 (ps:这里加解密是横向编制密码表)

加密解密实例(ps:这里加解密也是横向编制密码表):

#!python
>>>from pycipher import Playfair
>>>Playfair('CULTREABDFGHIKMNOPQSVWXYZ').encipher('THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG')
'UKDNLHTGFLWUSEPWHLISNPCGCRGAUBVZAQIV'
>>>Playfair('CULTREABDFGHIKMNOPQSVWXYZ').decipher('UKDNLHTGFLWUSEPWHLISNPCGCRGAUBVZAQIV')
'THEQUICKBROWNFOXIUMPSOVERTHELAZYDOGX'

波利比奥斯方阵密码

介绍

波利比奥斯方阵密码(Polybius Square Cipher或称波利比奥斯棋盘)是棋盘密码的一种,是利用波利比奥斯方阵进行加密的密码方式,简单的来说就是把字母排列好,用坐标(行列)的形式表现出来。字母是密文,明文便是字母的坐标。更多 参考

常见的排布方式:

img

加密实例:

明文: THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG

密文: 442315 4145241325 1242345233 213453 2445323543 442315 31115554 143422

ADFGX和ADFGVX密码

ADFGX密码

ADFGX密码(ADFGX Cipher)是结合了改良过的Polybius方格替代密码与单行换位密码的矩阵加密密码,使用了5个合理的密文字母:A,D,F,G,X,这些字母之所以这样选择是因为当转译成摩尔斯电码(ADFGX密码是德国军队在一战发明使用的密码)不易混淆,目的是尽可能减少转译过程的操作错误。

加密矩阵示例:

#!shell
    A  D  F  G   X
  ----------------
A | p  h  q  g   m 
D | e  a  y  n   o 
F | f  d  x  k   r
G | c  v  s  z   w 
X | b  u  t  i/j l

明文: THE QUICK BROWN FOX

结果矩阵加密:

#!shell
XF AD DA   AF XD XG GA FG   XA FX DX GX DG   FA DX FF

列移位密钥: how are u

img

密文: DXADF AGXF XFFXD FXGGX DGFG AADA ADXXF

已知密钥加解密:

#!python
>>>from pycipher import ADFGX
>>>a = ADFGX('phqgmeaynofdxkrcvszwbutil','HOWAREU')
>>>a.encipher('THE QUICK BROWN FOX')
'DXADFAGXFXFFXDFXGGXDGFGAADAADXXF'
>>>a.decipher('DXADFAGXFXFFXDFXGGXDGFGAADAADXXF')
'THEQUICKBROWNFOX'

在线加解密 传送门

ADFGVX密码

ADFGVX密码实际上就是ADFGX密码的扩充升级版,一样具有ADFGX密码相同的特点,加密过程也类似,不同的是密文字母增加了V,使得可以再使用10数字来替换明文。

#!shell
    A D F G V X
  -------------
A | p h 0 q g 6
D | 4 m e a 1 y
F | l 2 n o f d
G | x k r 3 c v
V | s 5 z w 7 b
X | j 9 u t i 8

由于两种加密过程完全类似这里就不再重复给出加密过程。

#!python
>>>from pycipher import ADFGVX
>>>a = ADFGVX('ph0qg64mea1yl2nofdxkr3cvs5zw7bj9uti8','HOWAREU')
>>>a.encipher('THE QUICK BROWN FOX')
'DXXFAFGFFXGGGFGXDVGDVGFAVFVAFVGG'
>>>a.decipher('DXXFAFGFFXGGGFGXDVGDVGFAVFVAFVGG')
'THEQUICKBROWNFOX'

双密码

双密码

双密码(Bifid Cipher)结合了波利比奥斯方阵换位密码,并采用分级实现扩散,这里的“双”是指用2个密钥进行加密。双密码是由法国Felix Delastelle发明,除此之外Felix Delastelle还发明了三分密码(Trifid Cipher),四方密码(Four-Square Cipher)。还有一个 两方密码 (Two-Square)与四方密码类似, 共轭矩阵双密码 (Conjugated Matrix Bifid Cipher)也是双密码的变种。

示例密阵:

#!shell
   1 2 3 4 5
1| p h q g m
2| e a y l n
3| o f d x k
4| r c v s z
5| w b u t i/j

明文: THE QUICK BROWN FOX

经过密阵转换:

行: 512 15543 54352 333

列: 421 33525 21115 214

分组:

51215 54354 35233 3

42133 52521 11521 4

合并:

#!shell
5121542133 5435452521 3523311521 34

在经过密阵转换后密文: WETED TKZNE KYOME X

已知密阵加解密
#!python
>>>from pycipher import
>>>Bifid('phqgmeaylnofdxkrcvszwbuti',5).encipher('THE QUICK BROWN FOX')
'WETEDTKZNEKYOMEX'
>>>Bifid('phqgmeaylnofdxkrcvszwbuti',5).decipher('WETEDTKZNEKYOMEX')
'THEQUICKBROWNFOX'

在线加解密 传送门

未知密阵破解

手工分析破解双密码是有一定难度的,每个字母都是同过3个数字进行非线性代替转换,而且之后还会对字母顺序进行打乱,这样使双密码比一些替换密码和换位密码更难破解。然而,现在是计算机时代,这张加密方式没有安全性可言,通过 模拟退火 算法就能快速找到双密码的密阵。 这里推荐一篇详细的 双密码破解分析 的文章,基于模拟退火算法实现的工具破解示例:

密文:

#!shell
KWTAZQLAWWZCPONIVBTTBVQUZUGRNHAYIYGIAAYURCUQLDFTYVHTNQEENUPAIFCUNQTNGITEFUSHFDWHRIFSVTBISYDHHASQSROMUEVPQHHCCRBYTQBHWYRRHTEPEKHOBFSZUQBTSYRSQUDCSAOVUUGXOAUYWHPGAYHDNKEZPFKKWRIEHDWPEIOTBKESYETPBPOGTHQSPUMDOVUEQAUPCPFCQHRPHSOPQRSSLPEVWNIQDIOTSQESDHURIEREN

解密:

img

得到加密矩阵:

#!shell
G B C M K
D H U E T
L V Y W I
X O Z S P
N F A R Q

明文:

#!shell
CRYPTANALYS IS OF BIFID BY HAND IS ACTUALLY FAIRLY DIFFICULT THE FRACTIONATING NATURE OF THE CIPHER IE EACH LETTER IS SUBSTITUTED BY CHARACTERS THEN THESE CHARACTERS ARE IUM BLED WHICH WILL PULL THEM APART MAKES THE CIPHER MUCH STRONGER THAN SUBSTITUTION CIPHERS OR TRANSPOSITION CIPHER SON THEIR OWN

三分密码

三分密码(Trifid Cipher)结合换位和替换,三分密码与双密码非常相似,差别之处就是用除了3×3×3的密阵代替5×5密阵。

示例密阵:

#!shell
密阵顺序 = EPSDUCVWYM.ZLKXNBTFGORIJHAQ      

方阵 1      方阵 2      方阵 3                                     
  1 2 3      1 2 3      1 2 3    
1 E P S    1 M . Z    1 F G O    
2 D U C    2 L K X    2 R I J    
3 V W Y    3 N B T    3 H A Q

明文: THE QUICK BROWN FOX.

经过密阵转换:

#!shell
T H E Q U I C K B R O W N F O X .
2 3 1 3 1 3 1 2 2 3 3 1 2 3 3 2 2
3 3 1 3 2 2 2 2 3 2 1 3 3 1 1 2 1
3 1 1 3 2 2 3 2 2 1 3 2 1 1 3 3 2

T(233)表示T在第一个方阵第三行第三列的位置

分组(分组密钥以5为例):

#!shell
THEQU ICKBR OWNFO X.
23131 31223 31233 22
33132 22232 13311 21
31132 23221 32113 32

合并:

#!shell
23131 33132 31132 31223 22232 23221 31233 13311 32113 22 21 32

在经过密阵转换后密文:

#!shell
231313313231132312232223223221312331331132113222132
N  O  O  N  W  G  B  X  X  L  G  H  H  W  S  K  W

想要深入了解三分密码并破解三分密码的小伙伴推荐去看LANIKI教授的一篇密码课程章节的 讲义

四方密码

介绍

四方密码(Four-Square Cipher)是类似普莱菲尔密码双字母加密密码,这样使加密效果强于其他替换密码,因为频率分析变得更加困难了。

四方密码使用4个预先设置的5×5字母矩阵,每个矩阵包括25个字母,通常字母’j’被融入到’i’中(维基百科上说’q’被忽略,不过这不重要,因为’q’和’j’都是很少出现的字母),通常左上和右下矩阵式是标准字母排序明文矩阵,右上和左下矩阵是打乱顺序的密钥矩阵。

示例矩阵:

img

明文: THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG

整理明文(分组不够时用’X’填充): TH EQ UI CK BR OW NF OX JU MP SO VE RT HE LA ZY DO GX

加密过程:分别在明文矩阵中找到’TH’,分别找到他们在右上矩阵有左下矩阵的交点字母’ES’就是密文,以此类推。

密文: ESZWQAFHGTDKWHRKUENYQOLMQTUNWMBPTGHQ

已知密钥矩阵加解密
#!python
>>>from pycipher import Foursquare
>>>fs = Foursquare('zgptfoihmuwdrcnykeqaxvsbl','mfnbdcrhsaxyogvituewlqzkp')
>>>fs.encipher('THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG')
'ESZWQAFHGTDKWHRKUENYQOLMQTUNWMBPTGHQ'
>>>fs.decipher('ESZWQAFHGTDKWHRKUENYQOLMQTUNWMBPTGHQ')
'THEQUICKBROWNFOXJUMPSOVERTHELAZYDOG'

在线加解密 传送门

未知密钥矩阵破解

推荐一篇关于采用 模拟退火算法四方密码分析 文章,如果有足够多的密文那么四方密码可以轻易被破解,如果知道了明文和密文推出密钥是很容易的,猜测部分明文是一个有效的方法去破解四方密码,如果一部分明文已知或者可以被猜测出 那么我们首先要确定尽可能多可利用的密钥,然后才可以进行更多的推测或者用其他的方法破译。基于四方密码分析一文实现的 C代码 破解示例:

密文(密文最好在200个字符以上):

HMMKEQESDTMDHLAWFWMNKSOSFOMRFNLWLKHNSQGGEKXEOLLVDXNRSQQGARTFKSAVNUDLFNDHESPZGQ TWESAGPGSQSQSTPKUSBBQLQHESAGPGSQSQGXLNAVHTPMHMKKNYGSUGDMTPDGFNKYAVHXLWGEKRILESLZ ZOFNAVIHRHRKAGHSMYUGEGNSRGAVMVOQPRLNKRXLMYLQPXILESQYBNRHRKAGKYQXDIHMPGPYOERZOLBEZ LURFWLWUOLDDPNSQYAGMUQPQWESBEZVEQESDTMDBQLWDIUSHB

用法:

#!shell
gcc -O3 -lm foursquarecrack2.c scoreText_2.c -o fsc
./fsc

输出结果:

#!shell
Running foursquarecrack, this could take a few minutes... 
best score so far: -1239.505249, on iteration 1
Key: 'KFMLUGWSQEPOZTNRBHDAVXCIY','UGSVKFIZMOYXPQRWTHLNCABED'     
plaintext: 'THECIPHERTEXTSQUARESCANBEGENERATEDUSINGAKEYWORDDROPPINGDUPLICAT
            ELETTERSTHENFILLTHEREMAININGSPACESWITHTHEREMAININGLETTERSOFTHEA
            LPHABETINORDERALTERNATIVELYTHECIPHERTEXTSQUARESCANBEGENERATEDCO
            MPLETELYRANDOMLYTHEFOURSQUAREALGORITHMALLOWSFORTWOSEPARATEKEYSO
            NEFOREACHOFTHETWOCIPHERTEXTMATRICESX'

自动密钥密码

介绍

自动密钥密码(Autokey Cipher)是多表替换密码,与维吉尼亚密码密切相关,但使用不同的方法生成密钥,通常来说要比维吉尼亚密码更安全。自动密钥密码主要有两种,关键词自动密钥密码和原文自动密钥密码.下面我们以关键词自动密钥为例:

明文: THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG

关键词: CULTURE

自动生成密钥: CULTURE THE QUICK BROWN FOX JUMPS OVER THE

接下来的加密过程和维吉尼亚密码类似,从密表可得:

密文: VBP JOZGD IVEQV HYY AIICX CSNL FWW ZVDP WVK

已知关键词加解密
#!python
>>>from pycipher import Autokey
>>>Autokey('CULTURE').encipher('THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG')
'VBPJOZGDIVEQVHYYAIICXCSNLFWWZVDPWVK'
>>>Autokey('CULTURE').decipher('VBPJOZGDIVEQVHYYAIICXCSNLFWWZVDPWVK')
'THEQUICKBROWNFOXJUMPSOVERTHELAZYDOG'

在线加解密 传送门

未知关键词破解

推荐去看这篇 自动密钥密码分析文章 ,基于文中的算法实现的工具来破解示例。

密文:

#!shell
isjiqymdebvuzrvwhmvysibugzhyinmiyeiklcvioimbninyksmmnjmgalvimlhspjxmgfiraqlhjcpvolqmnyynhpdetoxemgnoxl

解密

img

(ps:从klen 13可以看出使用的关键词为’FORTIFICATION’)

明文:

#!shell
DESPITEBEINGMORESECURETHANTHEVIGENERECIPHERTHEAUTOKEYCIPHERISSTILLVERYEASYTOBREAKUSINGAUTOMATEDMETHODS

将明文转换成可读句子:

despite being more secure than the vigenere cipher the autokey cipher is still very easy to break using automated methods

博福特密码

介绍

博福特密码(Beaufort Cipher),是一种类似于维吉尼亚密码的代换密码,由弗朗西斯·蒲福(Francis Beaufort)发明。它最知名的应用是Hagelin M-209密码机。博福特密码属于对等加密,即加密演算法与解密演算法相同。

明文: THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG

密钥(循环使用,密钥越长相对破解难度越大): CULTURE

加密过程:如果第一行为明文字母,第一列为密文字母,那么沿明文字母’T’列出现密钥字母’C’的行号就是密文字母’J’,以此类推。

密文: JNH DAJCS TUFYE ZOX CZICM OZHC BKA RUMV RDY

已知密钥加解密
#!python
>>>from pycipher import Beaufort
>>>Beaufort('CULTURE').encipher('THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG')
'JNHDAJCSTUFYEZOXCZICMOZHCBKARUMVRDY'
>>>Beaufort('CULTURE').decipher('JNHDAJCSTUFYEZOXCZICMOZHCBKARUMVRDY')
'THEQUICKBROWNFOXJUMPSOVERTHELAZYDOG'

在线加解密 传送门

滚动密钥密码

介绍

滚动密钥密码(Running Key Cipher)和维吉尼亚密码有着相同的加密机制,区别是密钥的选取,维吉尼亚使用的密钥简短,而且重复循环使用,与之相反,滚动密钥密码使用很长的密钥,比如引用一本书作为密钥。这样做的目的是不重复循环使用密钥,使密文更难破译,尽管如此,滚动密钥密码还是可以被攻破,因为有关于密钥和明文的统计分析模式可供利用,如果滚动密钥密码使用统计上的随机密钥来源,那么理论上是不可破译的,因为任何可能都可以成为密钥,并且所有的可能性都是相等的。

明文: THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG

密钥:选取C语言编程(1978版)第63页第1行"errors can occur in several places. A label has…",去掉非字母部分作为密钥(实际选取的密钥很长,长度至少不小于明文长度)。

加密过程:加密过程和维吉尼亚密码加密过程相同

密文: XYV ELAEK OFQYH WWK BYHTJ OGTC TJI DAK YESR

已知密钥在线加解密 传送门

Porta密码

介绍

Porta密码(Porta Cipher)是一个由意大利那不勒斯的医生Giovanni Battista della Porta发明的多表代换密码,Porta密码具有加密解密过程的是相同的特点。

密表:

#!shell
KEYS| A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
----|----------------------------------------------------
A,B | N O P Q R S T U V W X Y Z A B C D E F G H I J K L M
C,D | O P Q R S T U V W X Y Z N M A B C D E F G H I J K L
E,F | P Q R S T U V W X Y Z N O L M A B C D E F G H I J K
G,H | Q R S T U V W X Y Z N O P K L M A B C D E F G H I J
I,J | R S T U V W X Y Z N O P Q J K L M A B C D E F G H I
K,L | S T U V W X Y Z N O P Q R I J K L M A B C D E F G H
M,N | T U V W X Y Z N O P Q R S H I J K L M A B C D E F G
O,P | U V W X Y Z N O P Q R S T G H I J K L M A B C D E F
Q,R | V W X Y Z N O P Q R S T U F G H I J K L M A B C D E
S,T | W X Y Z N O P Q R S T U V E F G H I J K L M A B C D
U,V | X Y Z N O P Q R S T U V W D E F G H I J K L M A B C
W,X | Y Z N O P Q R S T U V W X C D E F G H I J K L M A B
Y,Z | Z N O P Q R S T U V W X Y B C D E F G H I J K L M A

明文: THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG

密钥(循环使用,密钥越长相对破解难度越大): CULTURE

加密过程:明文字母’T’列与密钥字母’C’行交点就是密文字母’F’,以此类推。

密文: FRW HKQRY YMFMF UAA OLWHD ALWI JPT ZXHC NGV

已知密钥在线加解密 传送门

破解

Porta密码可以被以 维吉尼亚密码 破解相类似方式进行自动攻破,破解Porta密码第一步是先确定密钥长度,这里推荐一篇关于使用 重合指数算法 确定为维吉尼亚密钥长度 文章

0x05 RSA

数论基础

欧拉函数(具体讨论)

[]: https://zhuanlan.zhihu.com/p/48249182 “RSA算法原理”

问题引出:任意给定正整数n,请问在小于等于n的正整数之中,有多少个与n构成互质关系?(比如,在1到8之中,有多少个数与8构成互质关系?)

计算这个值的方法就叫做欧拉函数,以φ(n)表示。在1到8之中,与8形成互质关系的是1、3、5、7,所以 φ(n) = 4。

φ(n)的计算方法并不复杂,但是为了得到最后那个公式,需要一步步讨论。

  1. 如果 n = 1 n=1 n=1,则 φ ( 1 ) = 1 φ(1) = 1 φ(1)=1 。因为1与任何数(包括自身)都构成互质关系。

  2. 如果 n n n是质数,则 φ ( n ) = n − 1 φ(n)=n-1 φ(n)=n1 。因为质数与小于它的每一个数,都构成互质关系。比如5与1、2、3、4都构成互质关系。

  3. 如果n是质数的某一个次方,即 n = p k ( p 为 质 数 , k 为 大 于 等 于 1 的 整 数 n = p^k (p为质数,k为大于等于1的整数 n=pk(pk1,则 φ ( n ) = p k − p k − 1 \varphi(n)=p^k-p^{k-1} φ(n)=pkpk1,因为 1 ∼ p k 1\sim p^k 1pk中所有数中,含有因子 p p p的数有 1 × p , 2 × p , 3 × p . . . . p k − 1 × p 1\times p,2\times p,3\times p....p^{k-1}\times p 1×p,2×p,3×p....pk1×p. 上式还可写成 φ ( n ) = p k ( 1 − 1 k ) \varphi(n)=p^k(1-\frac{1}{k}) φ(n)=pk(1k1),可以看出,上面的第二种情况$k=1 $时的特例。

  4. 如果n可以分解成两个互质的整数之积,即 n = p 1 k 1 p 2 k 2 n=p^{k1}_1p^{k2}_2 n=p1k1p2k2,所以 φ ( n ) = φ ( p 1 k 1 p 2 k 2 ) = φ ( p 1 k 1 ) φ ( p 2 k 2 ) \varphi(n)=\varphi(p^{k1}_1p^{k2}_2)=\varphi(p^{k1}_1)\varphi(p^{k2}_2) φ(n)=φ(p1k1p2k2)=φ(p1k1)φ(p2k2),所以 φ ( n ) = p 1 k 1 p 2 k 2 ( 1 − 1 p 1 ) ( 1 − 1 p 2 ) \varphi(n)=p_1^{k1}p_2^{k2}(1-\frac{1}{p_1})(1-\frac{1}{p_2}) φ(n)=p1k1p2k2(1p11)(1p21)

  5. 综上,对于任意n,n可以分解成若干素数的积,即 n = p 1 k 1 p 2 k 2 . . . p r k r n=p_1^{k1}p_2^{k2}...p_r^{kr} n=p1k1p2k2...prkr,所以 φ ( n ) = p 1 k 1 p 2 k 2 . . . p r k r ( 1 − 1 p 1 ) ( 1 − 1 p 2 ) . . . ( 1 − 1 p r ) \varphi(n)=p_1^{k1}p_2^{k2}...p_r^{kr}(1-\frac{1}{p_1})(1-\frac{1}{p_2})...(1-\frac{1}{p_r}) φ(n)=p1k1p2k2...prkr(1p11)(1p21)...(1pr1),所以 φ ( n ) = n ( 1 − 1 p 1 ) ( 1 − 1 p 2 ) . . . ( 1 − 1 p r ) \varphi(n)=n(1-\frac{1}{p_1})(1-\frac{1}{p_2})...(1-\frac{1}{p_r}) φ(n)=n(1p11)(1p21)...(1pr1)

欧拉定理

如果两个正整数a和n互质,则有 a φ ( n ) ≡ 1 ( m o d n ) a^{\varphi(n)}\equiv1\pmod n aφ(n)1(modn)

也就是说, a a a φ ( n ) φ(n) φ(n)次方被 n n n除的余数为1。或者说, a a a φ ( n ) φ(n) φ(n)次方减去1,可以被 n n n整除。比如,3和7互质,而7的欧拉函数φ(7)等于6,所以3的6次方(729)减去1,可以被7整除(728/7=104)。

证明暂略

欧拉定理可以大大简化某些运算。比如,7和10互质,根据欧拉定理
7 φ ( 10 ) ≡ 1 ( m o d 10 ) 7 4 ≡ 1 ( m o d 10 ) 7 4 k ≡ 1 ( m o d 10 ) 7^{\varphi(10)}\equiv1\pmod{10}\\ 7^{4}\equiv1\pmod{10}\\ 7^{4k}\equiv1\pmod{10} 7φ(10)1(mod10)741(mod10)74k1(mod10)
因此,7的任意次方的个位数(例如7的222次方),心算就可以算出来。

欧拉定理有一个特殊情况(费马小定理)。

假设正整数a与质数p互质,因为质数p的φ§等于p-1,

则欧拉定理可以写成 a p − 1 ≡ 1 ( m o d p ) a^{p-1}\equiv1\pmod p ap11(modp),也可以写成 a p ≡ a ( m o d p ) a^p\equiv a\pmod{p} apa(modp)

模反元素

如果两个正整数a和n互质,那么一定可以找到整数b,使得 a b − 1 ab-1 ab1 n n n整除,或者说 a b ab ab n n n除的余数是1。

a b ≡ 1 ( m o d n ) ab\equiv1\pmod{n} ab1(modn)

如上,b称为a的模反元素

比如,3和11互质,那么3的模反元素就是4,因为 (3 × 4)-1 可以被11整除。显然,模反元素不止一个, 4加减11的整数倍都是3的模反元素 {…,-18,-7,4,15,26,…},即如果b是a的模反元素,则 b+kn 都是a的模反元素。

欧拉定理可以用来证明模反元素必然存在。
a φ ( n ) = a a φ ( n − 1 ) ≡ 1 ( m o d n ) a^{\varphi(n)}=aa^{\varphi(n-1)}\equiv1\pmod n aφ(n)=aaφ(n1)1(modn)
可见a的模逆元素就是 a φ ( n − 1 ) a^{\varphi(n-1)} aφ(n1)

拓展欧几里得

设 a , b 是 不 全 为 零 的 整 数 , 则 存 在 整 数 x , y , 使 得 a x + b y = g c d ( a , b ) 设a,b是不全为零的整数,则存在整数x,y,使得ax+by=gcd(a,b) a,b,x,y,使ax+by=gcd(a,b)

求解方程思路

  1. 若 b = 0 , 则 g c d ( a , b ) = a , x = 1 , y = 0 是 一 组 解 若b=0,则gcd(a,b)=a,x=1,y=0是一组解 b=0,gcd(a,b)=a,x=1,y=0

  2. 若 a , b 都 不 等 于 0 若a,b都不等于0 a,b0

    考 虑 到 g c d ( a , b ) = g c d ( b , a % b ) , a % b = a − ⌊ a b ⌋ b 考虑到gcd(a,b)=gcd(b,a\%b),\quad a\%b=a-\lfloor\frac{a}{b}\rfloor b gcd(a,b)=gcd(b,a%b),a%b=abab

    所 以 a x 1 + b y 1 = g c d ( a , b ) = g c d ( b , a % b ) = b x 2 + ( a − ⌊ a b ⌋ b ) y 2 所以ax_1+by_1=gcd(a,b)=gcd(b,a\%b)=bx_2+(a-\lfloor\frac{a}{b}\rfloor b)y_2 ax1+by1=gcd(a,b)=gcd(b,a%b)=bx2+(abab)y2

    所 以 a x 1 + b y 1 = a y 2 + b ( x 2 − ⌊ a b ⌋ y 2 ) 所以ax_1+by_1=ay_2+b(x_2-\lfloor\frac{a}{b}\rfloor y_2) ax1+by1=ay2+b(x2bay2)

    所 以 x 1 = y 2 , y 1 = x 2 − ⌊ a b ⌋ y 2 所以x_1=y_2,\quad y_1=x_2-\lfloor\frac{a}{b}\rfloor y_2 x1=y2,y1=x2bay2

    递归进行上述计算

中国剩余定理

Chinese Remainder Theorem,CRT

考虑如下一元线性同余方程组:
{ x ≡ a 1 ( m o d n 1 ) x ≡ a 2 ( m o d n 2 ) x ≡ a 3 ( m o d n 3 ) ⋯ x ≡ a k ( m o d n k ) 其 中 ( n 1 , n 2 … n k 两 两 互 质 ) \begin{cases} x\equiv a_1\pmod {n_1}\\ x\equiv a_2\pmod {n_2}\\ x\equiv a_3\pmod {n_3}\\ \cdots\\ x\equiv a_k\pmod {n_k}\\ \end{cases} \quad 其中(n_1,n_2\ldots n_k两两互质) xa1(modn1)xa2(modn2)xa3(modn3)xak(modnk)(n1,n2nk)

证明

观 察 如 下 一 组 x i { x 1 ≡ 1 ( m o d n 1 ) x 1 ≡ 0 ( m o d n 2 ) ⋯ x 1 ≡ 0 ( m o d n k ) { x 2 ≡ 0 ( m o d n 1 ) x 2 ≡ 1 ( m o d n 2 ) ⋯ x 2 ≡ 0 ( m o d n k ) … { x k ≡ 0 ( m o d n 1 ) x k ≡ 0 ( m o d n 2 ) ⋯ x k ≡ 1 ( m o d n k ) 显 然 有 x = a 1 x 1 + a 2 x 2 + … + a k x k 满 足 原 方 程 组 设 M = ∏ i = 1 k n i 显 然 x i 能 被 n 1 , n 2 . . . n k ( 除 了 n i ) 整 除 又 因 为 n 1 , n 2 … n k 两 两 互 质 设 m i = M n i , 所 以 x i 能 被 m i 整 除 , 有 x i = t m i 又 因 为 x i = t m i ≡ 1 ( m o d n i ) 所 以 t m i + s n i = 1 ( t 其 实 是 x i 模 n i 的 模 逆 m i − 1 ) 根 据 拓 展 欧 几 里 得 定 理 , s , t 有 解 , 所 以 x i 有 解 , x 有 解 观察如下一组x_i\\ \begin{cases} x_1\equiv 1\pmod {n_1}\\ x_1\equiv 0\pmod {n_2}\\ \cdots\\ x_1\equiv 0\pmod {n_k}\\ \end{cases} \begin{cases} x_2\equiv 0\pmod {n_1}\\ x_2\equiv 1\pmod {n_2}\\ \cdots\\ x_2\equiv 0\pmod {n_k}\\ \end{cases} \ldots \begin{cases} x_k\equiv 0\pmod {n_1}\\ x_k\equiv 0\pmod {n_2}\\ \cdots\\ x_k\equiv 1\pmod {n_k}\\ \end{cases}\\ 显然有 x=a_1x_1+a_2x_2+\ldots+a_kx_k 满足原方程组\\ 设M=\prod_{i=1}^k n_i\\ 显然x_i能被n_1,n_2...n_k(除了n_i)整除\\ 又因为n_1,n_2\ldots n_k两两互质\\ 设m_i=\frac{M}{n_i}, 所以x_i能被m_i整除,有x_i=tm_i\\ 又因为x_i=tm_i\equiv 1\pmod {n_i}\\ 所以tm_i+sn_i=1 (t其实是x_i模n_i的模逆m_i^{-1})\\ 根据拓展欧几里得定理,s,t有解,所以x_i有解,x有解 xix11(modn1)x10(modn2)x10(modnk)x20(modn1)x21(modn2)x20(modnk)xk0(modn1)xk0(modn2)xk1(modnk)x=a1x1+a2x2++akxkM=i=1knixin1,n2...nk(ni)n1,n2nkmi=niM,ximi,xi=tmixi=tmi1(modni)tmi+sni=1(txinimi1),s,t,xi,x

求解算法
  1. 计 算 M = ∏ i = 1 k n i 计算M=\prod_{i=1}^kn_i M=i=1kni

  2. 对 于 x i 对于x_i xi
    2.1 计 算 m i = M n i 计算m_i=\frac{M}{n_i} mi=niM

    2.2 计 算 m i − 1 ( m i 在 模 n i 下 的 模 逆 ) 计算m_i^{-1} (m_i在模n_i下的模逆) mi1(mini)

    2.3 计 算 c i = m i m i − 1 ( 不 对 n i 取 模 ) 计算c_i=m_im_{i}^{-1} (不对n_i取模) ci=mimi1(ni)

  3. x = ∑ i = 1 k x i c i ( m o d n ) x=\sum_{i=1}^{k}x_ic_i\pmod n x=i=1kxici(modn)

python代码
# Python Version
def CRT(k, a, r):
    n = 1; ans = 0
    for i in range(1, k + 1):
        n = n * r[i]
    for i in range(1, k + 1):
        m = n // r[i]; b = y = 0
        exgcd(m, r[i], b, y) # b * m mod r[i] = 1
        ans = (ans + a[i] * m * b % mod) % mod
    return (ans % mod + mod) % mod

RSA流程

密钥生成

  1. 随机选取两个不相等的质数p,q

    比如61和53

  2. 计算p和q的乘积n

    n=61*53=3233,n的长度就是密钥长度。3233写成二进制是110010100001,一共有12位,所以这个密钥就是12位。实际应用中,RSA密钥一般是1024位,重要场合则为2048位。

  3. 计算n的欧拉函数 φ ( n ) \varphi(n) φ(n)

    因为p,q是质数,所以 φ ( n ) = φ ( p q ) = φ ( p ) φ ( q ) \varphi(n)=\varphi(pq)=\varphi(p)\varphi(q) φ(n)=φ(pq)=φ(p)φ(q)

    φ ( 3233 ) φ(3233) φ(3233)等于60×52,即3120。

  4. 随机一个整数e,满足 1 < e < φ ( n ) 且 e 与 φ ( n ) 互 质 1<e<\varphi(n) \quad且e与\varphi(n)互质 1<e<φ(n)eφ(n)

    比如选择17

  5. 计算e对于 φ ( n ) \varphi(n) φ(n)的模反元素d
    e d ≡ 1 ( m o d ( φ ( n ) ) 等 价 于 e d − 1 = k φ ( n ) 即 求 解 关 于 d , k 的 二 元 方 程 e d + φ ( n ) k = 1 即 e x + φ ( n ) y = 1 e = 17 , φ ( n ) = 3120 得 出 一 组 解 为 ( 2753 , − 15 ) 即 d = 2753 ed\equiv1\pmod{(\varphi(n)}\\ 等价于\quad ed-1=k\varphi(n)\\ 即求解关于d,k的二元方程\quad \\ ed+\varphi(n)k=1\\ 即ex+\varphi(n)y=1\\ e=17,\varphi(n)=3120\\ 得出一组解为(2753,-15)\quad 即d=2753 ed1(mod(φ(n))ed1=kφ(n)d,ked+φ(n)k=1ex+φ(n)y=1e=17φ(n)=3120(2753,15)d=2753

  6. 封装密钥

    综上, 公钥为 ( 3233 , 17 ) (3233,17) (3233,17),私钥为 ( 3233 , 2753 ) (3233,2753) (3233,2753)

RSA的可靠性

对于外界来说, p q n φ ( n ) e d p \quad q\quad n\quad \varphi(n)\quad e\quad d pqnφ(n)ed 这六个参数中,只有 n n n e e e是可见的, d d d作为私钥,也是最关键的

那么,有无可能在已知n和e的情况下,推导出d?

1) e d ≡ 1 ( m o d φ ( n ) ) ed≡1 (mod φ(n)) ed1(modφ(n)) 只有知道 e e e φ ( n ) φ(n) φ(n),才能算出 d d d
2) φ ( n ) = ( p − 1 ) ( q − 1 ) φ(n)=(p-1)(q-1) φ(n)=(p1)(q1)。只有知道 p p p q q q,才能算出 φ ( n ) φ(n) φ(n)
3) n = p q n=pq n=pq。只有将 n n n因数分解,才能算出 p p p q q q

结论:如果n可以被因数分解,d就可以算出,也就意味着私钥被破解。

可是,大整数的因数分解,是一件非常困难的事情。目前,除了暴力破解,还没有发现别的有效方法。维基百科这样写道:

“对极大整数做因数分解的难度决定了RSA算法的可靠性。换言之,对一极大整数做因数分解愈困难,RSA算法愈可靠。
假如有人找到一种快速因数分解的算法,那么RSA的可靠性就会极度下降。但找到这样的算法的可能性是非常小的。今天只有短的RSA密钥才可能被暴力破解。到2008年为止,世界上还没有任何可靠的攻击RSA算法的方式。
只要密钥长度足够长,用RSA加密的信息实际上是不能被解破的。”

RSA算法的加解密

加密: 使用公钥(n,e)

假设鲍勃要向爱丽丝发送加密信息m,他就要用爱丽丝的公钥 (n,e) 对m进行加密。这里需要注意,m必须是整数(字符串可以取ascii值或unicode值),且m必须小于n。

所谓”加密”,就是算出下式的c:

m e ≡ c ( m o d n ) m^e ≡ c \pmod n mec(modn)

爱丽丝的公钥是 (3233, 17),鲍勃的m假设是65,那么可以算出下面的等式:

6 5 17 ≡ 2790 ( m o d 3233 ) 65^{17} ≡ 2790 \pmod {3233} 65172790(mod3233)

于是,c等于2790,鲍勃就把2790发给了爱丽丝。

解密要用私钥(n,d)

爱丽丝拿到鲍勃发来的2790以后,就用自己的私钥(3233, 2753) 进行解密。可以证明,下面的等式一定成立:

c d ≡ m ( m o d n ) cd ≡ m \pmod n cdm(modn)

也就是说,c的d次方除以n的余数为m。现在,c等于2790,私钥是(3233, 2753),那么,爱丽丝算出

279 0 2753 ≡ 65 ( m o d 3233 ) 2790^{2753} ≡ 65 \pmod {3233} 2790275365(mod3233)

因此,爱丽丝知道了鲍勃加密前的原文就是65。

至此,”加密–解密”的整个过程全部完成。

我们可以看到,如果不知道d,就没有办法从c求出m。而前面已经说过,要知道d就必须分解n,这是极难做到的,所以RSA算法保证了通信安全。

你可能会问,公钥(n,e) 只能加密小于n的整数m,那么如果要加密大于n的整数,该怎么办?有两种解决方法:一种是把长信息分割成若干段短消息,每段分别加密;另一种是先选择一种”对称性加密算法”(比如DES),用这种算法的密钥加密信息,再用RSA公钥加密DES密钥。

私钥解密的证明

c d ≡ m ( m o d n ) c^d\equiv m\pmod n cdm(modn)

证明过程:
首 先 m e ≡ c ( m o d n ) 所 以 有 c + k n = m e c = m e − k n 代 入 原 式 有 ( m e − k n ) d ≡ m ( m o d n ) 观 察 得 , 左 式 中 含 有 k n 得 项 都 能 被 n 整 除 所 以 等 价 于 证 明 m e d ≡ m ( m o d n ) 考 虑 到 e d ≡ t φ ( n ) + 1 所 以 即 证 m t φ ( n ) + 1 ≡ m ( m o d n ) 首先\quad m^e\equiv c\pmod n\\ 所以有\quad c+kn=m^e\\c=m^e-kn\\ 代入原式有\quad (m^e-kn)^d\equiv m\pmod n\\ 观察得, 左式中含有kn得项都能被n整除\\ 所以等价于证明\quad m^{ed}\equiv m\pmod n\\ 考虑到\quad ed\equiv t\varphi(n)+1\\ 所以即证 m^{t\varphi(n)+1}\equiv m\pmod n mec(modn)c+kn=mec=mekn(mekn)dm(modn),knnmedm(modn)edtφ(n)+1mtφ(n)+1m(modn)
接下来有两种情况:

  1. m与n互质

因 为 m φ ( n ) ≡ 1 ( m o d n ) 所 以 m t φ ( n ) ≡ 1 ( m o d n ) 所 以 m t φ ( n ) + 1 ≡ m ( m o d n ) 因为 m^{\varphi(n)}\equiv 1\pmod n\\ 所以 m^{t\varphi(n)}\equiv 1\pmod n\\ 所以 m^{t\varphi(n)+1}\equiv m\pmod n mφ(n)1(modn)mtφ(n)1(modn)mtφ(n)+1m(modn)

  1. m与n不互质

n = p × q , 所 以 g c d ( m , n ) = p 或 者 g c d ( m , n ) = q 假 设 m = r × p , 那 么 此 时 m 与 q 必 互 质 且 m < n 根 据 费 马 小 定 理 m q − 1 = 1 ( m o d q ) ( m q − 1 ) t ( p − 1 ) ≡ 1 ( m o d q ) 因 为 ( p − 1 ) ( q − 1 ) = φ ( n ) 所 以 m t φ ( n ) ≡ 1 ( m o d q ) 所 以 m e d − 1 ≡ 1 ( m o d q ) 所 以 m e d − 1 = s q + 1 m e d = s q m + m 因 为 假 设 m = r p , 所 以 m e d = r s p q + m m e d = r s n + m 即 m e d ≡ m ( m o d n ) 得 证 n=p\times q,所以gcd(m,n)=p或者gcd(m,n)=q\\ 假设m=r\times p, 那么此时m与q必互质且m<n\\ 根据费马小定理\\ m^{q-1}=1\pmod q\\ (m^{q-1})^{t(p-1)}\equiv 1\pmod q\\ 因为(p-1)(q-1)=\varphi(n)\\ 所以m^{t\varphi(n)}\equiv 1\pmod q\\ 所以m^{ed-1}\equiv 1\pmod q\\ 所以m^{ed-1}=sq+1\\ m^{ed}=sqm+m\\ 因为假设m=rp,所以m^{ed}=rspq+m\\ m^{ed}=rsn+m\\ 即m^{ed}\equiv m\pmod n\\ 得证 n=p×qgcd(m,n)=pgcd(m,n)=qm=r×p,mqm<nmq1=1(modq)(mq1)t(p1)1(modq)(p1)(q1)=φ(n)mtφ(n)1(modq)med11(modq)med1=sq+1med=sqm+mm=rp,med=rspq+mmed=rsn+mmedm(modn)

RSA攻击

https://www.tr0y.wang/2017/11/06/CTFRSA/#%E7%AE%80%E5%8D%95%E4%BB%8B%E7%BB%8D

大整数分解

http://factordb.com/

https://www.sagemath.org/

msieve

共模攻击

n n n不变的情况下,知道 n , e 1 , e 2 ( e 1 , e 2 互 质 ) , c 1 , c 2 n,e_1,e_2(e_1,e_2互质),c_1,c_2 n,e1,e2(e1,e2),c1,c2可以在不知道 d 1 , d 2 d_1,d_2 d1,d2的情况下解出 m m m
g c d ( e 1 , e 2 ) = 1 e 1 s 1 + e 2 s 2 = g c d ( e 1 , e 2 ) = 1 c 1 = m e 1 % n c 2 = m e 2 % n 所 以 c 1 s 1 c 2 s 2 % n = ( ( m e 1 % n ) s 1 × ( m e 2 % n ) s 2 ) % n = ( m 1 e 1 s 1 + e 2 s 2 ) % n = m gcd(e_1,e_2)=1 \\ e_1s_1+e_2s_2=gcd(e_1,e_2)=1\\ c_1=m^{e_1} \% n\\ c_2=m^{e_2} \% n\\ 所以 c_1^{s_1}c_2^{s_2}\%n=((m^{e_1}\%n)^{s_1}\times (m^{e_2}\%n)^{s_2})\%n\\ =(m_1^{e_1s_1+e_2s_2})\%n\\ =m gcd(e1,e2)=1e1s1+e2s2=gcd(e1,e2)=1c1=me1%nc2=me2%nc1s1c2s2%n=((me1%n)s1×(me2%n)s2)%n=(m1e1s1+e2s2)%n=m
所以问题的关键点在于如何计算 s 1 , s 2 s_1,s_2 s1,s2,即之前提到过的拓展欧几里得算法

注意

考虑到 s 2 s_2 s2是负数,那么模运算中处理 c 2 s 2   m o d   n c_2^{s2}\bmod n c2s2modn时,应该先计算 c 2 c_2 c2关于 n n n的模逆元素 c 2 r c_{2r} c2r,然后计算 c 2 r − s 2 c_{2r}^{-s_2} c2rs2

已知p+q或者p-q

求 解 方 程 组 { p × q = m p + q = a 求解方程组\begin{cases} p \times q= m\\ p + q = a \end{cases} {p×q=mp+q=a

已知e,d分解n

e d ≡ 1   m o d   n e d = 1 + k φ ( n ) 枚 举 k 可 以 解 出 φ ( n ) 问 题 转 化 为 已 知 φ ( n ) , 求 n φ ( n ) = ( p − 1 ) ( q − 1 ) = p q − ( p + q ) + 1 = n − ( p + q ) + 1 解 方 程 { p + q = n − φ ( n ) + 1 p × q = n ed\equiv1\bmod n\\ ed=1+k\varphi(n)\\ 枚举k可以解出\varphi(n)\\ 问题转化为已知\varphi(n),求n\\ \begin{aligned} \varphi(n) & = (p-1)(q-1)\\ & = pq-(p+q)+1\\ & = n-(p+q)+1\\ \end{aligned} \\ 解方程\begin{cases} p+q=n-\varphi(n)+1\\ p\times q=n \end{cases} ed1modned=1+kφ(n)kφ(n)φ(n),nφ(n)=(p1)(q1)=pq(p+q)+1=n(p+q)+1{p+q=nφ(n)+1p×q=n

Coppersmith 定理攻击

coppersmith 定理指出在一个 e 阶的 mod n 多项式 f(x)中,如果有一个根小于 n 1 e n^\frac{1}{e} ne1,就可以运用一个 O(log n)的算法求出这些根。

这个定理可以应用于 RSA 算法。如果 e = 3 并且在明文当中只有三分之二的比特是已知的,这种算法可以求出明文中所有的比特。

听上去很简单,但是会涉及到格这个东西,还有个 LLL 算法。经过查找,发现 sage 里有相关的库。。等闲下来用 python 实现一遍

sage 是基于 Python 的一个科学运算,很强大,这里可以在线运行

有空详细说吧,先放着

低加密指数攻击

在 RSA 中 e 也称为加密指数。由于 e 是可以随意选取的,选取小一点的 e 可以缩短加密时间(比如 3),但是选取不当的话,就会造成安全问题

c ≡ m e   m o d   n c\equiv m^e\bmod n cmemodn

如果 m e < n m^e<n me<n,那么有 c = m e , m = c e c=m^e, m=\sqrt[e]{c} c=me,m=ec

如果 m e ≫̸ n m^e\not\gg n men,那么有 c = m e + k n c=m^e+kn c=me+kn,可以爆破 k k k,寻找能开整数 e e e次根式的 c − k n c-kn ckn, 有 m = c − k n e m=\sqrt[e]{c-kn} m=eckn

低加密指数广播攻击

如果选取的加密指数较低,并且使用了相同的加密指数给一个接受者的群发送相同的信息,那么可以进行广播攻击得到明文。选取了相同的加密指数 e(这里取 e=3),对相同的明文 m 进行了加密并进行了消息的传递,那么有:
c 1 = m e   m o d   n 1 → m e = c 1 + k n 1 c 2 = m e   m o d   n 2 → m e = c 2 + k n 2 c 3 = m e   m o d   n 3 → m e = c 3 + k n 3 即 { x ≡ c 1 m o d    n 1 x ≡ c 2 m o d    n 2 x ≡ c 3 m o d    n 3 . . . x ≡ c k m o d    n k c_1=m^e\bmod n_1 \rightarrow m^e=c_1+kn_1\\ c_2=m^e\bmod n_2 \rightarrow m^e=c_2+kn_2\\ c_3=m^e\bmod n_3 \rightarrow m^e=c_3+kn_3\\ 即\begin{cases} x\equiv c_1\mod n_1\\ x\equiv c_2\mod n_2\\ x\equiv c_3\mod n_3\\ ...\\ x\equiv c_k\mod n_k \end{cases} c1=memodn1me=c1+kn1c2=memodn2me=c2+kn2c3=memodn3me=c3+kn3xc1modn1xc2modn2xc3modn3...xckmodnk
通过欧几里得算法求出 x x x,即 m e m^e me,然后开e次方根即可

低解密指数攻击

若 d 满 足 : d < 1 3 n 1 4 若d满足:d<\frac{1}{3}n^{\frac{1}{4}} d:d<31n41

那么一种基于连分数(一个数论当中的问题)的特殊攻击类型就可以危害 RSA 的安全。此时需要满足:

q < p < 2 q q<p<2q q<p<2q

如果满足上述条件,通过 Wiener Attack 可以在多项式时间中分解 n,思路如下:

回想一下 RSA:

n = p q , φ ( n ) = ( p − 1 ) ( q − 1 ) = p q − ( p + q ) + 1 = n − ( p + q ) + 1 n=pq,\varphi(n)=(p-1)(q-1)=pq-(p+q)+1=n-(p+q)+1 n=pq,φ(n)=(p1)(q1)=pq(p+q)+1=n(p+q)+1

$因为p,q非常大,所以pq\gg p+q, 所以\varphi(n)\approx n $

因 为 e d ≡ 1   m o d   φ ( n ) , 所 以 e d − 1 = k φ ( n ) , 两 边 同 除 d φ ( n ) 因为ed\equiv 1\bmod \varphi(n),所以ed-1=k\varphi(n),两边同除d\varphi(n) ed1modφ(n),ed1=kφ(n),dφ(n)

得 e φ ( n ) − k d = 1 d φ ( n ) → e n − k d = 1 d φ ( n ) 得\frac{e}{\varphi(n)}-\frac{k}{d}=\frac{1}{d\varphi(n)} \rightarrow\frac{e}{n}-\frac{k}{d}=\frac{1}{d\varphi(n)} φ(n)edk=dφ(n)1nedk=dφ(n)1

同样因为 d φ ( n ) d\varphi(n) dφ(n)是个很大的数,所以 e N 略 大 于 k d \frac{e}{N}略大于\frac{k}{d} Nedk

为啥要这么写呢,因为 e 和 n 是我们是知道的,公钥中给我们的,所以我们计算出 e n \frac{e}{n} ne后,比它略小的 k d \frac{k}{d} dk怎么出来呢,计算 e n \frac{e}{n} ne的连分数展开,依次算出这个分数每一个渐进分数,由于 e n \frac{e}{n} ne略大于 k d \frac{k}{d} dk,wiener 证明了,该攻击能精确的覆盖 k d \frac{k}{d} dk(论文刚不动,只知道结论)

连分数的例子

在这里插入图片描述

那么e/N的依次每个渐进分数

在这里插入图片描述
算法过程:
  1. 通过对 e n \frac{e}{n} ne进行连分数展开
  2. 然后依次求其渐进分数
  3. 遍历所有渐进分数如果找到了 d d d的话, ( e d − 1 ) (ed-1) (ed1)会整除 φ ( n ) \varphi(n) φ(n),也就是存在 k k k使得 e ∗ d − 1 = k φ ( n ) e*d-1=k\varphi(n) ed1=kφ(n),建立方程求 p , q p,q p,q x 2 − ( p + q ) x + p q = 0 x^2−(p+q)x+pq=0 x2(p+q)x+pq=0这个方程的解就是p,q)如果 p q = = n pq==n pq==n则找到了d
# -*- coding: cp936 -*-
import gmpy2
import time

# 展开为连分数
def continuedFra(x, y):
    cF = []
    while y:
        cF += [x / y]
        x, y = y, x % y
    return cF

def Simplify(ctnf):
    numerator = 0
    denominator = 1
    for x in ctnf[::-1]:
        numerator, denominator = denominator, x * denominator + numerator
    return (numerator, denominator)

# 连分数化简
def calculateFrac(x, y):
    cF = continuedFra(x, y)
    cF = map(Simplify, (cF[0:i] for i in xrange(1, len(cF))))
    return cF

# 解韦达定理
def solve_pq(a, b, c):
    par = gmpy2.isqrt(b * b - 4 * a * c)
    return (-b + par) / (2 * a), (-b - par) / (2 * a)

def wienerAttack(e, n):
    for (d, k) in calculateFrac(e, n):
        if k == 0: continue
        if (e * d - 1) % k != 0: continue

        phi = (e * d - 1) / k
        p, q = solve_pq(1, n - phi + 1, n)
        if p * q == n:
            return abs(int(p)), abs(int(q))
    print 'not find!'

time.clock()
n = 12238605063252292170613110607692779326628090745751955692266649177882959231822580682548279800443278979485092243645806337103841086023159482786712759291169541633901936290854044069486201989034158882661270017305064348254800318759062921744741432214818915527537124001063995865927527037625277330117588414586505635959411443039463168463608235165929831344586283875119363703480280602514451713723663297066810128769907278246434745483846869482536367912810637275405943566734099622063142293421936734750356828712268385319217225803602442033960930413469179550331907541244416573641309943913383658451409219852933526106735587605884499707827
e = 11850552481503020257392808424743510851763548184936536180317707155841959788151862976445957810691568475609821000653594584717037528429828330763571556164988619635320288125983463358648887090031957900011546300841211712664477474767941406651977784177969001025954167441377912326806132232375497798238928464025466905201977180541053129691501120197010080001677260814313906843670652972019631997467352264392296894192998971542816081534808106792758008676039929763345402657578681818891775091140555977382868531202964486261123748663752490909455324860302967636149379567988941803701512680099398021640317868259975961261408500449965277690517
c = 9472193174575536616954091686751964873836697237500198884451530469300324470671555310791335185133679697207007374620225900775502162690848135615431624557389304657410880981454777737587420426091879654002644281066474715074536611611252677882396384453641127487515845176069574754606670518031472235144795376526854484442135299818868525539923568705203042265537204111153151119105287648912908771710419648445826883069030285651763726003413418764301988228077415599665616637501056116290476861280240577145515875430665394216054222788697052979429015400411487342877096677666406389711074591330476335174211990429870900468249946600544116793793
p, q = wienerAttack(e, n)

print '[+]Found!'
print '  [-]p =',p
print '  [-]q =',q
print '  [-]n =',p*q
d = gmpy2.invert(e,(p-1)*(q-1))
print '  [-]d =', d
print '  [-]m is:' + '{:x}'.format(pow(c,d,n)).decode('hex')
print '\n[!]Timer:', round(time.clock(),2), 's'
print '[!]All Done!'

0x06词频分析

http://quipqiup.com/

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Dan Boneh 是一位著名的密码学家和计算机科学家,他开设的密码学基础课程被广泛认为是学习密码学的理想选择。 在 Boneh 的密码学基础课程中,学生将学习密码学的基本概念、原则和技术。课程内容涵盖了对称加密、公钥加密、哈希函数、数字签名等关键密码学算法和协议的深入讲解。 在课程开始的阶段,Boneh 会简要介绍密码学的历史背景和基本概念,然后逐步引入重要的密码学算法。学生将学习如何使用对称加密算法来保护数据的机密性,如何使用公钥加密算法来实现安全的通信,以及如何使用哈希函数来验证数据的完整性。 此外,课程还将涵盖一些高级密码学主题,如数字签名和零知识证明等。学生将学习如何使用数字签名算法来验证数据的身份和完整性,以及如何使用零知识证明来实现安全的认证和身份验证。 Boneh 的密码学基础课程注重理论与实践相结合,学生将有机会参与编写和分析密码学算法的代码。通过实践,学生将更深入地理解密码学的核心概念和实际应用。 总而言之,Dan Boneh 的密码学基础课程是一门全面且深入的密码学课程,能够帮助学生建立扎实的密码学基础,为深入研究密码学或从事密码学相关工作打下坚实的基础。毫无疑问,这是一门高品质的密码学课程,值得推荐给对密码学感兴趣的学生和从业人员。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值