亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁技術文章
文章詳情頁

詳解Android安全防護之加密算法

瀏覽:81日期:2022-09-18 10:55:36
目錄摘要Android應用常用的加密算法MD5RSAAES摘要

也許有些開發者或者企業覺得。我們公司的app,數據量這些少,會有那個黑客吃飽了沒事做來破解啊。又不是支付寶,或者其他那些用戶量很多的應用。如果是這樣想的話,那只能說目光短淺了。

Android應用常用的加密算法

如果說按加密的內容是否可以還原,可以分為可逆加密和非可逆加密。

非可逆加密:也就是說加密后的數據是不能還原成原來的數據。比如MD5加密 加密一個密碼:123456 加密后成: afabsbfbabf437hfbbff73(結果并不一定是這個,只是舉例)。也就是說加密后的結果afabsbfbabf437hfbbff73是不能夠在解密出123456這個值的。

可逆加密:可逆加密有一個公鑰和一個私鑰,通過公鑰進行數據的加密,通過私鑰進行解密。代表有:RSA,AES。

對稱加密和非對稱加密:可逆加密根據其使用加解密是否使用同一個密鑰又分為對稱加密(加解密使用同一個密鑰)和非對稱加密(加解密的密鑰分開)

MD5

MD5的特點:

1、壓縮性:任意長度的數據,算出來的MD5值的長度都是固定。

2、容易計算性:從原始數據計算出MD5值是很容易的。

3、抗修改性:愿數據只要有一點點的改動,得到的MD5差別都是很大的。

4、強抗碰撞性:從原數據計算出來的MD5,想要找到一個具有相同的MD5,非常難。

MD5的應用場景:

1、一致性驗證(比如下載某個文件,不知道文件是否下載完成,可以MD5進行校驗。加密文件比較耗時,需要放到子線程中)

2、密碼的存儲(如登陸注冊這些,賬號密碼會保存到sp中,直接就保存到賬號密碼的MD5值就好了。這樣也可以避免服務器權限者知道這個密碼)

MD5的簡單使用

先寫一個MD5的工具類

package com.example.huangjialin.md5test;import java.io.UnsupportedEncodingException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;public class Utils { public static String md5(String content) {byte[] hash = null;try { hash = MessageDigest.getInstance('MD5').digest(content.getBytes('UTF-8'));} catch (NoSuchAlgorithmException e) { e.printStackTrace();} catch (UnsupportedEncodingException e) { e.printStackTrace();}StringBuilder stringBuilder = new StringBuilder(hash.length * 2);for (byte b: hash) { if ((b & 0xFF) < 0x10){stringBuilder.append('0'); } stringBuilder.append(Integer.toHexString(b & 0xFF));}return stringBuilder.toString(); }}

簡單的解釋一下上面的,首先是通過MessageDigest.getInstance(“MD5”)來獲取到MessageDigest這個類,這個類是java自帶的一個加密類,然后通過調用digest()方法來的獲取到加密后的字節數組。該方法傳入的參數是byte[] input 所以還需要將字符串轉化為byte[]。得到加密后的字節數組以后,將他們轉換成16禁止的字符串,然后拼接起來就可以了。

然后直接調用:

/*** MD5加密*/button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) {String md5_123456abc = Utils.md5('123456abc');String md5_huangjialin = Utils.md5('huangjialin');Log.i('huangjialin',' md5_123456abc算出的MD5值是: ' + md5_123456abc);Log.i('huangjialin',' md5_huangjialin算出的MD5值是: ' + md5_huangjialin); }});

得出的結果:

09-20 15:33:12.208 7352-7352/com.example.huangjialin.md5test I/huangjialin:     md5_123456abc算出的MD5值是:    df10ef8509dc176d733d59549e7dbfaf

09-20 15:33:12.208 7352-7352/com.example.huangjialin.md5test I/huangjialin:     md5_huangjialin算出的MD5值是:   08e768954478c8669619d7d087db0070

這里說一句題外話:Log輸出日志有很多種如Log.i();Log.d()等等,但是現在有些手機廠商直接就把等級較低的日志給屏蔽掉,所以有些日志輸出在有些手機可以看到,有些手機沒有看到。解決辦法就是換輸出等級較高的就OK了。

RSA

RSA是現在比較流行的一種非對稱加密的,它需要一對密鑰(公鑰和私鑰)公鑰進行加密,私鑰進行解密。

RSA的加密原理

1、隨機選擇兩個大的質數P和Q,P不等于Q,計算出結果:N = P*Q;

2、選擇一個大于1,小于N的自然數E,E必須和(P-1)*(Q-1)互素。

3、用公式計算出D:D*E = mod(P-1)*(Q-1)

4、銷毀P和Q

最終得到的N,E就是公鑰,D就是私鑰了。

RSA加解密步驟

1、甲方生成密鑰對(公鑰和私鑰,公鑰用來加密數據,私鑰自己保留,用來解密數據)

2、甲方使用私鑰加密數據,然后用私鑰對加密后的數據簽名,并把這些放送給乙方,乙方使用公鑰,簽名來驗證帶解密數據是否有效,如果有效就使用公鑰對數據進行解密

3、乙方使用公鑰加密數據,向甲方發送經過加密后的數據,甲方或者加密數據后,就可以通過私鑰進行解密了。

RSA使用場景

項目中一些敏感的數據,比如身份證號,銀行卡,等相關信息可通過加密后在傳給服務器,服務器使用私鑰進行解密。

RSA密鑰對生成

RSA的密鑰對生成方式有兩種

/* 初始化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();} }

當然上面這種生成密鑰對的方式,基本很少會在項目中使用使用,用得比較多的還是第二中方式。

第二種是通過OpenSSl工具生成密鑰對

這種生成密鑰對的方式需要安裝OpenSSl。這里就不說具體怎么安裝了。這里簡單的說一下生成密鑰對所需要的一些命令

使用命令生成私鑰:

genrsa -out rsa_private_key.pem 1024

這條命令是讓openssl隨機生成一份私鑰,長度為1024

使用命令生成公鑰:

rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout

命令成功以后,就會在openSSL下的bin目錄下生成公鑰和私鑰,然后就可以進行加密和解密了。

加密

/** * 加密 */ @RequiresApi(api = Build.VERSION_CODES.O) 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()); Log.i('huangjialin', '----> ' + Base64.getEncoder().encodeToString(result));} 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; }

解密

/** * 解密 */ @RequiresApi(api = Build.VERSION_CODES.O) 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); Log.i('huangjialin', '--解密--> ' + new String(result)); //Assert.assertTrue(content.equals(new String(result)));} 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是一個對稱加密,也就是說使用AES進行加密和解密,他們使用的密鑰都是一樣的。AES加密算法是密碼學中的高級加密標準,又稱Rijndael加密法,是美國聯邦政府采用的一種區塊加密標準。這個標準用來替代原先的DES,已經被多方分析并使用。同時AES他的算法加密強度大,執行效率很高。

AES使用場景

1、由于AES是對稱加密,加解密都是使用同一個密鑰,所以說在項目中一些敏感的數據需要保存到本地??梢韵韧珹ES的密鑰進行加密,需要用的使用,將數據取出來再進行解密。

2、可以進行對一些敏感數據進行加密,然后在傳遞給服務器。

AES使用

在Android7.0之前可以這樣獲取到密鑰

private SecretKey generateKey(String seed) throws Exception {// 獲取秘鑰生成器KeyGenerator keyGenerator = KeyGenerator.getInstance('AES');// 通過種子初始化SecureRandom secureRandom = SecureRandom.getInstance('SHA1PRNG', 'Crypto');secureRandom.setSeed(seed.getBytes('UTF-8'));keyGenerator.init(128, secureRandom);// 生成秘鑰并返回return keyGenerator.generateKey(); }

但是在Android7.0之后就不支持了,移除了Crypto。當然也這種獲取密鑰方式在7.0之后Google也給出了解決方案,但是官方并不建議這樣來獲取。具體的可以看這里。https://android-developers.googleblog.com/2016/06/security-crypto-provider-deprecated-in.html

官方給出的是另一種方式,并不需要獲取密鑰,而是定義密碼的形式。

package com.example.huangjialin.md5test;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.util.Base64;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;import javax.crypto.Cipher;import javax.crypto.SecretKey;import javax.crypto.spec.SecretKeySpec;public class MainActivity extends AppCompatActivity { private EditText edittext; private Button button, jiami, jiemi; private TextView textView; private SecretKey secretKey; private byte[] bytes; private String content = 'huangjialin,我是要加密的數據'; String password = 'huangji黃家磷'; @Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);edittext = findViewById(R.id.edittext);button = findViewById(R.id.button);textView = findViewById(R.id.textview);jiami = findViewById(R.id.jiami);jiemi = findViewById(R.id.jiemi);Log.i('huagjialin', '--加密的數據-- > ' + content);/** * 獲取密鑰 */ /* button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) {try { secretKey = generateKey('huangjiain');} catch (Exception e) { e.printStackTrace();} }});*//** * 加密 */jiami.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) {try { bytes = encrypt(content, password); String str = new String(bytes); Log.i('huagjialin', '--加密后的數據-- > ' + Base64.decode(str,Base64.DEFAULT));} catch (Exception e) { e.printStackTrace();} }});/** * 解密 */jiemi.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) {try { byte[] by = decrypt(bytes, password); String string = new String(by); Log.i('huagjialin', '--解密后的數據-- > ' + string);} catch (Exception e) { e.printStackTrace();} }}); } /** * 另一種加密形式 */ private byte[] encrypt(String content, String password) throws Exception {// 創建AES秘鑰SecretKeySpec key = new SecretKeySpec(password.getBytes(), 'AES/CBC/PKCS5PADDING');// 創建密碼器Cipher cipher = Cipher.getInstance('AES');// 初始化加密器cipher.init(Cipher.ENCRYPT_MODE, key);// 加密return cipher.doFinal(content.getBytes('UTF-8')); } /** * 解密 */ private byte[] decrypt(byte[] content, String password) throws Exception {// 創建AES秘鑰SecretKeySpec key = new SecretKeySpec(password.getBytes(), 'AES/CBC/PKCS5PADDING');// 創建密碼器Cipher cipher = Cipher.getInstance('AES');// 初始化解密器cipher.init(Cipher.DECRYPT_MODE, key);// 解密return cipher.doFinal(content); }}

09-20 21:12:36.394 15933-15933/com.example.huangjialin.md5test I/huagjialin: --加密的數據-- > huangjialin,我是要加密的數據

09-20 21:12:39.561 15933-15933/com.example.huangjialin.md5test I/huagjialin: --加密后的數據-- > [B@d62495e

09-20 21:12:41.829 15933-15933/com.example.huangjialin.md5test I/huagjialin: --解密后的數據-- > huangjialin,我是要加密的數據

以上就是我們比較常用的幾種加密的一些內容。

以上就是詳解Android安全防護之加密算法的詳細內容,更多關于Android安全防護之加密算法的資料請關注好吧啦網其它相關文章!

標簽: Android
相關文章:
主站蜘蛛池模板: 99热国产这里只有精品免费 | a级黄毛片| 欧美黑粗大 | 国产无限免费观看黄网站 | 免费国产黄网站在线观看视频 | 欧美一级黄色录相 | 97碰碰碰免费公开在线视频 | 亚洲欧美一区二区三区不卡 | 日韩高清一区二区 | 久操视频免费观看 | 国产探花在线视频 | 一级视频在线免费观看 | 久久精品国产亚洲综合色 | 美国一级大黄大黄大色毛片a | 日韩欧美亚洲国产 | 欧美一区二区三区免费看 | 91短视频版在线观看免费 | 国产福利不卡视频 | 女同视频一区二区在线观看 | 亚洲综合三区 | 免费看黄网站在线 | 日本精品国产 | 免费大片在线观看高清 | 国产精品成人一区二区三区 | 中文日韩字幕一区在线观看 | 欧美国一级毛片片aa | 久久精品国产这里是免费 | 香蕉视频呦呦 | 精品欧美激情在线看 | 亚洲性网| 男女爱爱激情视频在线观看 | 三级黄色毛片 | 亚洲综合一 | 国产一区二区三区精品久久呦 | 精品九九在线 | 欧美在线视频 一区二区 | 一级黄色国产片 | 亚洲欧洲一区二区三区在线 | 亚洲视频在线一区二区 | 国产99福利视频在线 | 国产一区二区三区欧美精品 |