Android应用常用的加密方式
程序员文章站
2024-03-16 18:24:04
...
Android数据加密的方式,按加密的内容是否可以还原,可以分为可逆加密和非可逆加密。
非可逆加密: 加密后的数据不能还原成原来的数据,如MD5,sha1。
可逆加密: 可逆加密有一个公钥和一个私钥,通过公钥加密,私钥解密。常用的有:RSA,AES。
MD5
-
使用场景:
1.一致性验证,比如下载某个文件,不知道文件是否下载完成,可以MD5进行校验。加密文件比较耗时,应放到子线程中。
2.密码的存储,如登陆注册这些,账号密码会保存到sp中,如果直接保存账号密码的MD5值。 -
代码实现:
/**
* 使用md5方式进行加密
* @return
*/
public static String digest(String content){
StringBuilder builder = new StringBuilder();
try {
MessageDigest msgDitest = MessageDigest.getInstance("MD5");
msgDitest.update(content.getBytes());
byte[] digests = msgDitest.digest();
//将每个字节转为16进制
for (int i=0;i<digests.length;i++){
builder.append(Integer.toHexString(digests[i] & 0xff +8));//+8为加盐操作
}
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return builder.toString();
}
RSA
- 加密原理:
1、随机选择两个大的质数P和Q,P不等于Q,计算出结果:N = PQ;
2、选择一个大于1,小于N的自然数E,E必须和(P-1)(Q-1)互素;
3、用公式计算出D:DE = mod(P-1)(Q-1);
4、销毁P和Q。最终得到的N,E就是公钥,D就是私钥了。 - 使用场景:
项目中一些敏感的数据,比如身份证号,银行卡号,支付密码等相关敏感信息可以加密后再传输到服务端,服务端使用私钥进行解密。
-**对的生成:
/*
初始化KeyPairGenerator类,并获取到公钥和私钥
*/
byte[] publicKeyByte;
byte[] prvateKtyByte;
public void getKey() {
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(“RSA”);//KeyPairGenerator类是java专门提供生成**对的一个类。
keyPairGenerator.initialize(1024); //设置**对的大小
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PrivateKey privateKey = keyPair.getPrivate();//获取私钥
PublicKey publicKey = keyPair.getPublic();//获取公钥
prvateKtyByte = privateKey.getEncoded();//私钥对应的字节数组
publicKeyByte = publicKey.getEncoded(); //公钥对应的字节数组
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
-公钥加密:
public byte[] encryption(String content) {
byte[] result = null;
try {
Cipher cipher = Cipher.getInstance("RSA");
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKeyByte);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
result = cipher.doFinal(content.getBytes());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
return result;
}
- 私钥解密:
public void decryption() {
Cipher cipher = null;
try {
cipher = Cipher.getInstance("RSA");
//私钥需要通过PKCS8EncodedKeySpec来读取
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(prvateKtyByte);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
//生成私钥
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
//String content = "123456";
byte[] input = encryption("123456");
byte[] result = cipher.doFinal(input);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
}
AES
-
使用场景:AES是对称加密,加解密都是使用一个key,在项目中将一些敏感数据保存在本地,要使用时再取出来解密。
-
代码实现:
public class AesUtils {
/**
* @param
* @return AES加密算法加密
*/
public static String encrypt(String seed, String key)
throws Exception {
byte[] rawKey = getRawKey(key.getBytes());
byte[] result = encrypt(seed.getBytes("utf-8"), rawKey);
return toHex(result);
}
public static byte[] encryptByte(String seed, String key)
throws Exception {
byte[] rawKey = getRawKey(key.getBytes());
return encrypt(seed.getBytes("utf-8"), rawKey);
}
public static String decryptString(byte[] byteData, byte[] byteKey) throws Exception {
byte[] rawKey = getRawKey(byteKey);
byte[] result = decrypt(byteData, rawKey);
return new String(result, "UTF8");
}
/***
* AES加密算法加密
* @param byteData 数据
* @param byteKey key
*/
private static byte[] encrypt(byte[] byteData, byte[] byteKey) throws Exception {
return Ase(byteData, byteKey, Cipher.ENCRYPT_MODE);
}
/***
* AES加密算法解密
* @param byteData 数据
* @param byteKey key
*/
private static byte[] decrypt(byte[] byteData, byte[] byteKey) throws Exception {
return Ase(byteData, byteKey, Cipher.DECRYPT_MODE);
}
/***
*
* @param byteData
* @param byteKey
* @param opmode
*/
private static byte[] Ase(byte[] byteData, byte[] byteKey, int opmode) throws Exception {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
SecretKeySpec skeySpec = new SecretKeySpec(byteKey, "AES");
cipher.init(opmode, skeySpec);
byte[] decrypted = cipher.doFinal(byteData);
return decrypted;
}
private static byte[] getRawKey(byte[] seed) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = null;
int sdk_version = android.os.Build.VERSION.SDK_INT;
if (sdk_version > 23) { // Android 6.0 以上
sr = SecureRandom.getInstance("SHA1PRNG", new CryptoProvider());
} else if (sdk_version >= 17) {
sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
} else {
sr = SecureRandom.getInstance("SHA1PRNG");
}
sr.setSeed(seed);
kgen.init(128, sr); // 192 and 256 bits may not be available
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
return raw;
}
public static class CryptoProvider extends Provider {
/**
* Creates a Provider and puts parameters
*/
public CryptoProvider() {
super("Crypto", 1.0, "HARMONY (SHA1 digest; SecureRandom; SHA1withDSA signature)");
put("SecureRandom.SHA1PRNG",
"org.apache.harmony.security.provider.crypto.SHA1PRNG_SecureRandomImpl");
put("SecureRandom.SHA1PRNG ImplementedIn", "Software");
}
}
private static String toHex(byte[] buf) {
final String HEX = "0123456789ABCDEF";
if (buf == null)
return "";
StringBuffer result = new StringBuffer(2 * buf.length);
for (int i = 0; i < buf.length; i++) {
result.append(HEX.charAt((buf[i] >> 4) & 0x0f)).append(
HEX.charAt(buf[i] & 0x0f));
}
return result.toString();
}
private static byte[] toByte(String hexString) {
int len = hexString.length() / 2;
byte[] result = new byte[len];
for (int i = 0; i < len; i++)
result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2),
16).byteValue();
return result;
}
}
推荐阅读
-
Android应用常用的加密方式
-
Android中常用的加密算法——MD5加密
-
浅谈MVP架构在Android中的应用
-
android之视频播放系统VideoView和自定义VideoView控件的应用 VideoAndroid自定义控件Android视频视频
-
用Kotlin的Anko库优雅开发Android应用--Anko库详细教程
-
android应用创建快捷方式 博客分类: android android桌面创建快捷方式
-
广播机制的2种注册方式 博客分类: android android广播机制
-
android应用创建快捷方式 博客分类: android android桌面创建快捷方式
-
广播机制的2种注册方式 博客分类: android android广播机制
-
Android - 字符串简单的加密和解密