白乐天

道阻且长,行则将至。

编码与加解密

编码

ASCII

Hex

JS实现toHex

1
2
3
4
5
6
7
8
9
function toHex(data) {
let hexdata = '';
for (let i = 0; i < data.length; i++) {
hexdata += data.charCodeAt(i).toString(16).padStart(2, '0');
}
return hexdata;
}

console.log(toHex("Bileton")) // 42696c65746f6e
  • charCodeAt(i) 获取字符串中每个字符的 Unicode 编码。

  • toString(16) 将数字转换为 16 进制字符串。

  • padStart(2, '0') 确保每个字符的 Hex 码都是两位数(即不足两位时会在前面补充 0)。

frida常用

1
2
3
4
var ByteString = Java.use("com.android.okhttp.okio.ByteString");
function toHex(tag, data) {
console.log(tag + " Hex: " + ByteString.of(data).hex());
}

Python实现toHex与fromHex

1
2
3
4
5
6
7
8
9
data = "Bileton"
data_toHex = data.encode("utf-8").hex()
print("toHex: ",data_toHex)
data_toHex_fromHex = bytes.fromhex(data_toHex).decode("utf-8")
print("fromHex: ",data_toHex_fromHex)

>>>
toHex: 42696c65746f6e
fromHex: Bileton
1
2
3
4
5
6
7
8
9
10
11
import binascii

data = "Bileton"
data_toHex = binascii.hexlify(data.encode("utf-8")).decode("utf-8")
print("toHex: ", data_toHex)
data_toHex_fromHex = binascii.unhexlify(data_toHex.encode("utf-8")).decode("utf-8")
print("fromHex: ", data_toHex_fromHex)

>>>
toHex: 42696c65746f6e
fromHex: Bileton

Base64

Python实现Base64的编码与解码

1
2
3
4
5
6
7
8
9
10
11
12
import base64
data = "Bielton"
print("data:",data)
data_b64encode = base64.b64encode(data.encode())
print("b64编码:",data_b64encode.decode("utf-8"))
data_b64decode = base64.b64decode(data_b64encode)
print("b64解码",data_b64decode.decode("utf-8"))

>>>
data: Bielton
b64编码: QmllbHRvbg==
b64解码 Bielton

Java实现Base64的编码与解码

1
2
3
4
5
6
7
8
9
      String data = "Bielton";
Base64.Encoder encoder= Base64.getEncoder();
byte[] encoded = encoder.encode(data.getBytes());
String encodedToString = new String(encoded);
System.out.println(encodedToString); // QmllbHRvbg==

byte[] decoded = Base64.getDecoder().decode(encodedToString);
String decodedToString = new String(decoded);
System.out.println(decodedToString); // Bielton

Android Studio

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Button B64_en = findViewById(R.id.b64encode);
B64_en.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String data = "Bileton";
String data_encode = Base64.encodeToString(data.getBytes(), Base64.DEFAULT);
Toast.makeText(MainActivity.this,data_encode,Toast.LENGTH_SHORT).show(); // QmllbHRvbg==
}
});

Button B64_de = findViewById(R.id.b64decode);
B64_de.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String data = "Bileton";
String data_encode = Base64.encodeToString(data.getBytes(), Base64.DEFAULT);
byte[] data_decode = Base64.decode(data_encode,Base64.DEFAULT);
String decodeString = new String(data_decode);
Toast.makeText(MainActivity.this,decodeString,Toast.LENGTH_SHORT).show(); // Bielton
}
});

哈希算法

CRC32

最终生成32位(4字节)的哈希值。

MD5

最终生成128位(16字节)长度的哈希值。

Python实现MD5

1
2
3
4
5
6
7
8
9
10
11
import hashlib

def md5_call(encoded_data):
md5 = hashlib.md5()
md5.update(encoded_data)
return md5.digest()

md5_str = b"Bileton"
print(md5_str,"的哈希值为:",md5_call(md5_str).hex())
>>>
Bileton 的哈希值为: 1483ab1f77ea828faa5f78514d2765c1

SHA1

消息处理

SHA1的消息处理方式与MD5基本相同,区别是最后的消息长度使用的是大端字节序。

初始化常量

1
2
3
4
5
H0 = 0x67452301
H1 = 0xEFCDAB89
H2 = 0x98BADCFE
H3 = 0x10325476
H4 = 0xC3D2E1F0

生成结果

最终生成160位(20字节)长度的哈希值。(这里的结果使用的是大端字节序。)

Python实现SHA1

1
2
3
4
5
6
7
8
9
def sha1_call(encoded_data):
sha1 = hashlib.sha1()
sha1.update(encoded_data)
return sha1.digest()

sha1_str = b"Bileton"
print(sha1_str.decode(),"的哈希值为:",sha1_call(sha1_str).hex())
>>>
Bileton 的哈希值为: ab345d2ef3e3a48433207b746c9cb3a49b473e3a

SHA256

消息处理

与SHA1相同。

初始化常量

1
2
3
4
5
6
7
8
H0 = 0x6a09e667
H1 = 0xbb67ae85
H2 = 0x3c6ef372
H3 = 0xa54ff53a
H4 = 0x510e527f
H5 = 0x9b05688c
H6 = 0x1f83d9ab
H7 = 0x5be0cd19

生成结果

最终生成256位(32字节)长度的哈希值。(这里的结果使用的是大端字节序。)

Python实现SHA256

1
2
3
4
5
6
7
8
9
def sha256_call(encoded_data):
sha256 = hashlib.sha256()
sha256.update(encoded_data)
return sha256.digest()

sha256_str = b"Bileton"
print(sha256_str.decode(),"的哈希值为:",sha256_call(sha256_str).hex())
>>>
Bileton 的哈希值为: b54bc358a78fb7bbfcb6bdcd79ba65436534c222ce67ebbc838e8a29df5b2b28

SHA512

1
2
3
4
5
6
7
8
9
def sha512_call(encoded_data):
sha512 = hashlib.sha512()
sha512.update(encoded_data)
return sha512.digest()

sha512_str = b"Bileton"
print(sha512_str.decode(),"的哈希值为:",sha512_call(sha512_str).hex())
>>>
Bileton 的哈希值为: 46c158d8ba16ccbecc15a6555ed65b3d83af4977f152496962cae3264605c9a6f0e8a9382d8ace14d83b95a9f5a6e65dd8581b191096bdf5a2883c8d83485464

SHA3_256

1
2
3
4
5
6
7
8
9
def sha3_256_call(encoded_data):
sha3_256 = hashlib.sha3_256()
sha3_256.update(encoded_data)
return sha3_256.digest()

sha3_256_str = b"Bileton"
print(sha3_256_str.decode(),"的哈希值为:",sha3_256_call(sha3_256_str).hex())
>>>
Bileton 的哈希值为: 1e45a220d0d8ae2c46d727da1e21d639d9414bdb5eaeeaa3a7188bbefb359204

MAC算法

MAC公式

message是消息m
key是密钥
||是级联,其实就是拼接操作
ipad值为0x36
opad值为0x5c
代表异或

密钥扩展

  • 若密钥长度小于Hash的分组长度
    在密钥末尾填充0,直到长度达到Hash的分组长度
  • 若密钥长度大于Hash的分组长度
    将密钥进行哈希运算,然后补充0,直到长度达到Hash的分组长度

HmacMD5

与MD5不同的是,HmacMD5结合了密钥。

生成128位(16字节)长度的哈希值。

HmacSHA1

与HmacSHA1不同的是,HmacSHA1结合了密钥。

生成256位(32字节)长度的哈希值。

HmacSHA256

与HmacSHA256不同的是,HmacSHA256结合了密钥。

SM3

1
2
3
4
5
6
7
8
9
10
import gmssl
import gmssl.sm3

def sm3_call(data):
hash_value = gmssl.sm3.sm3_hash(list(data))
return hash_value

print(sm3_call(b"bileton"))

# b096187636f59092a00c758defd085ae7e3153e9d8bb93e9a64d4f6cadcfa47a

对称加密算法

TEA

XXTEA

1
2
pip install xxtea-py
pip install cffi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import xxtea
import base64

key = "0123456789abcdef".encode("utf-8")
data = "biletont".encode("utf-8")
# data = bytes.fromhex("932d84f10aad1197f4c793ed")

encrypted_data = xxtea.encrypt(data, key)

print(base64.b64encode(encrypted_data).decode())

data = base64.b64decode("ky2E8QqtEZf0x5Pt")
decrypt_data = xxtea.decrypt(data,key)
print(decrypt_data.decode())

RC4

DES

Python实现DES

加密ECB

1
2
3
4
5
6
7
8
9
10
11
12
13
from Crypto.Cipher import DES
from Crypto.Util.Padding import pad,unpad

def des_encrypt_ecb(plaintext,key):
cipher = DES.new(key,DES.MODE_ECB)
padded_text = pad(plaintext,DES.block_size)
# print(padded_text)
encrypted_data = cipher.encrypt(padded_text)
return encrypted_data

data = b"Bileton"
key = b"12345678"
print(des_encrypt_ecb(data,key).hex()) # 66b99748acc81443

解密ECB

1
2
3
4
5
6
7
8
9
10
11
12
13
from Crypto.Cipher import DES
from Crypto.Util.Padding import pad,unpad

def desdecrypt_ecb(encrypted_data,key):
cipher = DES.new(key,DES.MODE_ECB)
decrypted_data = cipher.decrypt(encrypted_data)
unpadded_text = unpad(decrypted_data,DES.block_size)
return unpadded_text

encrypted_data = "66b99748acc81443"
key = b"12345678"
decrypted_data = desdecrypt_ecb(bytes.fromhex(encrypted_data),key).decode("utf-8")
print(decrypted_data) # "Bileton"

加密CBC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from Crypto.Cipher import DES
from Crypto.Util.Padding import pad,unpad

def des_encrypt_cbc(plaintext,key,iv):
cipher = DES.new(key,DES.MODE_CBC,iv)
padded_text = pad(plaintext,DES.block_size)
encrypted_data = cipher.encrypt(padded_text)
return encrypted_data

data = b"Bileton"
key = b"12345678"
iv = b"12345678"
encrypted_data = des_encrypt_cbc(data,key,iv).hex()
print(encrypted_data) # fa8669e459a42d7f

解密CBC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from Crypto.Cipher import DES
from Crypto.Util.Padding import pad,unpad

def des_decrypted_cbc(encrypted_data,key,iv):
cipher = DES.new(key,DES.MODE_CBC,iv)
decrtpted_data = cipher.decrypt(encrypted_data)
unpaded_data = unpad(decrtpted_data,DES.block_size)
return unpaded_data

encrypted_data = "fa8669e459a42d7f"
key = b"12345678"
iv = b"12345678"

decrypted_data = des_decrypted_cbc(bytes.fromhex(encrypted_data),key,iv).decode("utf-8")
print(decrypted_data) # "Bileton"

3DES

Python实现3DES

加密ECB

1
2
3
4
5
6
7
8
9
10
11
12
13
from Crypto.Cipher import DES3
from Crypto.Util.Padding import pad,unpad

def des_encrypt_ecb(plaintext,key):
cipher = DES3.new(key,DES3.MODE_ECB)
padded_text = pad(plaintext,DES3.block_size)
# print(padded_text)
encrypted_data = cipher.encrypt(padded_text)
return encrypted_data

data = b"Bileton"
key = b"123456788765432112345678"
print(des_encrypt_ecb(data,key).hex()) # 4b7b3adfc5743685

解密ECB

1
2
3
4
5
6
7
8
9
10
11
12
13
from Crypto.Cipher import DES3
from Crypto.Util.Padding import pad,unpad

def desdecrypt_ecb(encrypted_data,key):
cipher = DES3.new(key,DES3.MODE_ECB)
decrypted_data = cipher.decrypt(encrypted_data)
unpadded_text = unpad(decrypted_data,DES3.block_size)
return unpadded_text

encrypted_data = "4b7b3adfc5743685"
key = b"123456788765432112345678"
decrypted_data = desdecrypt_ecb(bytes.fromhex(encrypted_data),key).decode("utf-8")
print(decrypted_data) # "Bileton"

加密CBC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from Crypto.Cipher import DES3
from Crypto.Util.Padding import pad,unpad

def des_encrypt_cbc(plaintext,key,iv):
cipher = DES3.new(key,DES3.MODE_CBC,iv)
padded_text = pad(plaintext,DES3.block_size)
encrypted_data = cipher.encrypt(padded_text)
return encrypted_data

data = b"Bileton"
key = b"123456788765432112345678"
iv = b"12345678"
encrypted_data = des_encrypt_cbc(data,key,iv).hex()
print(encrypted_data) # 883036a2094c6fab

解密CBC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from Crypto.Cipher import DES3
from Crypto.Util.Padding import pad,unpad

def des_decrypted_cbc(encrypted_data,key,iv):
cipher = DES3.new(key,DES3.MODE_CBC,iv)
decrtpted_data = cipher.decrypt(encrypted_data)
unpaded_data = unpad(decrtpted_data,DES3.block_size)
return unpaded_data

encrypted_data = "883036a2094c6fab"
key = b"123456788765432112345678"
iv = b"12345678"

decrypted_data = des_decrypted_cbc(bytes.fromhex(encrypted_data),key,iv).decode("utf-8")
print(decrypted_data) # "Bileton"

AES

Python实现AES

加密ECB

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad

def aes_encrypt_ecb(plaintext,key):
cipher = AES.new(key,AES.MODE_ECB)
padded_data = pad(plaintext,AES.block_size)
encrypted_data = cipher.encrypt(padded_data)
return encrypted_data

data = b"Bileton"
key = b"0123456789abcdef"

encrypted_data = aes_encrypt_ecb(data,key).hex()
print(encrypted_data) # cef043b604dfa84449dd3a1e5bf117e6

解密ECB

1
2
3
4
5
6
7
8
9
10
11
12
13
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad

def aes_decrypted_ecb(encrypted_data,key):
cipher = AES.new(key,AES.MODE_ECB)
decrypted_data = cipher.decrypt(encrypted_data)
unpadded_data = unpad(decrypted_data,AES.block_size)
return unpadded_data

data = "cef043b604dfa84449dd3a1e5bf117e6"
key = b"0123456789abcdef"
decrypted_data = aes_decrypted_ecb(bytes.fromhex(data),key).decode("utf-8")
print(decrypted_data) # Bileton

加密CBC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad

def aes_encrypt_ecb(plaintext,key,iv):
cipher = AES.new(key,AES.MODE_CBC,iv)
padded_data = pad(plaintext,AES.block_size)
encrypted_data = cipher.encrypt(padded_data)
return encrypted_data

data = b"Bileton"
key = b"0123456789abcdef"
iv = b"0123456789abcdef"

encrypted_data = aes_encrypt_ecb(data,key,iv).hex()
print(encrypted_data) # 95e9660e32eaf61a1873afdd9dac4757

解密CBC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad

def aes_decrypted_ecb(encrypted_data,key,iv):
cipher = AES.new(key,AES.MODE_CBC,iv)
decrypted_data = cipher.decrypt(encrypted_data)
unpadded_data = unpad(decrypted_data,AES.block_size)
return unpadded_data

data = "95e9660e32eaf61a1873afdd9dac4757"
key = b"0123456789abcdef"
iv = b"0123456789abcdef"
decrypted_data = aes_decrypted_ecb(bytes.fromhex(data),key,iv).decode("utf-8")
print(decrypted_data) # Bileton

SM4

Python实现SM4

加密ECB

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import gmssl

from gmssl.sm4 import CryptSM4,SM4_ENCRYPT,SM4_DECRYPT

def sm4_encrypt_ecb(plaintext,key):
crypt_sm4 = CryptSM4()
crypt_sm4.set_key(key,SM4_ENCRYPT)
ciphertext = crypt_sm4.crypt_ecb(plaintext)
return ciphertext

plaintext_bytes = b"bileton"
key_bytes = b"0123456789abcdef"
ciphertext = sm4_encrypt_ecb(plaintext=plaintext_bytes,key=key_bytes).hex()
print(ciphertext)

# a9194834e2f0a78db402e22a3b409bc8

解密ECB

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import gmssl

from gmssl.sm4 import CryptSM4,SM4_ENCRYPT,SM4_DECRYPT

def sm4_decrypt_ecb(ciphertext,key):
crypt_sm4 = CryptSM4()
crypt_sm4.set_key(key,SM4_DECRYPT)
plaintext = crypt_sm4.crypt_ecb(ciphertext)
return plaintext

ciphertext_bytes = bytes.fromhex("a9194834e2f0a78db402e22a3b409bc8")
key_bytes = b"0123456789abcdef"
plaintext = sm4_decrypt_ecb(ciphertext_bytes,key_bytes).decode("utf-8")
print(plaintext)

# bileton

加密CBC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import gmssl

from gmssl.sm4 import CryptSM4,SM4_ENCRYPT,SM4_DECRYPT

def sm4_encrypt_cbc(plaintext,key,iv):
crypt_sm4 = CryptSM4()
crypt_sm4.set_key(key,SM4_ENCRYPT)
ciphertext = crypt_sm4.crypt_cbc(iv,plaintext)
return ciphertext

plaintext_bytes = b"bileton"
key_bytes = b"0123456789abcdef"
iv = b"0123456789abcdef"
ciphertext = sm4_encrypt_cbc(plaintext=plaintext_bytes,key=key_bytes,iv=iv).hex()
print(ciphertext)

# 4ca44c34423c7a670136671806a228ab

解密CBC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import gmssl

from gmssl.sm4 import CryptSM4,SM4_ENCRYPT,SM4_DECRYPT

def sm4_decrypt_cbc(ciphertext,key,iv):
crypt_sm4 = CryptSM4()
crypt_sm4.set_key(key,SM4_DECRYPT)
plaintext = crypt_sm4.crypt_cbc(iv,ciphertext)
return plaintext

ciphertext_bytes = bytes.fromhex("4ca44c34423c7a670136671806a228ab")
key_bytes = b"0123456789abcdef"
iv = b"0123456789abcdef"
plaintext = sm4_decrypt_cbc(ciphertext_bytes,key_bytes,iv=iv).decode("utf-8")
print(plaintext)

# bileton

非对称加密算法

RSA

ECC

压缩算法

gzip

zlib

zip

tar

7z