1、數字摘要
是指通過算法将長資料變為短資料,通常用來辨別資料的唯一性,是否被修改,常用的加密算法有md5和sha1兩種,如Android的App簽名也是用的這兩種算法。
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();
}
sha1也具有不可逆性,比md5長度更長,是以更安全,但是機密的效率md5要慢一些,如檔案的秒傳功能,以及相同的v4包沖突都是可以根據sha1值進行比對的。
/**
* 使用sha-1方式進行加密
* @return
*/
public static String digest(String content){
StringBuilder builder = new StringBuilder();
try {
MessageDigest msgDitest = MessageDigest.getInstance("SHA-1");
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();
}
不過呢,由于以上兩種生成數字摘要的算法都是不可逆的,對于可逆的加密算法中,按照密鑰的數量和加密規則一半分為對稱加密和非對稱加密兩類:
對稱加密:
密鑰可以自己指定,隻有一把密鑰,如果密鑰洩漏資料就會暴漏;
常用的對稱加密算法有DES和AES兩種;
特點是加密速度快,但是缺點是安全性低,因為隻要密鑰暴漏,資料就可以被解密。
非對稱加密的特點:
常見的非對稱加密算法是RSA;
他有兩把密鑰,且是由程式生成的,不能自己指定;
特點是加密速度比較慢,但是安全性比較高;
加密和解密的規則是:公鑰加密隻能私鑰解密,私鑰加密隻能公鑰解密;
應用場景舉例:在內建支付寶支付SDK時,需要生成私鑰和公鑰,公鑰需要設定到支付寶網站的管理背景,在程式中調用支付接口的時候,使用我們自己的私鑰進行加密,這樣支付寶在收到訂單資訊之後就可以通過公鑰進行解密,其他人即時劫持了資料,但是沒有公鑰,也是無法解密的。
代碼實踐:使用AndroidUtils的工具類(工具類位址:https://github.com/zhaoyasong/ToolUtils)進行操作:
DES加密和解密的代碼如下:
String data = "我是俊哥";
String desKey = "青龍偃月刀";// 密鑰,口号
boolean isDesEncrypt = false;
private void useDes() {
try {
if(isDesEncrypt){
//解密
text.setText(Des.decrypt(text.getText().toString(), desKey));
}else {
//加密
text.setText(Des.encrypt(data, desKey));
}
isDesEncrypt = !isDesEncrypt;
} catch (Exception e) {
e.printStackTrace();
}
}
RSA加密和解密的代碼如下:
//1.生成密鑰對,設計口号
try {
Map<String, Object> genKeyPair = RSACrypt.genKeyPair();
//2.擷取公鑰
publicKey = RSACrypt.getPublicKey(genKeyPair);
//3.擷取私鑰
privateKey = RSACrypt.getPrivateKey(genKeyPair);
} catch (Exception e) {
e.printStackTrace();
}
private boolean isRSAEncrypt = false;
protected void useRSA() {
try {
if(isRSAEncrypt){
//公鑰解密
String str = text.getText().toString();
byte[] bs = RSACrypt.decryptByPublicKey(RSACrypt.decode(str), publicKey);
text.setText(new String(bs));
}else {
//私鑰加密
byte[] bs = RSACrypt.encryptByPrivateKey(data.getBytes(), privateKey);
text.setText(RSACrypt.encode(bs));
}
isRSAEncrypt = !isRSAEncrypt;
} catch (Exception e) {
e.printStackTrace();
}
}
轉載于:https://www.cnblogs.com/yegong0214/p/6498409.html