安卓简单密码

安卓简单密码

消息摘要算法(单向散列函数)

MD5

不管明文多长散列后密文定长

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.xiaojianbang.app;

import java.security.MessageDigest;//MessageDigest消息摘要

/* loaded from: classes.dex */
public class MD5 {
public static String md5_1(String args) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5", "BC");//可以直接理解为得到了一个MD5对象
md.update(args.getBytes());//获取输入数据
return Utils.byteToHexString(md.digest());//将刚刚放到摘要里面的数据转变成字符串拿出来
}

public static String md5_1(String args, boolean bool) throws Exception {
MessageDigest md = MessageDigest.getInstance("MD5", "BC");
md.update(args.getBytes(), 2, 5);
return Utils.byteToHexString(md.digest("xiaojianbang".getBytes()));
}
}

MD5本质来说是16个字节,我们平时看到的一般是32位的原因是把这16个字节进行了HEX的编码,两个十六进制数代表一个字节

32个十六进制数

update是可以被调用多次的

SHA1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.xiaojianbang.app;

import java.security.MessageDigest;

/* loaded from: classes.dex */
public class SHA {
public static String sha_1(String args) throws Exception {
MessageDigest md = MessageDigest.getInstance("SHA-1", "BC");
md.update(args.getBytes());
return Utils.byteToHexString(md.digest());
}

public static String sha_2(String args) throws Exception {
MessageDigest md = MessageDigest.getInstance("SHA-1", "BC");
md.update(args.getBytes(), 2, 5);
return Utils.byteToHexString(md.digest("xiaojianbang".getBytes()));
}
}

相对于MD5来说没有什么区别

MAC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.xiaojianbang.app;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

/* loaded from: classes.dex */
public class MAC {
public static String mac_1(String args) throws Exception {
SecretKey key = new SecretKeySpec("87654321".getBytes(), "HmacSHA1");//密钥 算法名
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(key);//初始化密钥
mac.update(args.getBytes());//加入明文
return Utils.byteToHexString(mac.doFinal());//计算结果
}

public static String mac_2(String args) throws Exception {
SecretKey key = new SecretKeySpec("87654321".getBytes(), "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(key);
mac.update(args.getBytes(), 2, 5);
return Utils.byteToHexString(mac.doFinal("xiaojianbang".getBytes()));
}
}

SecretKeySpec一般用来实例化一个密钥

对称加密

DES

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
package com.xiaojianbang.app;

import android.util.Base64;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;

/* loaded from: classes.dex */
public class DES {
public static String des_1(String args) throws Exception {
SecretKey secretKey = SecretKeyFactory.getInstance("DES").generateSecret(new DESKeySpec("12345678".getBytes()));//密钥
AlgorithmParameterSpec iv = new IvParameterSpec("87654321".getBytes());//iv
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
cipher.init(1, secretKey, iv);
cipher.update(args.getBytes());//明文获取
return Base64.encodeToString(cipher.doFinal(), 0);//结果获取
}

public static String des_2(String args) throws Exception {
SecretKey secretKey = SecretKeyFactory.getInstance("DES").generateSecret(new DESKeySpec("12345678".getBytes()));
AlgorithmParameterSpec iv = new IvParameterSpec("87654321".getBytes());
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");//如果这个地方模式不是CBC而是ECB的话,就不需要iv了
cipher.init(1, secretKey, iv);
return Base64.encodeToString(cipher.doFinal(args.getBytes()), 0);
}
}

DES密钥固定8个字节,大于8字节舍弃

DESKeySpec重要的类,其实底层还是调用的SecretKeySpec

RSA,AES,DES,3DES都是用这个cipher类去加密的

DESede

和DES没什么区别就是长度为24的密钥(3倍)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.xiaojianbang.app;

import android.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;

/* loaded from: classes.dex */
public class DESede {
public static String desede(String args) throws Exception {
SecretKey secretKey = SecretKeyFactory.getInstance("DESede").generateSecret(new DESedeKeySpec("123456781234567812345678".getBytes()));
Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
cipher.init(1, secretKey);
cipher.update(args.getBytes());
return Base64.encodeToString(cipher.doFinal("xiaojianbang".getBytes()), 0);
}
}

AES

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.xiaojianbang.app;

import android.util.Base64;
import java.security.spec.AlgorithmParameterSpec;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/* loaded from: classes.dex */
public class AES {
public static String aes(String args) throws Exception {
SecretKeySpec key = new SecretKeySpec("1234567890abcdef1234567890abcdef".getBytes(), "AES");
AlgorithmParameterSpec iv = new IvParameterSpec("1234567890abcdef".getBytes());
Cipher aes = Cipher.getInstance("AES/CBC/PKCS5Padding");
aes.init(1, key, iv);
return Base64.encodeToString(aes.doFinal(args.getBytes("UTF-8")), 0);
}
}

非对称加密算法
RSA
1、使用公钥加密,使用私钥解密

2.公钥是公开的,私钥保密
3、加密处理安全,但是性能极差,单次加密长度有限制
pkcs1padding 明文最大字节数为密钥字节数-11 密文与密钥等长

NoPadding 明文最大字节数为密钥字节数 密文与密钥等长

4、RSA既可用于数据交换,也可用于数据校验
数据校验通常结合消息摘要算法MD5withRSA等
5、两种加密算法常见结合套路
随机生成密钥
密钥用于AES/DES/3DES加密数据

RSA对密钥加密
提交加密后的密钥和加密后的数据给服务器

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
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
package com.xiaojianbang.app;

import android.util.Base64;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;

/* loaded from: classes.dex */
public class RSA {
public static String pubKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC9xhBZOWWF5Icw384mJksmaJ53RBLPUbEq5hXWW4Xgf82r6Zj24e3MWOnBTcblDodXYtSsaRJilosdTQVWGetJewebKmyqh1l1lUagS1/dbII9GsGat5zMboMHLWUO9NoBS9VDxqYL2VLppNEj/Xe39gBRHIiSnmtggiHuYsEv8wIDAQAB";
public static String priKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJWFpHc6vuy5SXAdSXYvLfq5WZuhnf4eGi+iAOMuBET0JtpSiRLZ6oZpUV9vEBTEVOE0O5er98EP5J1SCmmZxmsjDgcww/gC0TaoklAf8rE9aZtcfsu/70KKw209g6W9Yn8YdGp/3HdMEqON4nYKO5XGU8ENfrf4RyKXYlH2SVVrAgMBAAECgYAJ0TeGOI42nsfKm7GqF9juAGN4y3jDKZjQjdN/FxNir6Epboffe/1hC+My3+jvZCCqlLJg+AKRY4jAJ5XVbypO3tHRd9uLFgCjzREJ09J6SWyNj3KFKCkJ4vpaO0jbUAAtFGlLElc6ZtHNKabeJ0ECOgcIvVsfHpP47j1GTRU8oQJBAMXsksEmrIvCJ0l5mdDX73nRJzbxDK6m7jndE4fBe0h3Wl06iBCfuaS2x+PTjmiRWvfFu2B1/9E9Tt0jc4FQS3ECQQDBZUKZjnv6rKtwqBj1EqjIXVF2SAsttW/6vTpg6mhHYITlrqQqrt1NJ5+6PRVQr1FLDxPArNVSdoz6MFIIAiibAkA+3K+Tt0PQM78koAGRijPePea1lYPQqOY67JN6Z6JPVtEVkTSMCx78SK1eF+BAKAJ7dYrYzUGN5Gn65HqYFLeRAkBcBOFWjSxCjwwX03PkkBdNFtHe9NKU0iLQ7F6tpHsvkyZI3vrv8DoOLw9aHxxYQsLscuUUJWhvD0du97TgaJ6HAkEAoRXjsQO2UmgQcddE2e6Uxp5riOuWIEEzoW6YssCW9BznCnwXy/xamrTKhoW2cIHwn6cFx+MFmyaK5T0xAtF5pw==";

public static PublicKey getPublicKey(String key) throws Exception {
byte[] keyBytes = Base64.decode(key, 0);//可以理解为去获取生成公钥的字节
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);//RSA公钥解析的API X509EncodedKeySpec
KeyFactory keyFactory = KeyFactory.getInstance("RSA");//指定类型为RSA
PublicKey publicKey = keyFactory.generatePublic(keySpec);//最后调用keyFactory去生成公钥
return publicKey;
}

public static PrivateKey getPrivateKey(String key) throws Exception {
byte[] keyBytes = Base64.decode(key, 0);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
}

public static String sign(String data) throws Exception {
PrivateKey priK = getPrivateKey(priKey);
Signature sig = Signature.getInstance("SHA256withRSA");
sig.initSign(priK);
sig.update(data.getBytes());
return Base64.encodeToString(sig.sign(), 0);
}

public static boolean verify(byte[] data, byte[] sign) throws Exception {
PublicKey pubK = getPublicKey(pubKey);
Signature sig = Signature.getInstance("SHA256withRSA");
sig.initVerify(pubK);
sig.update(data);
return sig.verify(sign);
}

public static byte[] encrypt(byte[] plaintext) throws Exception {
PublicKey publicKey = getPublicKey(pubKey);
Cipher cipher = Cipher.getInstance("RSA/None/NoPadding", "BC");
cipher.init(1, publicKey);//初始化的时候括号里面第一个位置的数据是1或者2,1代表加密,2代表解密
byte[] bt_encrypted = cipher.doFinal(plaintext);
return bt_encrypted;
}

public static byte[] decrypt(byte[] encrypted) throws Exception {
PrivateKey privateKey = getPrivateKey(priKey);
Cipher cipher = Cipher.getInstance("RSA/None/PKCS1Padding", "BC");
cipher.init(2, privateKey);
byte[] bt_original = cipher.doFinal(encrypted);
return bt_original;
}

public static String rsa(String args) throws Exception {
byte[] cipher = encrypt("xiaojianbang".getBytes());
return Base64.encodeToString(cipher, 0);
}
}

PKCS填充的话会使得每一次加密数据都不一样

RSA HEX

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
package com.xiaojianbang.app;

import android.util.Base64;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.RSAPublicKeySpec;
import javax.crypto.Cipher;

/* loaded from: classes.dex */
public class RSAHex {

/* renamed from: N */
public static String f34N = "a32f7530324569c1d86dec45140c21ae0a6950d5331d22c591ab8c2834ecfbdf51682f494bbc07d17d7ff2b634fd13080954d9e145b6389ca3f23da22d52c1f70fdf716e56868cd7a49c3e8a13c30a18bdfd612d685efe8e36723e15d06446f0de4039a7cae690e96a23a3ba9193d80f1ad3afb1b70a76e2a927dba8fb63d6fb";

/* renamed from: E */
public static String f33E = "010001";

public static PublicKey createPublicKey(String stringN, String stringE) throws Exception {
BigInteger N = new BigInteger(stringN, 16);
BigInteger E = new BigInteger(stringE, 16);
RSAPublicKeySpec spec = new RSAPublicKeySpec(N, E);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePublic(spec);
}

public static String createPublicKey(String stringN) throws Exception {
BigInteger N = new BigInteger(stringN);
BigInteger E = new BigInteger("65537");
RSAPublicKeySpec spec = new RSAPublicKeySpec(N, E);
KeyFactory kf = KeyFactory.getInstance("RSA");
return Base64.encodeToString(kf.generatePublic(spec).getEncoded(), 0);
}

public static byte[] encrypt(String message, PublicKey key) throws Exception {
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(1, key);
byte[] data = cipher.doFinal(message.getBytes());
return data;
}

public static String rsaHex(String args) throws Exception {
return Base64.encodeToString(encrypt(args, createPublicKey(f34N, f33E)), 0);
}
}

数字签名验证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public static String sign(String data) throws Exception {
PrivateKey priK = getPrivateKey(priKey);
Signature sig = Signature.getInstance("SHA256withRSA");
sig.initSign(priK);
sig.update(data.getBytes());
return Base64.encodeToString(sig.sign(), 0);
}

public static boolean verify(byte[] data, byte[] sign) throws Exception {
PublicKey pubK = getPublicKey(pubKey);
Signature sig = Signature.getInstance("SHA256withRSA");
sig.initVerify(pubK);
sig.update(data);
return sig.verify(sign);
}


安卓简单密码
http://example.com/2024/05/29/密码学/
作者
John Doe
发布于
2024年5月29日
许可协议