728x90

Flutter 에서 AES 256 으로 암호화하고 PHP에서 복호화하는 코드 클래스를 구현했다.

Java for Android 에서 활용하던 코드를 기반으로 Flutter에 맞게 변환 및 구현했다.

Flutter 와 PHP 간에 암호화 및 복호화 처리하는데 정상 동작됨을 확인했다.

 

AES_key는 32 byte 이고 IV는 16 byte 이다.

서로 다른 언어간에도 IV 값이 일치해야 한다.

import 'package:intl/intl.dart';
import 'package:encrypt/encrypt.dart' as enc;
 
// flutter pub add encrypt
// flutter pub add intl
// flutter pub get 하면 라이브러리 추가된다.
 
class CIpheR {
  static final String URLKEY = "jgsysyksr897213579";
  static final String AES_Key = "abcdefghijtuvwxyz1234klmnopqrs56";
 
  static String URLkey() {
    DateTime now = DateTime.now();
    DateFormat formatter = DateFormat('yyyyMMdd');
    String date = formatter.format(now);
    String keyword = '${URLKEY}${date}';
    return keyword;
  }
 
  static String AES_encrypt(String value) {
    final key = enc.Key.fromUtf8(AES_Key);
    final iv = enc.IV.allZerosOfLength(16);
 
    final encrypter = enc.Encrypter(enc.AES(key, mode: enc.AESMode.cbc));
    final encrypted = encrypter.encrypt(value, iv: iv);
    return encrypted.base64;
  }
 
  static String AES_decrypt(String encrypted){
    final key = enc.Key.fromUtf8(AES_Key);
    final iv = enc.IV.allZerosOfLength(16);
 
    final encrypter = enc.Encrypter(enc.AES(key, mode: enc.AESMode.cbc));
    enc.Encrypted enBase64 = enc.Encrypted.from64(encrypted);
    final decrypted = encrypter.decrypt(enBase64, iv: iv);
    return decrypted;
  }
}
 

 

PHP에서 str_repeat(chr(0), 16) 에 해당하는 Flutter IV 값을 찾아내느라고 애를 먹었다.

final iv = enc.IV.allZerosOfLength(16); // PHP ::: str_repeat(chr(0), 16)

 

PHP 암호화/복호화 클래스

 

<?php
class LoginClass extends DBController {
    // class 자식클래스 extends 부모클래스
    // override : 부모 클래스와 자식 클래스가 같은 메소드를 정의했을 경우 자식 클래스가 우선시된다.
 
    // ########################################################################
    // RSA 암호화 키
    function get_publickey() {
        // 경로 : 절대경로로 설정 필요
        $rsakeyfile = '/home/rsa/key/rsa_pub.pem';
        
        $fp = fopen($rsakeyfile,"r");
        $key = "";
        while(!feof($fp)) {
            $key .= fgets($fp,4096);
        } 
        fclose($fp);
 
        $key = preg_replace('/\r\n|\r|\n/','',$key);
        return $key;
    } 
 
    function get_privatekey() {
        // 경로 : 절대경로로 설정 필요
        $rsakeyfile = '/home/rsa/key/rsa_pri.pem';
        
        $fp = fopen($rsakeyfile,"r");
        $key = "";
        while(!feof($fp)) {
            $key .= fgets($fp,4096);
        } 
        fclose($fp);
 
        $key = preg_replace('/\r\n|\r|\n/','',$key);
        return $key;
    } 
 
    // RSA 복호화
    function rsa_decrypt($str){
        $private_key = "file:////home/rsa/key/rsa_pri.pem";
        $openssl_pk = openssl_get_privatekey($private_key);
        $_plaintext = base64_decode(explode(':::'$str)[0]);
        openssl_private_decrypt($_plaintext$return$openssl_pk);
        return $return;
    }
 
    // AES 암호화
    function AES_encrypt($plain_text){
        global $key;
        $encryptedMessage = openssl_encrypt($plain_text"aes-256-cbc"$keytrue,str_repeat(chr(0), 16));
        return base64_encode($encryptedMessage);
    }
 
    // AES 복호화
    function AES_decrypt($base64_text){
        global $key;
        $decryptedMessage = openssl_decrypt(base64_decode($base64_text), "aes-256-cbc"$keytrue, str_repeat(chr(0), 16));
        return $decryptedMessage;
    }
 
}
?>
 
<?php
class DBController {
    protected $db// 변수를 선언한 클래스와 상속받은 클래스에서 참조할 수 있다.
 
    // 생성자
    function __construct() {
        $this->db = $this->connectDB();
        // construct 메소드는 객체가 생성(인스턴스화)될 때 자동으로 실행되는 특수한 메소드다.
    }
 
    // 소멸자(destructor)
    function __destruct() {
        mysqli_close($this->connectDB());
    }
 
    private function connectDB() {
        require_once 'dbinfo.php';
        // MySQLi 객체지향 DB 연결
        $conn = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_DATABASE);
        $conn->set_charset("utf8");
        return $conn// return database handler
    }
 
    public function putDbArray($sql) {
        $stmt = $this->db->prepare($sql);
        $stmt->execute();
        $result = $stmt->get_result();
        return $result;
    }
 
    public function getDbArray($sql) {
        $stmt = $this->db->prepare($sql);
        $stmt->execute();
        $result = $stmt->get_result();
        return $result;
    }
 
}
?>
 
<?php
// DB 정보 입력
define("DB_HOST""localhost");
define("DB_USER""andsample");
define("DB_PASSWORD""sample!#%");
define("DB_DATABASE""android");
 
/* 사용자 권한 등록
use mysql;
create user andsample@localhost identified by 'sample!#%';
grant all privileges on android.* to andsample@localhost;
flush privileges;
*/
?>

 

 

'Flutter 앱 > Network' 카테고리의 다른 글

Flutter Login with PHP Session #2 (Retrofit)  (0) 2023.12.24
Flutter Login with PHP Session #1  (0) 2023.12.24
ListView.separated 예제  (0) 2023.11.20
Flutter Login Example  (0) 2022.07.25
Session vs JWT  (0) 2022.07.22
블로그 이미지

Link2Me

,