大小端存储问题
对于一个由2个字节组成的16位整数,在内存中存储这两个字节有两种方法:一种是将低序字节存储在起始地址,这称为小端(little-endian)字节序;另一种方法是将高序字节存储在起始地址,这称为大端(big-endian)字节序。
假如现有一32位int型数0x12345678,那么其MSB(Most Significant Byte,最高有效字节)为0x12,其LSB (Least Significant Byte,最低有效字节)为0x78,在CPU内存中有两种存放方式:(假设从地址0x4000开始存放)
也就是说:大端是高字节存放到内存的低地址,小端是高字节存放到内存的高地址。
例:
from libnum import*
import struct
import binascii
s = [72143238992041641000000.000000,77135357178006504000000000000000.000000,1125868345616435400000000.000000,67378029765916820000000.000000,75553486092184703000000000000.000000,4397611913739958700000.000000,76209378028621039000000000000000.000000]
a = ''
b = ''
for i in s:
i = float(i)
a += struct.pack('<f',i).hex() #小端
print(a)
for j in s:
i = float(i)
b += struct.pack('>f',i).hex() #小端
print(b)
a = 0x496e74657265737472696e67204964656120746f20656e6372797074
b = 0x74707972747079727470797274707972747079727470797274707972
print(n2s(a))
print(n2s(b))
DH密钥交换
Diffie–Hellman(以下简称DH)密钥交换是一个特殊的交换密钥的方法。它是密码学领域内最早付诸实践的密钥交换方法之一。DH可以让双方在完全缺乏对方(私有)信息的前提条件下通过不安全的信道达成一个共享的密钥。此密钥用于对后续信息交换进行对称加密。
安全依据:计算离散对数(Discrete Logarithm Problem,DLP)的困难程度
方案原理:Alice和Bob想共有一个密钥,用于对称加密。但是他们之间的通信渠道是不安全的。所有经过此渠道的信息均会被敌对方:Eve看到。哪他们要如何交换信息,才能不让Eve知道这个密钥呢?
方案要求:q是一个很大的素数(如1024bit),而且(q-1)/2也是个素数。
Alice,Bob在不安全的信道建立相同的密钥:
Alice选择一个底数g,素数p,随机数a,
计算A=ga mod p,发送g,A,p给Bob
Bob选择一个随机数b,
计算B=gb mod p,将B发送给Alice,同时计算Ab mod p作为密钥k
Alice再计算Bamodp作为密钥k,那么最终密钥是相同的。
如果想直接破解就是离散对数问题,但是DH密钥交换难以抵御中间人攻击。
将a,A看作Alice的私钥和公钥,b,B看作Bob的私钥和公钥。
MT19937
加密算法
#! coding: utf-8
class MersenneTwister:
__n = 624
__m = 397
__a = 0x9908b0df
__b = 0x9d2c5680
__c = 0xefc60000
__kInitOperand = 0x6c078965
__kMaxBits = 0xffffffff
__kUpperBits = 0x80000000
__kLowerBits = 0x7fffffff
def __init__(self, seed = 0):
self.__register = [0] * self.__n
self.__state = 0
self.__register[0] = seed
for i in range(1, self.__n):
prev = self.__register[i - 1]
temp = self.__kInitOperand * (prev ^ (prev >> 30)) + i
self.__register[i] = temp & self.__kMaxBits
def __twister(self):
for i in range(self.__n):
y = (self.__register[i] & self.__kUpperBits) + \
(self.__register[(i + 1) % self.__n] & self.__kLowerBits)
self.__register[i] = self.__register[(i + self.__m) % self.__n] ^ (y >> 1)
if y % 2:
self.__register[i] ^= self.__a
return None
def __temper(self):
if self.__state == 0:
self.__twister()
y = self.__register[self.__state]
y = y ^ (y >> 11)
y = y ^ (y << 7) & self.__b
y = y ^ (y << 15) & self.__c
y = y ^ (y >> 18)
self.__state = (self.__state + 1) % self.__n
return y
def __call__(self):
return self.__temper()
def load_register(self, register):
self.__state = 0
self.__register = register
if __name__ == "__main__":
mt = MersenneTwister(0)
tank = set()
kLen = 100
for i in range(kLen):
t = mt()
tank.add(t)
print(t)
print(len(tank) == kLen)
爆破:
class TemperInverser:
__b = 0x9d2c5680
__c = 0xefc60000
__kMaxBits = 0xffffffff
def __inverse_right_shift_xor(self, value, shift):
i, result = 0, 0
while i * shift < 32:
part_mask = ((self.__kMaxBits << (32 - shift)) & self.__kMaxBits) >> (i * shift)
part = value & part_mask
value ^= part >> shift
result |= part
i += 1
return result
def __inverse_left_shift_xor(self, value, shift, mask):
i, result = 0, 0
while i * shift < 32:
part_mask = (self.__kMaxBits >> (32 - shift)) << (i * shift)
part = value & part_mask
value ^= (part << shift) & mask
result |= part
i += 1
return result
def __inverse_temper(self, tempered):
value = tempered
value = self.__inverse_right_shift_xor(value, 18)
value = self.__inverse_left_shift_xor(value, 15, self.__c)
value = self.__inverse_left_shift_xor(value, 7, self.__b)
value = self.__inverse_right_shift_xor(value, 11)
return value
def __call__(self, tempered):
return self.__inverse_temper(tempered)
class MersenneTwisterCracker:
__n = 624
def __init__(self, mt_obj):
inverser = TemperInverser()
register = [inverser(mt_obj()) for i in range(self.__n)]
self.__mt = MersenneTwister(0)
self.__mt.load_register(register)
def __call__(self):
return self.__mt()
if __name__ == "__main__":
mt = MersenneTwister(0)
for i in range(100):
mt()
mtc = MersenneTwisterCracker(mt)
for i in range(100):
assert(mt() == mtc())
Base加密
str="JASGBWcQPRXEFLbCDIlmnHUVKTYZdMovwipatNOefghq56rs****kxyz012789+/"
ciper="MyLkTaP3FaA7KOWjTmKkVjWjVzKjdeNvTnAjoH9iZOIvTeHbVD"#(==没有用)
import string
import binascii
for i in string.ascii_letters+string.digits:
if i not in str:
print(i)
import itertools
s=['3','4','j','u']
for i in itertools.permutations(s,4):
ss="JASGBWcQPRXEFLbCDIlmnHUVKTYZdMovwipatNOefghq56rs"+"".join(i)+"kxyz012789+/"
bins = ""
for j in ciper:
bins+=bin(ss.index(j))[2:].zfill(6)
print(binascii.unhexlify(hex(eval("0b"+bins))[2:-1]))
Base隐写
#!/usr/bin/python
from Crypto.Util.number import*
import base64
c = b'VEhJUz==\nRkxBR3==\nSVN=\nSElEREVOLo==\nQ0FO\nWU9V\nRklORM==\nSVT=\nT1VUP4==\nRE8=\nWU9V\nS05PV9==\nQkFTRTY0P5==\nWW91bmdD\nVEhJTku=\nWU9V\nQVJF\nTk9U\nVEhBVE==\nRkFNSUxJQVI=\nV0lUSO==\nQkFTRTY0Lh==\nQmFzZTY0\naXO=\nYW==\nZ3JvdXA=\nb2b=\nc2ltaWxhcn==\nYmluYXJ5LXRvLXRleHR=\nZW5jb2Rpbme=\nc2NoZW1lc0==\ndGhhdD==\ncmVwcmVzZW50\nYmluYXJ5\nZGF0YW==\naW5=\nYW6=\nQVNDSUl=\nc3RyaW5n\nZm9ybWF0\nYnk=\ndHJhbnNsYXRpbmd=\naXS=\naW50b1==\nYT==\ncmFkaXgtNjQ=\ncmVwcmVzZW50YXRpb24u\nVGhl\ndGVybc==\nQmFzZTY0\nb3JpZ2luYXRlc8==\nZnJvbd==\nYY==\nc3BlY2lmaWN=\nTUlNRT==\nY29udGVudI==\ndHJhbnNmZXI=\nZW5jb2Rpbmcu\nVGhl\ncGFydGljdWxhct==\nc2V0\nb2b=\nNjR=\nY2hhcmFjdGVyc5==\nY2hvc2Vu\ndG+=\ncmVwcmVzZW50\ndGhl\nNjQ=\ncGxhY2UtdmFsdWVz\nZm9y\ndGhl\nYmFzZd==\ndmFyaWVz\nYmV0d2Vlbt==\naW1wbGVtZW50YXRpb25zLp==\nVGhl\nZ2VuZXJhbI==\nc3RyYXRlZ3n=\naXO=\ndG9=\nY2hvb3Nl\nNjR=\nY2hhcmFjdGVyc5==\ndGhhdA==\nYXJl\nYm90aN==\nbWVtYmVyc5==\nb2a=\nYS==\nc3Vic2V0\nY29tbW9u\ndG8=\nbW9zdM==\nZW5jb2RpbmdzLA==\nYW5k\nYWxzb8==\ncHJpbnRhYmxlLg==\nVGhpc9==\nY29tYmluYXRpb25=\nbGVhdmVz\ndGhl\nZGF0YW==\ndW5saWtlbHk=\ndG/=\nYmV=\nbW9kaWZpZWS=\naW5=\ndHJhbnNpdE==\ndGhyb3VnaN==\naW5mb3JtYXRpb26=\nc3lzdGVtcyw=\nc3VjaN==\nYXM=\nRS1tYWlsLD==\ndGhhdA==\nd2VyZQ==\ndHJhZGl0aW9uYWxseQ==\nbm90\nOC1iaXQ=\nY2xlYW4uWzFd\nRm9y\nZXhhbXBsZSw=\nTUlNRSdz\nQmFzZTY0\naW1wbGVtZW50YXRpb24=\ndXNlcw==\nQahDWiw=\nYahDeiw=\nYW5k\nMKhDOQ==\nZm9y\ndGhl\nZmlyc3Q=\nNjI=\ndmFsdWVzLg==\nT3RoZXI=\ndmFyaWF0aW9ucw==\nc2hhcmU=\ndGhpcw==\ncHJvcGVydHk=\nYnV0\nZGlmZmVy\naW4=\ndGhl\nc3ltYm9scw==\nY2hvc2Vu\nZm9y\ndGhl\nbGFzdA==\ndHdv\ndmFsdWVzOw==\nYW4=\nZXhhbXBsZQ==\naXM=\nVVRGLTcu'
def get_base64_diff_value(s1, s2):
base64chars = b'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
res = 0
for i in range(len(s2)):
if s1[i] != s2[i]:
return abs(base64chars.index(s1[i]) - base64chars.index(s2[i]))
return res
def solve_stego():
line=b''
bin_str=''
for i in c:
k=long_to_bytes(i)
if k==b'\n':
steg_line = line
norm_line = base64.b64encode(base64.b64decode(line))
diff = get_base64_diff_value(steg_line, norm_line)
#print(diff)
pads_num = steg_line.count(b'=')
if diff:
bin_str += bin(diff)[2:].zfill(pads_num * 2)
else:
bin_str += '0' * pads_num * 2
print(goflag(bin_str))
line=b''
continue
line+=k
def goflag(bin_str):
res_str = ''
for i in range(0, len(bin_str), 8):
res_str += chr(int(bin_str[i:i + 8], 2))
return res_str
if __name__ == '__main__':
solve_stego()
bytes与str转换
from Crypto.Util.number import *
print(long_to_bytes(m))
print(bytes_to_long(m))
八进制转ASCII码
b=list(input().split(' '))
for i in b:
print(chr(int(i,base=8)),end='')
解方程
import sympy
# 首先定义 `x`为一个符号,代表一个未知数
x = sympy.Symbol('x')
# 解方程:x - 1 = 0
sympy.solve(x - 1,x)
#Out: [1]
# 解方程:x ^ 2 - 1 = 0
sympy.solve(x ** 2 - 1,x)
#Out: [-1, 1]
# 解方程:x ^ 2 + 1 = 0
sympy.solve(x ** 2 + 1,x)
#Out: [-I, I]
'''
把函数式赋给一个变量
有时候为了书写起来简洁,可以把一个函数式起个名字,比如:
'''
x = sympy.Symbol('x')
f = x + 1
sympy.solve(f,x)
#Out: [-1]
'''
解方程组
比如要解这么个二元一次方程组:
'''
# 一次性定义多个符号
x,y = sympy.symbols('x y')
sympy.solve([x + y - 1,x - y -3],[x,y])
#Out: {x: 2, y: -1}
十六进制转二进制
c=list(bin(int(input(),16)))
c.pop(1)
c=list(map(int,c))
print(c)
\x开头Unicode编码转中文
s = '\xe4\xbd\xa0\xe5\xa5\xbd\xe4\xb8\x96\xe7\x95\x8c'
s = s.encode('unicode_escape')
#得到编码:b'\\xe4\\xbd\\xa0\\xe5\\xa5\\xbd\\xe4\\xb8\\x96\\xe7\\x95\\x8c'
ss = s.decode('utf-8').replace('\\x', '%')
#得到url编码:%e4%bd%a0%e5%a5%bd%e4%b8%96%e7%95%8c
from urllib import parse
un = parse.unquote(ss)
print(un)
#得到中文:你好世界
#整一块就是
s = '\xe4\xbd\xa0\xe5\xa5\xbd\xe4\xb8\x96\xe7\x95\x8c'
from urllib import parse
print(parse.unquote(s.encode('unicode_escape').decode('utf-8').replace('\\x','%')))
Rabin加密
相当于e=2的rsa,但是不能用rsa常规方法解
from Crypto.Util.number import *
import gmpy2
#放上n、e、p、q
mp = pow(c,(p+1)//4,p)
mq = pow(c,(q+1)//4,q)
yp = gmpy2.invert(p,q)
yq = gmpy2.invert(q,p)
a = (yp*p*mq + yq*q*mp)%n
b = n - int(a)
c = (yp*p*mq - yq*q*mp)%n
d = n - int(c)
print(long_to_bytes(a))
print(long_to_bytes(b))
print(long_to_bytes(c))
print(long_to_bytes(d))
中国剩余定理
# -*- coding: UTF-8 -*-
def Get_Mi(m_list, M): # 获取所有的Mi
M_list = []
for mi in m_list:
M_list.append(M // mi)
return M_list
def Get_ei_list(M_list, m_list): # 取所有的Mi的逆元
ei_list = []
for i in range(len(M_list)):
ei_list.append(Get_ei(M_list[i], m_list[i])[0])
return ei_list
def Get_ei(a, b):
# 计算ei
if 0 == b:
x = 1;
y = 0;
q = a
return x, y, q
xyq = Get_ei(b, a % b)
x = xyq[0];
y = xyq[1];
q = xyq[2]
temp = x;
x = y;
y = temp - a // b * y
return x, y, q
def crt(a_list, m_list):
# 计算中国剩余定理,返回计算结果
M = 1 # M是所有mi的乘积
for mi in m_list:
M *= mi
Mi_list = Get_Mi(m_list, M)
Mi_inverse = Get_ei_list(Mi_list, m_list)
x = 0
for i in range(len(a_list)): # 开始计算x
x += Mi_list[i] * Mi_inverse[i] * a_list[i]
x %= M
return x
if __name__ == '__main__':
a_list = list(map(int, input().split(",")))
m_list = list(map(int, input().split(",")))
print(crt(a_list, m_list))
Schmidt-Samoa密码体制
与 Rabin 类似,它的安全性基于大整数分解的困难性。但 Rabin 解密时会得到四个解,而 Schmidt-Samor 得到的是唯一解。
构建密钥
选取大整数 pq , 计算 N = p2q作为公钥。
计算 d=invert(N,φ(pq)) 作为私钥。
加密过程
对于小于pq 的明文 m,计算c = mN mod N 作为密文。
解密过程
对于密文 c,计算 cd mod pq,得到密文。
解题代码:
from gmpy2 import*
from libnum import*
N = 2188967977749378274223515689363599801320698247938997135947965550196681836543275429767581633044354412195352229175764784503562989045268075431206876726265968368605210824232207290410773979606662689866265612797103853982014198455433380266671856355564273196151136025319624636805659505233975208570409914054916955097594873702395812044506205943671404203774360656553350987491558491176962018842708476009578127303566834534914605109859995649555122751891647040448980718882755855420324482466559223748065037520788159654436293431470164057490350841209872489538460060216015196875136927502162027562546316560342464968237957692873588796640619530455268367136243313422579857823529592167101260779382665832380054690727358197646512896661216090677033395209196007249594394515130315041760988292009930675192749010228592156047159029095406021812884258810889225617544404799863903982758961208187042972047819358256866346758337277473016068375206319837317222523597
#N = p^2*q
d = 1430375790065574721602196196929651174572674429040725535698217207301881161695296519567051246290199551982286327831985649037584885137134580625982555634409225551121712376849579015320947279716204424716566222721338735256648873164510429206991141648646869378141312253135997851908862030990576004173514556541317395106924370019574216894560447817319669690140544728277302043783163888037836675290468320723215759693903569878293475447370766682477726453262771004872749335257953507469109966448126634101604029506006038527612917418016783711729800719387298398848370079742790126047329182349899824258355003200173612567191747851669220766603
c = 1491421391364871767357931639710394622399451019824572362288458431186299231664459957755422474433520889084351841298056066100216440853409346006657723086501921816381226292526490195810903459483318275931326433052468863850690793659405367902593999395060606972100169925074005992478583035226026829214443008941631771292291305226470216430735050944285543542354459162474346521327649934512511202470099020668235115245819634762067338432916012664452035696422865651002305445711778476072004708256200872226475346448360491248823843688268126341094612981308791499434770936360676087490303951728563482686307164877000300082742316368597958297217061375140696272398140310043942637287763946305961019518639745426370821124559939597559475362769382796386720030343305889701616194279058139516811941262747298761646317383112470923295543635754747288259324745583689440061956478083777663996487389553238481759103908588004219390662578446313004404784835263543083088327198
pq = gcd(pow(2,d*N,N)-2,N)
m = pow(c,d,pq)
print(n2s(m))
关于python
- hash.digest() 返回摘要,作为二进制数据字符串值
- hash.hexdigest() 返回摘要,作为十六进制数据字符串值