最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解Android安全防護(hù)之加密算法

 更新時(shí)間:2021年06月08日 10:31:08   作者:handsome黃  
Android應(yīng)用對(duì)安全防范這方面要求越來越高了。特別是金融行業(yè),如果app沒有沒有做好安全處理,那些很容易被一些Hacker(黑客)所攻擊。并不是說做了這些安全防范,這個(gè)應(yīng)用就百分之百的安全的。只是說能夠盡可能加大破解難度。本文將詳細(xì)介紹Android安全防護(hù)之加密算法。

摘要

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

Android應(yīng)用常用的加密算法

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

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

可逆加密:可逆加密有一個(gè)公鑰和一個(gè)私鑰,通過公鑰進(jìn)行數(shù)據(jù)的加密,通過私鑰進(jìn)行解密。代表有:RSA,AES。

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

MD5

MD5的特點(diǎn):

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

2、容易計(jì)算性:從原始數(shù)據(jù)計(jì)算出MD5值是很容易的。

3、抗修改性:愿數(shù)據(jù)只要有一點(diǎn)點(diǎn)的改動(dòng),得到的MD5差別都是很大的。

4、強(qiáng)抗碰撞性:從原數(shù)據(jù)計(jì)算出來的MD5,想要找到一個(gè)具有相同的MD5,非常難。

MD5的應(yīng)用場(chǎng)景:

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

2、密碼的存儲(chǔ)(如登陸注冊(cè)這些,賬號(hào)密碼會(huì)保存到sp中,直接就保存到賬號(hào)密碼的MD5值就好了。這樣也可以避免服務(wù)器權(quán)限者知道這個(gè)密碼)

MD5的簡(jiǎn)單使用

先寫一個(gè)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();
    }

}

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

然后直接調(diào)用:

/**
* 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);
    }
});

得出的結(jié)果:

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()等等,但是現(xiàn)在有些手機(jī)廠商直接就把等級(jí)較低的日志給屏蔽掉,所以有些日志輸出在有些手機(jī)可以看到,有些手機(jī)沒有看到。解決辦法就是換輸出等級(jí)較高的就OK了。

RSA

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

RSA的加密原理

1、隨機(jī)選擇兩個(gè)大的質(zhì)數(shù)P和Q,P不等于Q,計(jì)算出結(jié)果:N = P*Q;

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

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

4、銷毀P和Q

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

RSA加解密步驟

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

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

3、乙方使用公鑰加密數(shù)據(jù),向甲方發(fā)送經(jīng)過加密后的數(shù)據(jù),甲方或者加密數(shù)據(jù)后,就可以通過私鑰進(jìn)行解密了。

RSA使用場(chǎng)景

項(xiàng)目中一些敏感的數(shù)據(jù),比如身份證號(hào),銀行卡,等相關(guān)信息可通過加密后在傳給服務(wù)器,服務(wù)器使用私鑰進(jìn)行解密。

RSA密鑰對(duì)生成

RSA的密鑰對(duì)生成方式有兩種

/*
      初始化KeyPairGenerator類,并獲取到公鑰和私鑰
    */
    byte[] publicKeyByte;
    byte[] prvateKtyByte;

    public void getKey() {
        try {
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(“RSA”);//KeyPairGenerator類是java專門提供生成密鑰對(duì)的一個(gè)類。
            keyPairGenerator.initialize(1024); //設(shè)置密鑰對(duì)的大小
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            PrivateKey privateKey = keyPair.getPrivate();//獲取私鑰
            PublicKey publicKey = keyPair.getPublic();//獲取公鑰
            prvateKtyByte = privateKey.getEncoded();//私鑰對(duì)應(yīng)的字節(jié)數(shù)組
            publicKeyByte = publicKey.getEncoded(); //公鑰對(duì)應(yīng)的字節(jié)數(shù)組

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
    }

當(dāng)然上面這種生成密鑰對(duì)的方式,基本很少會(huì)在項(xiàng)目中使用使用,用得比較多的還是第二中方式。

第二種是通過OpenSSl工具生成密鑰對(duì)

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

使用命令生成私鑰:

genrsa -out rsa_private_key.pem 1024

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

使用命令生成公鑰:

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

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

加密

/**
     * 加密
     */


    @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();
        }


    }

當(dāng)然上面的代碼是我寫測(cè)試用的,真正項(xiàng)目中,還得封裝好,把它弄成工具類,進(jìn)行調(diào)用。

AES

AES是一個(gè)對(duì)稱加密,也就是說使用AES進(jìn)行加密和解密,他們使用的密鑰都是一樣的。AES加密算法是密碼學(xué)中的高級(jí)加密標(biāo)準(zhǔn),又稱Rijndael加密法,是美國聯(lián)邦政府采用的一種區(qū)塊加密標(biāo)準(zhǔn)。這個(gè)標(biāo)準(zhǔn)用來替代原先的DES,已經(jīng)被多方分析并使用。同時(shí)AES他的算法加密強(qiáng)度大,執(zhí)行效率很高。

AES使用場(chǎng)景

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

2、可以進(jìn)行對(duì)一些敏感數(shù)據(jù)進(jìn)行加密,然后在傳遞給服務(wù)器。

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。當(dāng)然也這種獲取密鑰方式在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,我是要加密的數(shù)據(jù)";
    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", "--加密的數(shù)據(jù)-- > " + 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", "--加密后的數(shù)據(jù)-- > " + 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", "--解密后的數(shù)據(jù)-- > " + string);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });


    }

    /**
     * 另一種加密形式
     */
    private byte[] encrypt(String content, String password) throws Exception {
        // 創(chuàng)建AES秘鑰
        SecretKeySpec key = new SecretKeySpec(password.getBytes(), "AES/CBC/PKCS5PADDING");
        // 創(chuàng)建密碼器
        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 {
        // 創(chuàng)建AES秘鑰
        SecretKeySpec key = new SecretKeySpec(password.getBytes(), "AES/CBC/PKCS5PADDING");
        // 創(chuàng)建密碼器
        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: --加密的數(shù)據(jù)-- > huangjialin,我是要加密的數(shù)據(jù)

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

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

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

以上就是詳解Android安全防護(hù)之加密算法的詳細(xì)內(nèi)容,更多關(guān)于Android安全防護(hù)之加密算法的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Android 屏幕切換監(jiān)聽的實(shí)例代碼

    Android 屏幕切換監(jiān)聽的實(shí)例代碼

    我試著在屏幕切換時(shí),使View顯示在不同的位置,在網(wǎng)上搜索了一些資料,自己做了一段時(shí)間,終于完成了功能,今天小編給大家分享android 屏幕切換監(jiān)聽的實(shí)例代碼,需要的的朋友參考下吧
    2017-01-01
  • 超實(shí)用的Android手勢(shì)鎖制作實(shí)例教程

    超實(shí)用的Android手勢(shì)鎖制作實(shí)例教程

    這篇文章主要介紹了一個(gè)超實(shí)用的Android手勢(shì)鎖制作實(shí)例教程,普通的圓環(huán)形圖標(biāo)變換,在App和系統(tǒng)的鎖屏界面中都可以調(diào)用,需要的朋友可以參考下
    2016-04-04
  • Flutter 狀態(tài)管理的實(shí)現(xiàn)

    Flutter 狀態(tài)管理的實(shí)現(xiàn)

    這篇文章主要介紹了Flutter 狀態(tài)管理的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • Android實(shí)現(xiàn)常見的驗(yàn)證碼輸入框?qū)嵗a

    Android實(shí)現(xiàn)常見的驗(yàn)證碼輸入框?qū)嵗a

    我們?cè)陂_發(fā)APP的時(shí)候經(jīng)常要遇到輸入框,下面這篇文章主要給大家介紹了關(guān)于利用Android如何實(shí)現(xiàn)常見的驗(yàn)證碼輸入框的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)下吧。
    2017-09-09
  • Android在一個(gè)app中安裝并卸載另一個(gè)app的示例代碼

    Android在一個(gè)app中安裝并卸載另一個(gè)app的示例代碼

    這篇文章主要介紹了Android在一個(gè)app中安裝并卸載另一個(gè)app的示例代碼,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • zxing二維碼位矩陣轉(zhuǎn)換成Bitmap位圖的實(shí)戰(zhàn)教程

    zxing二維碼位矩陣轉(zhuǎn)換成Bitmap位圖的實(shí)戰(zhàn)教程

    二維碼的應(yīng)用已經(jīng)可以說是非常廣泛了,下面這篇文章主要給大家介紹了關(guān)于zxing二維碼位矩陣轉(zhuǎn)換成Bitmap位圖的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-09-09
  • Android 圓角 ImageView類可設(shè)置弧度(代碼簡(jiǎn)單)

    Android 圓角 ImageView類可設(shè)置弧度(代碼簡(jiǎn)單)

    這篇文章主要介紹了Android 圓角 ImageView類可設(shè)置弧度 的相關(guān)資料,需要的朋友可以參考下
    2016-03-03
  • 安卓(android)怎么實(shí)現(xiàn)下拉刷新

    安卓(android)怎么實(shí)現(xiàn)下拉刷新

    這里我們將采取的方案是使用組合View的方式,先自定義一個(gè)布局繼承自LinearLayout,然后在這個(gè)布局中加入下拉頭和ListView這兩個(gè)子元素,并讓這兩個(gè)子元素縱向排列。對(duì)安卓(android)怎么實(shí)現(xiàn)下拉刷新的相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧
    2016-04-04
  • Android中使用ListView實(shí)現(xiàn)漂亮的表格效果

    Android中使用ListView實(shí)現(xiàn)漂亮的表格效果

    這篇文章主要介紹了Android中使用ListView實(shí)現(xiàn)漂亮的表格效果,本文用詳細(xì)的代碼實(shí)例創(chuàng)建了一個(gè)股票行情表格,需要的朋友可以參考下
    2014-10-10
  • Android ViewPager實(shí)現(xiàn)無限循環(huán)效果

    Android ViewPager實(shí)現(xiàn)無限循環(huán)效果

    這篇文章主要為大家詳細(xì)介紹了Android ViewPager實(shí)現(xiàn)無限循環(huán)效果的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-03-03

最新評(píng)論

开原市| 沙田区| 徐水县| 雅江县| 玉屏| 沙坪坝区| 张家口市| 鄂尔多斯市| 阿克苏市| 芒康县| 永福县| 青冈县| 武宁县| 阿合奇县| 尼勒克县| 东光县| 玉山县| 靖江市| 准格尔旗| 太保市| 新昌县| 陆河县| 辉南县| 建德市| 台江县| 嘉祥县| 嫩江县| 海丰县| 阿巴嘎旗| 中卫市| 虞城县| 临江市| 宁河县| 延庆县| 固阳县| 南涧| 崇礼县| 孟连| 桂平市| 普格县| 黔南|