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

Android客戶端與服務端數據加密傳輸方案詳解

 更新時間:2023年01月03日 15:23:08   作者:麥田里的守望者江  
這篇文章主要為大家介紹了Android客戶端與服務端數據加密傳輸方案詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

前言

在網絡通信中,通信傳輸數據容易被截取或篡改,如果在傳輸用戶隱私數據過程中,被不法分子截取或篡改,就可能導致用戶受到傷害,比如被詐 騙,所以對客戶端與服務端的傳輸數據加密,是網絡通信中必不可少的。

數據加密方案

首先,客戶端與服務端商量好數據加密協(xié)議,對傳輸數據做到安全保護。

安全保護至少需要有下面兩點:

  • 采用HTTPS協(xié)議
  • 采用公鑰密碼體制RSA算法對數據加密

現在安全是保證了,但還要考慮到性能問題,由于RSA算法對數據加密時運算速度慢,所以直接把所有傳輸數據都用RSA加密,會導致網絡通信慢,這對用戶將是不好的體驗。由于對稱密鑰密碼體制中的AES運算速度快且安全性高,所以結合AES對傳輸數據加密是非常好的方案。

下面是對客戶端與服務端通信數據加密比較通用的方案:

  • 客戶端生成AES密鑰,并保存AES密鑰
  • 客戶端用AES密鑰對請求傳輸數據進行加密
  • 客戶端使用RSA公鑰對AES密鑰加密,然后把值放到自定義的一個請求頭中
  • 客戶端向服務端發(fā)起請求
  • 服務端拿到自定義的請求頭值,然后使用RSA私鑰解密,拿到AES密鑰
  • 服務端使用AES密鑰對請求數據解密
  • 服務端對響應數據使用AES密鑰加密
  • 服務端向客戶端發(fā)出響應
  • 客戶端拿到服務端加密數據,并使用之前保存的AES密鑰解密

注意:傳輸數據使用AES密鑰加密,RSA公鑰對AES密鑰加密。RSA公鑰和私鑰由服務端生成,公鑰放在客戶端,私鑰放在服務端。公鑰私鑰要私密保護,不能隨便給人。

具體流程圖如下:

上面網絡通信過程是安全的,可以保證通信數據即使被截取了,也無法獲得任何有效信息;即使被篡改了,也無法被客戶端和服務端驗證通過。

數據加密細節(jié)

AES加解密

生成AES密鑰和使用AES密鑰加密、解密,有下面重要的幾點:

1.密鑰長度的選擇:AES能支持的密鑰長度可以為128,192,256位(也即16,24,32個字節(jié)),這里選擇128位。

2.算法/模式/填充的選擇:

算法/模式/填充字節(jié)加密后數據長度不滿16字節(jié)加密后長度
AES/CBC/NoPadding16不支持
AES/CBC/PKCS5Padding3216
AES/CBC/ISO10126Paddind3216
AES/CFB/NoPadding16原始數據長度
AES/CFB/PKCS5Padding3216
AES/CFB/ISO10126Padding3216
AES/ECB/NoPadding16不支持
AES/ECB/PKCS5Padding3216
AES/ECB/ISO10126Padding3216
AES/ECB/ISO10126Padding3216
AES/OFB/NoPadding16原始數據長度
AES/OFB/PKCS5Padding3216
AES/OFB/ISO10126Padding3216
AES/PCBC/NoPadding16不支持
AES/PCBC/PKCS5Padding3216
AES/PCBC/ISO10126Padding3216

這里選擇AES/CBC/PKCS5Padding。

3.添加向量 IvParameterSpec:增強算法強度。 4.編碼格式選擇:UTF-8。

下面為具體代碼實現:

    private final int AES_KEY_LENGTH = 16;//密鑰長度16字節(jié),128位
    private final String AES_ALGORITHM = "AES";//算法名字
    private final String AES_TRANSFORMATION = "AES/CBC/PKCS5Padding";//算法/模式/填充
    private final String AES_IV = "0112030445060709";//使用CBC模式,需要一個向量iv,可增加加密算法的強度
    private final String AES_STRING = "abcdefghijklmnopqrstuvwxyzABCDEFGHIGKLOP";
    private final Charset UTF_8 = Charset.forName("UTF-8");//編碼格式
    /**
     * 使用AES加密
     *
     * @param aesKey AES Key
     * @param data   被加密的數據
     * @return AES加密后的數據
     */
    private byte[] encodeAES(byte[] aesKey, String data) {
        if (aesKey == null || aesKey.length != AES_KEY_LENGTH) {
            return null;
        }
        SecretKeySpec keySpec = new SecretKeySpec(aesKey, AES_ALGORITHM);
        try {
            Cipher cipher = Cipher.getInstance(AES_TRANSFORMATION);
            IvParameterSpec iv = new IvParameterSpec(AES_IV.getBytes(UTF_8));
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
            return cipher.doFinal(data.getBytes(UTF_8));
        } catch (Exception e) {
            Log.d(TAG, e.getMessage(), e);
        }
        return null;
    }
    /**
     * 使用AES解密
     *
     * @param aesKey AES Key
     * @param data   被解密的數據
     * @return AES解密后的數據
     */
    private String decodeAES(byte[] aesKey, byte[] data) {
        if (aesKey == null || aesKey.length != AES_KEY_LENGTH) {
            return null;
        }
        SecretKeySpec keySpec = new SecretKeySpec(aesKey, AES_ALGORITHM);
        try {
            Cipher cipher = Cipher.getInstance(AES_TRANSFORMATION);
            IvParameterSpec iv = new IvParameterSpec(AES_IV.getBytes(UTF_8));
            cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
            return new String(cipher.doFinal(data), UTF_8);
        } catch (Exception e) {
            Log.d(TAG, e.getMessage(), e);
        }
        return null;
    }
    private int getRandom(int count) {
        return (int) Math.round(Math.random() * (count));
    }
    /**
     * 生成AES key
     *
     * @return AES key
     */
    private String initAESKey() {
        StringBuilder sb = new StringBuilder();
        int len = AES_STRING.length();
        for (int i = 0; i < AES_KEY_LENGTH; i++) {
            sb.append(AES_STRING.charAt(getRandom(len - 1)));
        }
        return sb.toString();
    }

現在AES密鑰和AES加密、解密都有了,在通常情況下,還會對加密、解密過程進行Base64 編碼、解碼。

Base64編碼,選擇 URL_SAFE 標識,也就是 "-" 和 “_” 會被替換為 "+" 和 "/",:

    /**
     * 對數據進行Base64編碼,使用的是{@link android.util.Base64},而且flags需要使用 {@link android.util.Base64#URL_SAFE,android.util#Base64.NO_PADDING,android.util.Base64#NO_WRAP}。
     *
     * @param input 來源數據
     * @return Base64編碼的數據
     */
    private String encodeBase64(byte[] input) {
        return new String(Base64.encode(input, Base64.URL_SAFE | Base64.NO_PADDING | Base64.NO_WRAP), UTF_8);
    }

Base64解碼,和編碼對應:

    /**
     * 對數據進行Base64解碼,使用的是{@link android.util.Base64},而且flags需要使用 {@link android.util.Base64#URL_SAFE,android.util.Base64#NO_WRAP},主要是為了和Base64加密對應。
     *
     * @param str 需要解碼的數據
     * @return Base64解碼后的數據
     */
    private byte[] decodeBase64(String str) {
        return Base64.decode(str.getBytes(UTF_8), Base64.URL_SAFE | Base64.DEFAULT);
    }

RSA公鑰加密

RSA公鑰是從服務端拿到的,這個公鑰不能被泄漏,必須做到安全保護。

使用RSA公鑰加密,也有幾個重要點:

1.拿到的公鑰是Base64 編碼后的,所以首先需要對公鑰Base64解碼。

2.算法/模式/填充的選擇:RSA/ECB/PKCS1Padding

3.編碼格式選擇:UTF-8。

注意:使用RSA公鑰加密的流程對應的就是服務端使用RSA私鑰解密的流程,所以需要和服務端溝通商量好。

具體代碼實現:

    private final String RSA_PUB_KEY = "服務端給的公鑰";
    private final String RSA_TRANSFORMATION = "RSA/ECB/PKCS1Padding";
    /**
     * 公鑰加密
     *
     * @param data           要加密的數據
     * @param key            公鑰
     * @param transformation 算法/模式/填充
     * @return 加密后的數據
     */
    public byte[] encryptByPublicKey(byte[] data, String key, String transformation)
            throws GeneralSecurityException {
        byte[] keyBytes = Base64.decode(key.getBytes(UTF_8), Base64.NO_WRAP);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey pubKey = keyFactory.generatePublic(keySpec);
        Cipher cipher = Cipher.getInstance(transformation);
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);
        return cipher.doFinal(data);
    }

總結

1.為了保證網絡通信中的通信數據安全,首先采用HTTPS協(xié)議和公鑰密鑰體制中的RSA加密。

2.因為是RSA運算速度慢,所以采用運算速度快且安全性高的對稱密鑰密碼體制中的AES對所 有傳輸數據進行加密,然后再用RSA對AES密鑰加密,這樣既能保證安全又能保證性能。

3.RSA公鑰和私鑰由服務端生成,公鑰放在客戶端,私鑰放在服務端。

4.數據加密后采用Base64編碼,數據解密前采用Base64解碼。

5.編碼格式同一采用UTF-8。

以上就是Android客戶端與服務端數據加密傳輸方案詳解的詳細內容,更多關于Android客戶端服務端數據加密傳輸的資料請關注腳本之家其它相關文章!

相關文章

  • Android 仿余額寶數字跳動動畫效果完整代碼

    Android 仿余額寶數字跳動動畫效果完整代碼

    這篇文章主要介紹了Android 仿余額寶數字跳動動畫效果完整代碼,需要的朋友可以參考下
    2017-11-11
  • 解決webview調用goBack()返回上一頁自動刷新閃白的情況

    解決webview調用goBack()返回上一頁自動刷新閃白的情況

    本文主要介紹了解決webview調用goBack()返回上一頁自動刷新閃白的情況。具有很好的參考價值。下面跟著小編一起來看下吧
    2017-03-03
  • Android實現可以展開的TextView

    Android實現可以展開的TextView

    這篇文章主要為大家詳細介紹了Android實現可以展開的TextView,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • Android在ubuntu上過濾多條關鍵字日志

    Android在ubuntu上過濾多條關鍵字日志

    今天小編就為大家分享一篇關于Android在ubuntu上過濾多條關鍵字日志,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-04-04
  • Android中如何安全地打印日志詳解

    Android中如何安全地打印日志詳解

    日志是我們在日常開發(fā)中必不可少的一部分,下面這篇文章主要給大家介紹了關于Android中如何安全地打印日志的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們一起來看看吧。
    2017-12-12
  • android surfaceView實現播放視頻功能

    android surfaceView實現播放視頻功能

    這篇文章主要為大家詳細介紹了android surfaceView實現播放視頻功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • Android仿拉手網團購App我的收藏界面實例代碼

    Android仿拉手網團購App我的收藏界面實例代碼

    這篇文章主要介紹了Android仿拉手團購網App我的收藏界面實例代碼,需要的朋友可以參考下
    2017-05-05
  • Android中ViewFlipper的使用及設置動畫效果實例詳解

    Android中ViewFlipper的使用及設置動畫效果實例詳解

    這篇文章主要介紹了Android中ViewFlipper的使用及設置動畫效果的方法,以實例形式較為詳細的分析了ViewFlipper的功能、原理及設置與使用技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-10-10
  • Android ProgressDialog使用總結

    Android ProgressDialog使用總結

    ProgressDialog 繼承自AlertDialog,AlertDialog繼承自Dialog,實現DialogInterface接口,本文給大家介紹Android ProgressDialog使用總結的相關知識,需要的朋友通過此文一起學習吧
    2016-01-01
  • Android隱私彈框功能的實現

    Android隱私彈框功能的實現

    最近做app類的項目,現在發(fā)布app都需要在發(fā)布前生成一個用戶隱私彈框讓用戶點擊,這個功能看似簡單,到底怎么實現的呢?下面小編給大家?guī)砹薃ndroid隱私彈框功能的實現代碼,一起看看吧
    2021-10-10

最新評論

镇原县| 莱阳市| 邹平县| 武宣县| 皋兰县| 年辖:市辖区| 府谷县| 胶南市| 盐池县| 锡林浩特市| 沿河| 五寨县| 永丰县| 广昌县| 宝坻区| 堆龙德庆县| 昌吉市| 芮城县| 江孜县| 班玛县| 登封市| 茂名市| 武宣县| 上饶市| 治多县| 鹤山市| 叙永县| 乐至县| 武宣县| 包头市| 喀喇| 左贡县| 石嘴山市| 松潘县| 河间市| 合水县| 徐水县| 道孚县| 万宁市| 成安县| 平定县|