API 加密解密-[AES-RSA]

AES

It must be 16, 24 or 32 bytes long (respectively for AES-128,
AES-192 or AES-256).

  • 加密数据长度无限制,
  • key必须是16的倍数,
  • 加密的数据不够16需要填充至16的倍数

代码中使用BASE64混淆是为了兼容不同语言之间字节码的差异

Python

1
2
3
4
5
#3.6 安装  
pip3 install pycryptodome
#mac
pip3 install pycrypto
https://github.com/sfbahr/PyCrypto-Wheels
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# example 中 iv 也是 key
#
from Crypto.Cipher import AES
key = "qweasdzxcqweasdz"

def encrypt(key, message):
"""
AES 数据加密
:param message:
:return: BASE64 混淆数据
"""
cipher = AES.new(key, AES.MODE_CBC, key)
# 把数据转成bytearray(byte的数组),bytearray只能追加数字,默认把数字转成字节
ba_data = bytearray(message, encoding='utf-8')
v1 = len(ba_data)
v2 = v1 % 16
if v2 == 0: # 保证收据长度是 16 的时候数据还是加密的
v3 = 16
else:
v3 = 16 - v2
for i in range(v3): # 追加 v3 长度
ba_data.append(v3)
# final_data = ba_data.decode('utf-8')
crypt_data = cipher.encrypt(ba_data) # 要加密的字符串,必须是16个字节或16个字节的倍数
base64_data = base64.b64encode(crypt_data)
return base64_data


def decrypt(key, base64_bytes):
"""
AES 数据解密
:param base64_bytes: base64 的混淆字节数据
:param key: 解密 key
:return:
"""
key = bytes(key, encoding='utf-8')
msg = base64.b64decode(base64_bytes)
cipher = AES.new(key, AES.MODE_CBC, key)
try:
result = cipher.decrypt(msg)
except ValueError as e:
return ''
data = result[0:-result[-1]]
return str(data, encoding='utf-8')

Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

private final static String ALGO = "AES"; // AES加密
private final static String ALGO_MODE = "AES/CBC/NoPadding"; // (算法/模式/填充)
//private final static String ALGO_MODE = "AES"; // (算法)
private static String key = "qweasdzxcqweasdz"; // 固定的密钥
private static String iv = "qweasdzxcqweasdz";
// *********************************
// 加密
// *********************************
public static String encrypt(String text) {
try {
Cipher cipher = Cipher.getInstance(ALGO_MODE);
// Cipher块的大小 16/32/...
int blockSize = cipher.getBlockSize();
// 将待加密的数据转成字节
byte[] dataBytes = data.getBytes();

// 将加密字节数组填充至Cipher的倍数,
// 填充规则16 - (70 % 16) = 10 ,在字节数组末尾添加10个10,
// 具体的填充规则可以根据需要修改
int dataLength = dataBytes.length;
int paddingLength = blockSize - dataLength % 16;
int encryptDataLength = dataLength + paddingLength;
// 待填充的新数组
byte[] encryptDataBytes = new byte[encryptDataLength];
// copy
System.arraycopy(dataBytes, 0, encryptDataBytes, 0, dataBytes.length);
// 填充数组至16的倍数
byte padding = Byte.valueOf(String.valueOf(paddingLength));
for (int i = encryptDataLength - 1; i >= dataLength; i--){
encryptDataBytes[i] = padding;
}

SecretKeySpec keyspec = new SecretKeySpec(key.getBytes("utf-8"), ALGO);
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes("utf-8"));
// 加密
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
byte[] encrypted = cipher.doFinal(encryptDataBytes);
// 加密后的字节码通过BASE64处理
String EncStr = Base64.encodeToString(encrypted, Base64.DEFAULT);
Log.d(TAG, "encrypt: before" + Arrays.toString(encryptDataBytes));
Log.d(TAG, "encrypt: encrypt" + Arrays.toString(encrypted));
Log.d(TAG, "encrypt: BASE " + EncStr);
return EncStr ;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
// *********************************
// 解密
// *********************************
public static String decrypt(String text) {
try {
// BASE64 解密
byte[] encrypt = Base64.decode(text, Base64.DEFAULT);
Cipher cipher = Cipher.getInstance(ALGO_MODE);

// AES 解密
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes("utf-8"), ALGO);
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes("utf-8"));
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
byte[] encryptData = cipher.doFinal(encrypt);
int encryptDataLength = encryptData.length;

//
int removePadding = encryptData[encryptData.length-1];
int dataLength = encryptData.length - removePadding;
byte[] dataBytes = new byte[dataLength];
for (int i = 0; i< dataLength; i++){
dataBytes[i] = encryptData[i];
}

String data = new String(dataBytes);

Log.d(TAG, "decrypt: " + Arrays.toString(encryptData));
Log.d(TAG, "decrypt: " + Arrays.toString(dataBytes));
Log.d(TAG, "decrypt: " + data);
return data;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}

RSA

加密数据长度是有限制的
参考资料

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import rsa
import base64


# ######### 1. 生成公钥私钥 #########
pub_key_obj, priv_key_obj = rsa.newkeys(256)

pub_key_str = pub_key_obj.save_pkcs1()
pub_key_code = base64.standard_b64encode(pub_key_str)

priv_key_str = priv_key_obj.save_pkcs1()
priv_key_code = base64.standard_b64encode(priv_key_str)

print(pub_key_code)
print(priv_key_code)

# ######### 2. 加密 #########
def encrypt(value):
key_str = base64.standard_b64decode(pub_key_code)
pk = rsa.PublicKey.load_pkcs1(key_str)
val = rsa.encrypt(value.encode('utf-8'), pk)
return val


# ######### 3. 解密 #########
def decrypt(value):
key_str = base64.standard_b64decode(priv_key_code)
pk = rsa.PrivateKey.load_pkcs1(key_str)
val = rsa.decrypt(value, pk)
return val


# ######### 基本使用 #########
if __name__ == '__main__':
v = 'wupeiqi'
v1 = encrypt(v)
print(v1)
v2 = decrypt(v1)
print(v2)