首頁 > 軟體

Flutter RSA加密解密的範例程式碼

2022-04-14 13:00:03

資料加密有對稱加密(對稱金鑰方案)非對稱加密(公鑰加密) 兩種加密方式。

對稱加密

在對稱加密演演算法中,加密和解密金鑰是相同的。通訊雙方必須具有相同的金鑰才能實現加密解密的全過程。主要目的為了防止資料儲存的管理方直接獲取敏感資訊,是資料儲存安全當中重要的一環。

對稱加密演演算法主要有兩種形式:分組加密序列加密

非對稱加密

在非對稱加密演演算法中,需要兩個金鑰來進行加密和解密,且加密和解密金鑰是不同的,分別是公開金鑰(public key,簡稱公鑰)和私有金鑰(private key,簡稱私鑰)。

公開金鑰與私有金鑰是成對的,如果用公開金鑰對資料進行加密,只有用對應的私有金鑰才能解密;如果用私有金鑰對資料進行加密,那麼只有用對應的公開金鑰才能解密。因為加密和解密使用的是兩個不同的金鑰,所以這種演演算法叫作非對稱加密演演算法。

非對稱加密主要是保證資料傳輸過程中的資料安全。例如:我們的登入操作過程中的密碼傳輸,銀行賬戶資訊傳輸……。

在Flutter中加密的庫非常多,通過這篇博文介紹一下使用頻率比較高的encrypt庫,主流的加密方式也都支援。

先看一下常規用法:

第一步、首先pubspec.yaml中新增依賴

dev_dependencies:
  flutter_test:
    sdk: flutter
  # The "flutter_lints" package below contains a set of recommended lints to
  # encourage good coding practices. The lint set provided by the package is
  # activated in the `analysis_options.yaml` file located at the root of your
  # package. See that file for information about deactivating specific lint
  # rules and activating additional ones.
  flutter_lints: ^1.0.0
  # 全域性狀態管理
  provider: ^6.0.2
  # 資料請求
  dio: ^4.0.4
  # 本地資料持久化
  shared_preferences: ^2.0.13
  # 前端加密
  encrypt: ^5.0.1

第二步、獲取公鑰私鑰檔案

assets 目錄下新建rsa_key資料夾,用來儲存我們的公鑰私鑰檔案。

第三步、在pubspec.yaml檔案中新增公鑰私鑰檔案。

flutter:
  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true

  # To add assets to your application, add an assets section, like this:
  assets:
    - assets/fonts/iconfont.json
    - assets/rsa_key/rsa_public_key.pem
    - assets/rsa_key/rsa_private_key.pem
    #   - images/a_dot_burr.jpeg
    #   - images/a_dot_ham.jpeg
    - assets/images/home_logo.png

第四步、實現Encrypt加密解密工具類

lib/utils目錄下新建rsa_encrypt.dart檔案,用來開發我們的加密解密工具類。

import 'dart:convert';
import 'package:encrypt/encrypt.dart';
import 'package:flutter/services.dart';
import 'package:pointycastle/asymmetric/api.dart';
class Encrypt {
  ///  加密
  static encryption(content) async {
    final parser = RSAKeyParser();
    String publicKeyString = await rootBundle.loadString('assets/rsa_key/rsa_public_key.pem');
    print('publicKeyString=$publicKeyString'); // 注意這一行的輸出
    RSAPublicKey publicKey = parser.parse(publicKeyString) as RSAPublicKey;
    final encrypter = Encrypter(RSA(publicKey: publicKey));
    return encrypter.encrypt(content).base64;
  }
  /// 解密
  static Future<String> decrypt(String decoded) async {
    final parser = RSAKeyParser();
    String privateKeyString = await rootBundle.loadString('assets/rsa_key/rsa_private_key.pem');
    final privateKey = parser.parse(privateKeyString) as RSAPrivateKey;
    final encrypter = Encrypter(RSA(privateKey: privateKey));
    return encrypter.decrypt(Encrypted.fromBase64(decoded));
  }
}

print('publicKeyString=$publicKeyString');輸出的內容如下所示:

至此我們就已經實現了對加密解密工具類的封裝。

第五步、使用Encrypt工具類實現加密

  void _userLogin() async {
    /// 資料加密
    var password = await Encrypt.encryption(_formData["password"]);
    print('_formData=$password');
  } 

到這裡這篇部落格所介紹的內容網上基本一搜一大把,希望大家能繼續接著往下看。

第六步、專案實際需求,

為了資料安全起見,我們所採用的的加密方案是一密一用,也就是說,生成的私鑰公鑰我們只進行一次加密解密操作之後就回廢棄,下次使用會重新生成新的公鑰和私鑰。這樣的話前端生成公鑰私鑰肯定是不行的,所以公鑰私鑰都是在後端生成,每次進行加密之前先向後端發起資料請求,拿到公鑰之後再進行加密。因此,我們的工具類我們就可以調整為如下所示:

import 'dart:convert';
import 'package:cyber_security/utils/http.dart';
import 'package:encrypt/encrypt.dart';
import 'package:flutter/services.dart';
import 'package:pointycastle/asymmetric/api.dart';
class Encrypt {
  /// 公鑰
  static String pubKey = '';
  /// 可以理解為是本次使用的公鑰的id
  static String key = '';
  /// 獲取公鑰
  static getKey() async {
    /// DioRequest 是我自己封裝的資料請求的工具類,如果想學習看下面的連線。
    var response = await DioRequest.getInstance().dio.get('/getKey');
    var data = jsonDecode(response.toString());
    pubKey = data['key'];
    key = data['_key'];
  }
  ///  加密
  static encryption(content) async {
    final parser = RSAKeyParser();
    /// start
    /// 這個格式千萬別動,相信我
    String publicKeyString = '''
-----BEGIN PUBLIC KEY-----
$pubKey
-----END PUBLIC KEY-----
''';
    /// end
    RSAPublicKey publicKey = parser.parse(publicKeyString) as RSAPublicKey;
    final encrypter = Encrypter(RSA(publicKey: publicKey));
    return encrypter.encrypt(content).base64;
  }
}

Flutter網路請求Dio庫的使用及封裝

還記得前面print('publicKeyString=$publicKeyString'); 輸出的內容吧。

publicKeyString=-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDb6bKQPmUBcifd5L8hxzbluv50
26g5Jj5l1nYoq8mpxze6+iyIdJTUYbMVOGF4SEwSYL+0f0na4gC8m68n4eSnNUTB
ynG9BG8RfLKVPow3nH+0ND7WgE2iek0Z1ECqcDkim8sM3FDmVJLsSuCTlZOiorOx
bxI41zKKhL9AoO6sBQIDAQAB
-----END PUBLIC KEY-----

第七步、關於祕鑰的格式(非常重要)

現在我們說說這個publicKeyString的格式吧。

第一、中間的祕鑰部分可以不換行,且前後可以有多個換行,但是不能有空格;

第二、開始和結束的-----BEGIN PUBLIC KEY----------END PUBLIC KEY-----必須要有;

第三、-----BEGIN PUBLIC KEY-----前面不允許有空格,最多隻能有一個換行;

第四、-----END PUBLIC KEY-----前面可以有多個換行但是堅決不能有任何空格。

第八步、使用Encrypt具類實現加密

  void _userLogin() async {
    /// 獲取公鑰
    await Encrypt.getKey();
    /// 資料加密
    var password = await Encrypt.encryption(_formData["password"]);
    print('_formData=$password');
  } 

到此這篇關於Flutter RSA加密解密的範例程式碼的文章就介紹到這了,更多相關Flutter RSA加密解密內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com