逆向的时候,经常会遇到各种加密算法,google查起来比较乱,这里整理下。
编码:base64、
哈希算法:md5、sha-1、sha-256
对称加密:AES、DES、3DES
非对称加密:RSA
一、常见算法的Android实现
base64
1 | //编码 |
md5、sha-1、sha-256
写法都一样,区别在于MessageDigest.getInstance(“MD5”)指明要使用的算法,1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20fun md5(str: String): String {
val digest = MessageDigest.getInstance("MD5")
val result = digest.digest(str.toByteArray())
//没转16进制之前是16位
println("result${result.size}")
//转成16进制后是32字节
return toHex(result)
}
fun sha1(str:String): String {
val digest = MessageDigest.getInstance("SHA-1")
val result = digest.digest(str.toByteArray())
return toHex(result)
}
fun sha256(str:String): String {
val digest = MessageDigest.getInstance("SHA-256")
val result = digest.digest(str.toByteArray())
return toHex(result)
}
DES
这里DES加解密的区别只有一点,
cipher.init(Cipher.DECRYPT_MODE, securekey, sr),Cipher.DECRYPT_MODE为解密,Cipher.ENCRYPT_MODE为加密。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//DES加密
//DES加密的key必须是8个字节
String key="mykeysss";
// 生成一个可信任的随机数
SecureRandom sr = new SecureRandom();
// 从原始密钥数据创建DESKeySpec对象
DESKeySpec dks = new DESKeySpec(key.getBytes());
// 创建一个密钥工厂,然后用它把DESKeySpec转换成SecretKey对象
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey securekey = keyFactory.generateSecret(dks);
// Cipher对象实际完成加密操作
Cipher cipher = Cipher.getInstance("DES"); //默认为DES/ECB/PKCS5Padding
// 用密钥初始化Cipher对象
cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);
return cipher.doFinal(data);
//DES解密
//DES解密的key必须是8个字节
String key="mykeysss";
// 生成一个可信任的随机数源
SecureRandom sr = new SecureRandom();
// 从原始密钥数据创建DESKeySpec对象
DESKeySpec dks = new DESKeySpec(key.getBytes());
// 创建一个密钥工厂,然后用它把DESKeySpec转换成SecretKey对象
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey securekey = keyFactory.generateSecret(dks);
// Cipher对象实际完成解密操作
Cipher cipher = Cipher.getInstance("DES"); //默认为DES/ECB/PKCS5Padding
// 用密钥初始化Cipher对象
cipher.init(Cipher.DECRYPT_MODE, securekey, sr);
return cipher.doFinal(data);
AES
AES加解密的区别也是只有一个地方,cipher.init(Cipher.DECRYPT_MODE, skeySpec),Cipher.DECRYPT_MODE为解密,Cipher.ENCRYPT_MODE 加密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//AES加密
String key = "mysecret";
byte[] raw = key.getBytes("utf-8");
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
//初始化cipher 算法/模式/补码方式
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
//加密
byte[] bytesContent;
byte[] enc = cipher.doFinal(bytesContent);
return enc;
//AES解密
//key相关
byte[] raw = key.getBytes("utf-8");
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
//"算法/模式/补码方式" 初始化cipher
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
//执行解密
byte[] bytesContent;
byte[] dec = cipher.doFinal(bytesContent);
return dec;
RSA
1 | //秘钥长度为1024 生成公钥和私钥 |
二、python实现
逆向时需要进行算法验证,比较讨厌java代码的写法,可以用python进行验证。
python base64
1 | import base64 |
python DES
需要保证ECB或CBC模式、padmode与java实现一致。例如java的Cipher.getInstance(“DES”)默认为DES/ECB/PKCS5Padding模式。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16from pyDes import *
def des_encrypt(s):
secret_key = 'QExW+yCC'
iv = secret_key
k = des(secret_key, ECB, iv, pad=None, padmode=PAD_PKCS5)
en = k.encrypt(s, padmode=PAD_PKCS5)
return en
def des_descrypt(s):
secret_key = 'QExW+yCC'
iv = secret_key
k = des(secret_key, ECB, iv, pad=None, padmode=PAD_PKCS5)
de = k.decrypt(s, padmode=PAD_PKCS5)
return de
python AES
1 | #pip3 install pycryptodome |
python RSA
1 | >>> from Crypto.PublicKey import RSA |
三、openssl命令
使用openssl命令似乎更方便
base64
编码1
echo m4bln | openssl base64
解码1
echo YWJjCg== | openssl base64 -d
md5/sha1/sha256
1 | echo abc | openssl md5 |
des/aes/rsa
待补充
参考资料:
- android官方文档-加密 https://developer.android.com/guide/topics/security/cryptography?hl=zh-cn
- frida hook AES DES RSA 自吐算法 https://zhuanlan.zhihu.com/p/320229007